diff --git a/README.md b/README.md index b927426..4072fc5 100644 Binary files a/README.md and b/README.md differ diff --git a/my-app/.env.example b/my-app/.env.example new file mode 100644 index 0000000..ce277ab --- /dev/null +++ b/my-app/.env.example @@ -0,0 +1,11 @@ +# Endereço opcional da API. Sem esta variável, o frontend usa o proxy /backend. +# NEXT_PUBLIC_API_URL=https://api.exemplo.com + +# Destino usado pelo proxy interno /backend. Para desenvolvimento com a API local: +API_PROXY_TARGET=http://localhost:8080/api + +# Acesso de contingência para ambientes de demonstração sem API. +# Em produção, só habilite temporariamente e faça um novo deploy. +NEXT_PUBLIC_ENABLE_MOCK_AUTH=false +NEXT_PUBLIC_MOCK_AUTH_USERNAME=admin.mock +NEXT_PUBLIC_MOCK_AUTH_PASSWORD=Mock@123456789! diff --git a/my-app/.gitignore b/my-app/.gitignore index 5ef6a52..7b8da95 100644 --- a/my-app/.gitignore +++ b/my-app/.gitignore @@ -32,6 +32,7 @@ yarn-error.log* # env files (can opt-in for committing if needed) .env* +!.env.example # vercel .vercel diff --git a/my-app/PLANO_DE_TESTES.md b/my-app/PLANO_DE_TESTES.md new file mode 100644 index 0000000..6d2c98e --- /dev/null +++ b/my-app/PLANO_DE_TESTES.md @@ -0,0 +1,309 @@ +# PLANO DE TESTES - QUICK TRANSFER + +--- + +## 1. Informações Gerais +- **Projeto:** Quick Transfer - Frontend +- **Versão:** 1.0.0 +- **Documento:** Plano de Testes de Software (Seção 7 - Requisitos de Qualidade) +- **Data de Elaboração:** 29/07/2026 + +--- + +## 2. Estrutura Padrão dos Casos de Teste +Cada teste contemplado neste plano possui a seguinte estrutura padronizada de atributos: +1. **Código / Identificação do Teste** (ex: `CT-001`) +2. **Funcionalidade Testada** +3. **Objetivo do Teste** +4. **Pré-condições** +5. **Dados Utilizados** +6. **Etapas de Execução** +7. **Resultado Esperado** +8. **Trecho de Código de Exemplo (Componentes do Projeto / React Testing Library)** +9. **Prioridade** (`Alta`, `Média`, `Baixa`) +10. **Responsável pela Execução** + +--- + +## 3. Matriz de Casos de Teste + +### CT-001: Autenticação e Navegação por Perfil (RBAC / Sidebar) +- **Funcionalidade Testada:** Navegação entre telas e Controle de Acesso Baseado em Perfil (RBAC). +- **Objetivo do Teste:** Verificar se a Sidebar (`src/components/layout/sidebar.tsx`) exibe exclusivamente os módulos autorizados para cada perfil (`MANAGER`, `COORDINATOR`, `ADMIN`). +- **Pré-condições:** Aplicação em execução na rota `/login`. +- **Dados Utilizados:** + - Gestor: `userRole = "MANAGER"` + - Coordenador: `userRole = "COORDINATOR"` + - Admin: `userRole = "ADMIN"` +- **Etapas de Execução:** + 1. Renderizar o componente `Sidebar` passando as propriedades de perfil. + 2. Verificar os itens de menu renderizados na arvore DOM. +- **Resultado Esperado:** + - **MANAGER:** Exibe "Minhas Vagas", "Alunos", "Entrevistas" e "Locais". + - **COORDINATOR:** Exibe "Painel", "Turmas", "Alunos", "Cursos" e "Direcionar Alunos". + - **ADMIN:** Exibe somente "Painel Admin" e "Usuários". +- **Trecho de Código:** +```typescript +import { render, screen } from "@testing-library/react"; +import Sidebar from "@/components/layout/sidebar"; + +describe("CT-001: Autenticação e RBAC da Sidebar", () => { + it("deve renderizar apenas módulos do Gestor para o papel MANAGER", () => { + // Renderiza a Sidebar real do projeto com o perfil MANAGER + render(); + + expect(screen.getByText("Minhas Vagas")).toBeInTheDocument(); + expect(screen.getByText("Alunos")).toBeInTheDocument(); + expect(screen.queryByText("Painel Admin")).not.toBeInTheDocument(); + }); +}); +``` +- **Prioridade:** Alta +- **Responsável pela Execução:** QA / Equipe de Desenvolvimento + +--- + +### CT-002: Carregamento de Dados e Estado de Carregamento (Loading State) +- **Funcionalidade Testada:** Carregamento de dados e estados de carregamento. +- **Objetivo do Teste:** Garantir que indicadores visuais de carregamento (`DataTable` / Skeleton) são exibidos adequadamente em componentes de listagem como `DataTable` (`src/components/shared/data-table.tsx`). +- **Pré-condições:** Componente de tabela acionado antes da resolução do *fetch* da API. +- **Dados Utilizados:** `isLoading = true`, `data = []`. +- **Etapas de Execução:** + 1. Renderizar ``. + 2. Verificar a exibição das linhas de esqueleto (*loading skeleton*). +- **Resultado Esperado:** O componente renderiza o estado de carregamento visual sem falhas na interface. +- **Trecho de Código:** +```typescript +import { render, screen } from "@testing-library/react"; +import { DataTable } from "@/components/shared/data-table"; + +describe("CT-002: Estado de Carregamento na DataTable", () => { + it("deve exibir as linhas de carregamento quando isLoading for true", () => { + const columns = [{ key: "name", header: "Nome" }]; + + render(); + + // Verifica a presença das células de carregamento (Skeleton) + const skeletonRows = screen.getAllByRole("row"); + expect(skeletonRows.length).toBeGreaterThan(0); + }); +}); +``` +- **Prioridade:** Média +- **Responsável pela Execução:** QA / Tester + +--- + +### CT-003: Validação de Formulário e Cadastro de Nova Turma +- **Funcionalidade Testada:** Cadastro e Validação de Formulários (`src/app/classes/new/page.tsx`). +- **Objetivo do Teste:** Validar o comportamento do formulário de criação de turma `NovaTurmaPage` ao submeter dados. +- **Pré-condições:** Usuário autenticado na rota `/classes/new`. +- **Dados Utilizados:** + - `className`: "Turma 2026-A" + - `classCode`: "TURMA-2026-A" +- **Etapas de Execução:** + 1. Preencher os campos de input de Nome da Turma e Código da Turma. + 2. Disparar a submissão do formulário clicando no botão "Salvar Turma". +- **Resultado Esperado:** O evento `handleSubmit` deve processar os dados cadastrados e redirecionar para `/admin/classes`. +- **Trecho de Código:** +```typescript +import { render, screen, fireEvent } from "@testing-library/react"; +import NovaTurmaPage from "@/app/classes/new/page"; + +describe("CT-003: Cadastro de Nova Turma", () => { + it("deve permitir preencher o nome da turma e acionar a gravação", () => { + render(); + + const inputClassName = screen.getByLabelText(/Nome da Turma/i); + fireEvent.change(inputClassName, { target: { value: "Turma 2026-A" } }); + + const saveButton = screen.getByRole("button", { name: /Salvar Turma/i }); + expect(saveButton).toBeInTheDocument(); + fireEvent.click(saveButton); + }); +}); +``` +- **Prioridade:** Alta +- **Responsável pela Execução:** Tester / Desenvolvedor Frontend + +--- + +### CT-004: Edição e Exclusão de Registro com Confirmação Visual +- **Funcionalidade Testada:** Edição e Exclusão na Gestão de Usuários (`src/app/admin/users/page.tsx`). +- **Objetivo do Teste:** Assegurar que as ações de "Editar" e "Excluir" exibidas no componente `UsuariosPage` invoquem os manipuladores corretos. +- **Pré-condições:** Acesso à página `/admin/users` com a API autenticada. +- **Dados Utilizados:** Registro do usuário `UserDTO` com perfil `ADMIN` ou `COORDINATOR`. +- **Etapas de Execução:** + 1. Renderizar a página `UsuariosPage`. + 2. Localizar a tabela de usuários com os botões de ação (ícones `Edit` e `Trash2`). + 3. Clicar na ação de exclusão do registro target. +- **Resultado Esperado:** As ações acionam os modais de confirmação visual sem erros de execução. +- **Trecho de Código:** +```typescript +import { render, screen, fireEvent } from "@testing-library/react"; +import UsuariosPage from "@/app/admin/users/page"; + +describe("CT-004: Tabela de Usuários Admin - Ações de Edição e Exclusão", () => { + it("deve renderizar a tabela de usuários com os botões de ação", () => { + render(); + + // Confirma a renderização das colunas da página de usuários do projeto + expect(screen.getByText("Usuário")).toBeInTheDocument(); + expect(screen.getByText("Papel / Função")).toBeInTheDocument(); + expect(screen.getByText("Status")).toBeInTheDocument(); + }); +}); +``` +- **Prioridade:** Média +- **Responsável pela Execução:** QA / Tester + +--- + +### CT-005: Tratamento de Indisponibilidade da API +- **Funcionalidade Testada:** Resiliência do cliente de API (`src/lib/api.ts`). +- **Objetivo do Teste:** Verificar o comportamento do método `apiFetch` do projeto ao receber erro de conexão ou status HTTP 500 do Spring Boot (`http://localhost:8080`). +- **Pré-condições:** Servidor da API simulando indisponibilidade. +- **Dados Utilizados:** Chamada para o endpoint `/api/v1/students`. +- **Etapas de Execução:** + 1. Invocar a função `apiFetch("/students")` com endpoint inacessível. + 2. Tratar a exceção capturada para exibir feedback gracioso. +- **Resultado Esperado:** O sistema captura o erro e exibe uma mensagem amigável, sem simular persistência local em uma sessão real. +- **Trecho de Código:** +```typescript +import { apiFetch } from "@/lib/api"; + +describe("CT-005: Resiliência da API e Fallback", () => { + it("deve lançar erro tratável quando a API estiver offline", async () => { + global.fetch = jest.fn().mockRejectedValue(new TypeError("Failed to fetch")); + + await expect(apiFetch("/students")).rejects.toThrow("Failed to fetch"); + }); +}); +``` +- **Prioridade:** Alta +- **Responsável pela Execução:** Equipe de QA / Desenvolvedor + +--- + +### CT-006: Responsividade da Interface e Toggle da Sidebar Mobile +- **Funcionalidade Testada:** Responsividade e alternância da Sidebar (`src/components/layout/sidebar.tsx`). +- **Objetivo do Teste:** Testar a exibição do botão de menu mobile e o controle do estado `mobileOpen` no componente `Sidebar`. +- **Pré-condições:** Resolução de tela mobile (< 1024px). +- **Dados Utilizados:** Evento de clique no botão do menu hambúrguer (`Menu`). +- **Etapas de Execução:** + 1. Renderizar a `Sidebar` em ambiente simulado mobile. + 2. Localizar o botão de alternância do menu mobile. + 3. Clicar para abrir/fechar. +- **Resultado Esperado:** O estado de visibilidade da barra lateral alterna entre visível e oculto. +- **Trecho de Código:** +```typescript +import { render, screen, fireEvent } from "@testing-library/react"; +import Sidebar from "@/components/layout/sidebar"; + +describe("CT-006: Menu Mobile e Responsividade", () => { + it("deve acionar a abertura do menu mobile ao clicar no ícone de Menu", () => { + render(); + + const menuButtons = screen.getAllByRole("button"); + expect(menuButtons.length).toBeGreaterThan(0); + }); +}); +``` +- **Prioridade:** Média +- **Responsável pela Execução:** Designer UI/UX / QA Tester + +--- + +### CT-007: Telas do Perfil Gestor (Minhas Vagas, Meus Alunos e Entrevistas) +- **Funcionalidade Testada:** Módulo do Gestor (`src/app/manager/vacancies/page.tsx`, `src/app/manager/students/page.tsx` e `src/app/manager/interviews/page.tsx`). +- **Objetivo do Teste:** Validar a renderização da interface e listagem de dados das vagas geridas pelo perfil Gestor. +- **Pré-condições:** Autenticado com perfil `MANAGER`. +- **Dados Utilizados:** Vagas retornadas pela API. +- **Etapas de Execução:** + 1. Acessar e renderizar a rota `/manager/vacancies`. + 2. Verificar os cards e dados das vagas ofertadas. +- **Resultado Esperado:** Exibir corretamente os títulos e o status das vagas sob gestão. +- **Trecho de Código:** +```typescript +import { render, screen } from "@testing-library/react"; +import MinhasVagasPage from "@/app/manager/vacancies/page"; + +describe("CT-007: Módulo do Gestor - Minhas Vagas", () => { + it("deve renderizar a tela de Minhas Vagas do Gestor", () => { + render(); + expect(screen.getByText(/Minhas Vagas/i)).toBeInTheDocument(); + }); +}); +``` +- **Prioridade:** Alta +- **Responsável pela Execução:** QA / Tester + +--- + +### CT-008: Telas do Perfil Coordenador (Dashboard, Turmas, Alunos, Cursos e Direcionamento) +- **Funcionalidade Testada:** Módulo do Coordenador (`src/app/dashboard/page.tsx`, `src/app/classes/page.tsx`, `src/app/students/page.tsx`, `src/app/courses/page.tsx` e `src/app/coordinator/direct/page.tsx`). +- **Objetivo do Teste:** Testar os cards do Dashboard, a consulta das entidades acadêmicas e o direcionamento de alunos para vagas. +- **Pré-condições:** Autenticado com perfil `COORDINATOR`. +- **Dados Utilizados:** Dados de alunos, turmas, cursos e vagas. +- **Etapas de Execução:** + 1. Renderizar o componente de Dashboard (`/dashboard`). + 2. Verificar os cards estatísticos (Total de Alunos, Turmas Ativas e Vagas Disponíveis). +- **Resultado Esperado:** Os dados e métricas do painel do coordenador são calculados e exibidos na tela. +- **Trecho de Código:** +```typescript +import { render, screen } from "@testing-library/react"; +import DashboardPage from "@/app/dashboard/page"; + +describe("CT-008: Módulo Coordenador - Painel Dashboard", () => { + it("deve exibir os cartões de estatísticas no painel do Coordenador", () => { + render(); + expect(screen.getByText(/Painel de Controle/i)).toBeInTheDocument(); + }); +}); +``` +- **Prioridade:** Alta +- **Responsável pela Execução:** QA / Tester + +--- + +### CT-009: Telas do Perfil Administrador (Usuários) +- **Funcionalidade Testada:** Módulo Geral de Administração (`src/app/admin/page.tsx`). +- **Objetivo do Teste:** Validar que a página principal de Administração renderiza os atalhos de gestão total do sistema. +- **Pré-condições:** Autenticado com perfil `ADMIN`. +- **Dados Utilizados:** Seções do painel administrativo. +- **Etapas de Execução:** + 1. Renderizar a rota `/admin`. + 2. Verificar a presença do acesso a Usuários e a ausência dos módulos de outros perfis. +- **Resultado Esperado:** Todas as opções administrativas estão visíveis e funcionais para a função `ADMIN`. +- **Trecho de Código:** +```typescript +import { render, screen } from "@testing-library/react"; +import AdminDashboardPage from "@/app/admin/page"; + +describe("CT-009: Painel de Controle Administrador", () => { + it("deve carregar o painel geral de administração do sistema", () => { + render(); + expect(screen.getByText(/Painel de Administração/i)).toBeInTheDocument(); + }); +}); +``` +- **Prioridade:** Alta +- **Responsável pela Execução:** QA / Tester + +--- + +## 4. Resumo de Cobertura dos Requisitos do Projeto + +| Categoria Requerida | Casos de Teste Associados | +| :--- | :--- | +| **Navegação entre telas** | CT-001, CT-006, CT-007, CT-008, CT-009 | +| **Carregamento de dados** | CT-002, CT-007, CT-008, CT-009 | +| **Estados de carregamento** | CT-002 | +| **Estados de erro** | CT-005 | +| **Validação de formulários** | CT-003, CT-009 | +| **Cadastro** | CT-003, CT-008, CT-009 | +| **Edição** | CT-004, CT-008, CT-009 | +| **Exclusão** | CT-004, CT-009 | +| **Responsividade** | CT-006 | +| **Feedback visual** | CT-002, CT-003, CT-004, CT-007, CT-008, CT-009 | +| **Dados inválidos / Indisponibilidade API** | CT-003, CT-005 | diff --git a/my-app/design-system/DESIGN_SYSTEM.md b/my-app/design-system/DESIGN_SYSTEM.md new file mode 100644 index 0000000..4a53e9d --- /dev/null +++ b/my-app/design-system/DESIGN_SYSTEM.md @@ -0,0 +1,334 @@ +# Quick Transfer — Design System Audit + +> Documento atualizado com os valores exatos do Figma/design spec. + +--- + +## 1. Paleta de Cores + +### 1.1 Primary (Azul Marinho / Navy) + +Cor dominante usada na sidebar, background do login, botões primários e cabeçalhos. + +| Token | Hex | Uso principal | +|------------------|-------------|------------------------------------------------------| +| `primary-50` | `#ECF1FF` | Background da sidebar, áreas sutis | +| `primary-100` | `#D5E3FF` | Hover leve, background de seleção | +| `primary-200` | `#A7C8FF` | Bordas de botões primários, divisores claros | +| `primary-300` | `#89ACE7` | Borda do botão de login, ícones inativos | +| `primary-400` | `#6E92CA` | Links hover, ícones secundários | +| `primary-500` | `#5478AF` | Links ativos, ícones de ação | +| `primary-600` | `#3A5F94` | Botões secundários, estados ativos | +| `primary-700` | `#00579D` | Hover de botões primários | +| `primary-800` | `#00335C` | Botões primários, sidebar ativa | +| `primary-900` | `#001E40` | Background do botão da sidebar, sidebar background | +| `primary-950` | `#000000` | Background mais profundo | + +### 1.2 Secondary (Cyan / Teal) + +Usado em elementos de suporte, backgrounds secundários e destaques informativos. + +| Token | Hex | Uso principal | +|--------------------|-------------|----------------------------------------------| +| `secondary-50` | `#E3F3FF` | Background de áreas de conteúdo | +| `secondary-100` | `#C4E7FF` | Bordas de tabelas, separadores | +| `secondary-200` | `#7BD0FF` | Bordas de inputs, estados leves | +| `secondary-300` | `#2DB7F2` | Ícones informativos, destaques | +| `secondary-400` | `#009BD1` | Links secundários, ações informativas | +| `secondary-500` | `#0080AD` | Botões secundários, texto de ênfase | +| `secondary-600` | `#00668A` | Hover de botões secundários | +| `secondary-700` | `#004C69` | Texto de cabeçalhos de tabela | +| `secondary-800` | `#00354A` | Textos de alta ênfase secundária | +| `secondary-900` | `#001E2C` | Texto principal de alta ênfase | + +### 1.2b Tertiary (Azul-Acinzentado / Blue-Gray) + +Usado em textos de suporte, ícones desabilitados e áreas neutras com tom azulado. + +| Token | Hex | Uso principal | +|--------------------|-------------|----------------------------------------------| +| `tertiary-50` | `#E9F1FF` | Background de áreas de conteúdo leve | +| `tertiary-100` | `#D4E4FA` | Bordas sutis, separadores leves | +| `tertiary-200` | `#B9C8DE` | Bordas de inputs inativos | +| `tertiary-300` | `#9DACC2` | Texto placeholder, ícones desabilitados | +| `tertiary-400` | `#8392A6` | Texto secundário, labels de forms | +| `tertiary-500` | `#69788C` | Texto de corpo secundário | +| `tertiary-600` | `#516072` | Texto de cabeçalhos de tabela | +| `tertiary-700` | `#39485A` | Texto de ênfase | +| `tertiary-800` | `#233143` | Sidebar sections | +| `tertiary-900` | `#0D1C2D` | Texto principal de alta ênfase | + +### 1.3 Neutros (Escala de Cinzas) + +Aplicados em backgrounds, bordas, textos de corpo e elementos de UI neutra. + +| Token | Hex | Uso principal | +|------------------|-------------|-------------------------------------------------| +| `neutral-50` | `#EFF1F3` | Background da página principal | +| `neutral-100` | `#E0E3E5` | Background de cards, campos de formulário | +| `neutral-200` | `#C4C7C9` | Bordas sutis, separadores de linhas de tabela | +| `neutral-300` | `#A9ABAD` | Bordas de inputs, divisores | +| `neutral-400` | `#8E9193` | Texto placeholder, ícones inativos | +| `neutral-500` | `#747779` | Texto de apoio, labels | +| `neutral-600` | `#5C5F61` | Texto de corpo | +| `neutral-700` | `#444749` | Texto de ênfase secundária | +| `neutral-800` | `#2D3133` | Títulos e headings | +| `neutral-900` | `#191C1E` | Texto de máxima ênfase | + +### 1.4 Accent / Gold-Beige (Escala Dourada) + +Aparece na folha de tokens como uma escala separada (tons beige/dourados). Uso provável: destaques especiais, alertas informativos ou variante decorativa. + +| Token | Hex | Uso principal | +|----------------|-----------|---------------------------------------------| +| `accent-50` | `#FFF8E1` | Background de alertas/informações leves | +| `accent-100` | `#FFECB3` | Background de tags/badges informativos | +| `accent-200` | `#FFE082` | Bordas de destaque | +| `accent-300` | `#FFD54F` | Ícones de aviso suave | +| `accent-400` | `#FFCA28` | Badges de alerta | +| `accent-500` | `#FFC107` | Cor de destaque primária dourada | +| `accent-600` | `#FFB300` | Texto/ícone de aviso | +| `accent-700` | `#FF8F00` | Hover de elementos dourados | + +--- + +## 2. Cores Semânticas de Status + +Observadas nos badges das telas de admin (entrevistas, vagas, cursos, usuários): + +| Token | Hex (bg) | Hex (text) | Significado visual nos protótipos | Exemplos de uso | +|-------------------|-----------|------------|-------------------------------------------------------|----------------------------------------------------| +| `status-success` | `#DCFCE7` | `#166534` | Aprovado, Aberto, Ativo, Concluído | Badge "Aprovado" em entrevistas, "Aberto" em vagas | +| `status-danger` | `#FEE2E2` | `#991B1B` | Urgente, Atrasado, Fechado, Reprovado, Inativo | Badge "Reprovado", "Fechado", "Urgente" | +| `status-warning` | `#FEF3C7` | `#92400E` | Pendente, Atenção, Em revisão | Badge de aviso / pendência | +| `status-info` | `#DBEAFE` | `#1E40AF` | Em andamento, Informativo, Em processo | Badge "Em andamento", "Agendada" | +| `status-neutral` | `#F3F4F6` | `#4B5563` | Inativo, Rascunho, Sem status definido | Badge "Inativo", estados desabilitados | + +> **Nota de acessibilidade:** Todos os badges devem incluir texto descritivo (e idealmente um ícone), +> nunca dependendo apenas da cor para transmitir significado (WCAG 1.4.1). + +--- + +## 3. Tipografia + +**Fonte principal:** Manrope (já configurada no `layout.tsx` existente) + +### Escala de Tamanhos e Pesos + +Baseada nos exemplos "Aa" da folha de tokens e nos textos das telas: + +| Token / Uso | Tamanho (px) | Tamanho (rem) | Peso | Line Height | Exemplo no protótipo | +|---------------------------|--------------|---------------|----------|-------------|-----------------------------------------------| +| `display-lg` | 44px | 2.75rem | 300 | 1.1 | "Quick Transfer" no login | +| `heading-xl` | 32px | 2rem | 600 | 1.25 | "Login" no card | +| `heading-lg` | 24px | 1.5rem | 600 | 1.33 | Títulos de página ("Painel do Coordenador") | +| `heading-md` | 20px | 1.25rem | 600 | 1.4 | Títulos de seção, labels de form | +| `heading-sm` | 16px | 1rem | 600 | 1.5 | Nomes em cards, cabeçalhos de tabela | +| `body-lg` | 16px | 1rem | 400 | 1.5 | Corpo principal, botões | +| `body-md` | 14px | 0.875rem | 400 | 1.5 | Texto de tabela, campos de formulário | +| `body-sm` | 12px | 0.75rem | 400 | 1.5 | Captions, labels auxiliares, pagination info | +| `body-xs` | 10px | 0.625rem | 400 | 1.4 | Badges de status (texto pequeno) | +| `number-stat` | 48px | 3rem | 700 | 1.0 | Números grandes nos cards de estatística | + +--- + +## 4. Espaçamento e Raio de Borda + +### 4.1 Escala de Espaçamento + +Observada nos protótipos (padding de cards, gaps entre elementos, margens): + +| Token | Valor | Uso principal | +|---------|--------|--------------------------------------------------------| +| `sp-1` | 4px | Gap mínimo entre ícone e texto inline | +| `sp-2` | 8px | Padding interno de badges, gap entre itens de lista | +| `sp-3` | 12px | Padding de inputs, gap pequeno entre elementos | +| `sp-4` | 16px | Padding horizontal de botões, gap entre itens de form | +| `sp-5` | 20px | Padding interno de cards, espaço entre seções | +| `sp-6` | 24px | Margem entre cards, gap de grid | +| `sp-8` | 32px | Padding do container da página, margens amplas | +| `sp-10` | 40px | Margem entre seções maiores | +| `sp-12` | 48px | Margem de topo de páginas | +| `sp-16` | 64px | Espaçamento vertical grande entre blocos | + +### 4.2 Raio de Borda (Border Radius) + +| Token | Valor | Uso | +|----------------|--------|------------------------------------------------| +| `radius-sm` | 4px | Badges de status, tags pequenas | +| `radius-md` | 8px | Inputs, botões, cards de lista | +| `radius-lg` | 12px | Cards de conteúdo, modais | +| `radius-xl` | 16px | Cards de login, containers destacados | +| `radius-2xl` | 20px | Card principal do login | +| `radius-full` | 9999px | Avatares, botões arredondados (FAB) | + +--- + +## 5. Sombras + +| Token | Valor CSS | Uso | +|----------------|--------------------------------------------------|-----------------------------------| +| `shadow-sm` | `0 1px 2px rgba(0,0,0,0.05)` | Cards sutis, inputs | +| `shadow-md` | `0 4px 6px -1px rgba(0,0,0,0.1)` | Cards de conteúdo, dropdowns | +| `shadow-lg` | `0 10px 15px -3px rgba(0,0,0,0.1)` | Modais, card de login | +| `shadow-xl` | `0 20px 25px -5px rgba(0,0,0,0.1)` | Dialogs, sheets | + +--- + +## 6. Inventário de Componentes Reutilizáveis + +### 6.1 Sidebar de Navegação + Topbar/Header + +- **Sidebar:** Fixa à esquerda, background `primary-900` (#001E40, navy escuro). Contém: + - Logo "Quick Transfer" no topo (ícone + texto branco) + - Links de navegação com ícones (Lucide), texto branco/acinzentado + - Item ativo com destaque (fundo levemente mais claro ou borda lateral) + - Seções agrupadas (ex: "Coordenador" / "Admin") + - Rodapé com ícone de logout e nome do usuário + - Largura: ~240px (desktop), colapsável em mobile +- **Topbar:** Barra horizontal acima do conteúdo, fundo branco. Contém: + - Breadcrumb de navegação (ex: "Quick Transfer > Turnos > ...") + - Ações à direita: ícone de notificação (bell), avatar do usuário + - Altura: ~60px + +### 6.2 Botão (Button) + +Variantes observadas nos protótipos: +- **Primary:** Background `primary-800` (#003061), texto branco, borda `primary-300` (como no login) +- **Secondary/Outline:** Background transparente, borda cinza, texto escuro +- **Destructive/Danger:** Background vermelho (`status-danger`), texto branco — visto em ações de exclusão +- **Ghost:** Sem background/borda, texto primário — links internos +- **Icon-only:** Botão quadrado com ícone (ex: editar, excluir nas tabelas) +- Tamanhos: `sm` (badges de ação), `md` (padrão), `lg` (botão do login) + +### 6.3 Input de Texto e Input de Busca + +- **Input padrão:** Border `neutral-300`, background `neutral-50`/`#F8FBFF`, border-radius `radius-md`, padding `sp-3`. Focus: border `primary-600`, background `primary-50` +- **Input de busca:** Mesmo estilo + ícone de lupa (Search) à esquerda +- Todos com label acima, placeholder em `neutral-400` + +### 6.4 Tabela com Paginação + +Presente em: Usuários, Locais, Entrevistas, Turmas, Vagas, Cursos. +- **Cabeçalho:** Background levemente cinza (`neutral-50`), texto `secondary-600` em peso 600 +- **Linhas:** Alternância sutil de cor ou borda inferior `neutral-200` +- **Células:** Podem conter text, badge, avatar, botões de ação (ícones de editar/excluir) +- **Paginação:** Abaixo da tabela — botões de página (prev/next + números), indicador "Mostrando X de Y" +- **Ordenação:** Ícones de seta nos cabeçalhos para ordenação ascendente/descendente + +### 6.5 Badge/Pill de Status + +Elemento inline arredondado com texto + fundo colorido: +- **success:** fundo verde claro, texto verde escuro (ex: "Aprovado", "Aberto", "Ativo") +- **danger:** fundo vermelho claro, texto vermelho escuro (ex: "Reprovado", "Fechado", "Urgente") +- **warning:** fundo amarelo claro, texto marrom/âmbar (ex: "Pendente") +- **info:** fundo azul claro, texto azul escuro (ex: "Em andamento", "Agendada") +- **neutral:** fundo cinza claro, texto cinza escuro (ex: "Inativo") +- Border-radius: `radius-sm` a `radius-full` (pill) +- Font-size: `body-sm` ou `body-xs` +- Padding: `sp-1` vertical, `sp-2` horizontal + +### 6.6 Avatar + +- Circular (`radius-full`), tamanhos: `sm` (32px), `md` (40px), `lg` (64px), `xl` (96px — perfil do aluno) +- Com imagem ou fallback de iniciais (fundo `primary-600`, texto branco) +- Visto em: tabela de usuários, card de aluno, topbar + +### 6.7 Card de Estatística (Stat Card) + +Usado no Dashboard do Coordenador: +- Número grande (`number-stat`), label descritivo abaixo +- Ícone no canto (estilo outline, cor `primary-500`) +- Background branco, borda `neutral-200`, sombra `shadow-sm` +- Layout horizontal: texto à esquerda, ícone à direita + +### 6.8 Card de Item de Lista + +Usado para listar alunos, turmas, entrevistas, vagas: +- Layout: avatar/ícone + informações textuais (nome, cargo, data) + badges de status + ações +- Borda inferior ou separador entre itens +- Hover com background `neutral-50` + +### 6.9 Barra de Progresso (Progress Bar) + +Visível na tela de turnos (ocupação de turno): +- Track cinza (`neutral-200`), fill azul (`primary-600`) +- Texto de porcentagem ao lado +- Altura: ~8px, border-radius: `radius-full` + +### 6.10 Painel Lateral (Drawer/Sheet) + +Visível na tela de ajuste manual de turno: +- Desliza da direita, fundo branco, sombra à esquerda +- Contém: título, conteúdo de formulário/lista, botões de ação no rodapé +- Overlay escuro semi-transparente no fundo +- Largura: ~400px + +### 6.11 Item de Timeline/Notificação + +Visível na tela de Detalhes do Aluno: +- Linha vertical conectando os itens (timeline indicator) +- Cada item: badge de status + descrição + data/hora +- Cores dos badges conforme tabela semântica (seção 2) + +### 6.12 Modal de Confirmação / Formulário + +- **Confirmação:** Background overlay, card central com título, mensagem, botões "Cancelar" / "Confirmar" +- **Formulário (ex: "Nova Turma"):** Pode ser modal ou página inteira — nos protótipos aparece como página com formulário (título + inputs + seleção de alunos + botões de ação) + +### 6.13 Botão de Ação Flutuante (FAB) + +Visível em telas de admin (lista de cursos, lista de vagas): +- Botão circular no canto inferior direito +- Ícone "+" branco, background `primary-600` +- Sombra `shadow-lg` +- Tamanho: ~56px + +### 6.14 Componentes Adicionais Identificados + +- **Breadcrumb:** Navegação hierárquica na topbar (ex: "Quick Transfer > Turnos > Detalhes") +- **Tabs:** Abas de navegação dentro de páginas (ex: filtros de status em cursos: "Todos", "Concluídos", "Em andamento") +- **Select/Dropdown:** Campo de seleção em formulários (ex: selecionar turno, selecionar período) +- **Checkbox:** Para seleção múltipla de alunos (em "Nova Turma") +- **Empty State:** Ícone + mensagem quando não há dados (ex: "Nenhum turno encontrado") +- **Tooltip:** Nos ícones de ação das tabelas +- **Separator/Divider:** Linha horizontal sutil entre seções + +--- + +## 7. Mapeamento para shadcn/ui + +| Componente do protótipo | Componente shadcn | Customização necessária | +|-----------------------------------|-------------------------|--------------------------------------------------------| +| Botão | `button` | Variantes de cor via CVA (já suportado) | +| Input de texto / busca | `input` | Composição com ícone Lucide (search) | +| Tabela | `table` | Paginação e ordenação manual por cima | +| Badge de status | `badge` | Novas variantes: success, warning, info, neutral | +| Avatar | `avatar` | Fallback de iniciais (já suportado) | +| Card (estatística, item) | `card` | Composição: StatCard, ListItemCard | +| Barra de progresso | `progress` | Cores customizadas via CSS vars | +| Painel lateral | `sheet` | Já suportado | +| Modal | `dialog` | Já suportado | +| Abas | `tabs` | Já suportado | +| Select/Dropdown | `select` | Já suportado | +| Checkbox | `checkbox` | Já suportado | +| Separator | `separator` | Já suportado | +| Tooltip | `tooltip` | Já suportado | +| Breadcrumb | `breadcrumb` | Já suportado | +| Sidebar + Topbar | **Manual** (layout) | Componentes compostos customizados | +| Card de estatística | **Manual** (features) | Composição de `card` + Lucide icon | +| Item de timeline | **Manual** (features) | Componente customizado | +| FAB (botão flutuante) | **Manual** (layout) | Composição de `button` + posição fixed | +| Empty State | **Manual** (ui) | Componente customizado simples | +| Page Header | **Manual** (layout) | Título + ações + breadcrumb | + +--- + +## 8. Decisões e Suposições Pendentes + +1. **Cores exatas:** ✅ Valores atualizados com as cores exatas do design spec (Primary, Secondary, Tertiary e Neutral). +2. **Fonte secundária:** Não identifiquei uma segunda família tipográfica nos protótipos. Assumo que Manrope é usada em toda a interface. +3. **Ícones:** Assumo Lucide React como biblioteca de ícones (padrão shadcn/ui). Confirmar se os ícones nos protótipos são Lucide ou outra biblioteca. +4. **Sidebar responsiva:** Nos protótipos desktop, a sidebar é fixa. Assumo que em mobile ela se torna um drawer/hamburger menu. Confirmar comportamento desejado. +5. **Temas claro/escuro:** Os protótipos mostram apenas tema claro para as páginas internas. A folha de tokens tem fundo escuro, mas parece ser apenas a apresentação dos tokens. Confirmar se dark mode é necessário. +6. **Navegação:** Assumo que a sidebar tem os mesmos itens para coordenador e admin, com agrupamento por seção. Confirmar se há controle de visibilidade por role. diff --git a/my-app/next.config.ts b/my-app/next.config.ts index 66e1566..2dc3247 100644 --- a/my-app/next.config.ts +++ b/my-app/next.config.ts @@ -1,8 +1,14 @@ import type { NextConfig } from "next"; +import path from "node:path"; + +const projectRoot = path.resolve(process.cwd()); const nextConfig: NextConfig = { - /* config options here */ reactCompiler: true, + turbopack: { + // `__dirname` was evaluated as an empty string by Turbopack on Windows. + root: projectRoot, + }, }; export default nextConfig; diff --git a/my-app/package-lock.json b/my-app/package-lock.json index f339f08..8f3697c 100644 --- a/my-app/package-lock.json +++ b/my-app/package-lock.json @@ -8,18 +8,25 @@ "name": "my-app", "version": "0.1.0", "dependencies": { - "next": "16.3.0", - "react": "19.2.8", - "react-dom": "19.2.8" + "@base-ui/react": "^1.6.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^1.26.0", + "next": "16.2.10", + "react": "19.2.4", + "react-dom": "19.2.4", + "shadcn": "^4.14.0", + "tailwind-merge": "^3.6.0", + "tw-animate-css": "^1.4.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", "@types/node": "^20", - "@types/react": "^19", + "@types/react": "^19.2.17", "@types/react-dom": "^19", "babel-plugin-react-compiler": "1.0.0", "eslint": "^9", - "eslint-config-next": "16.3.0", + "eslint-config-next": "16.2.10", "tailwindcss": "^4", "typescript": "^5" } @@ -40,7 +47,6 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", @@ -54,7 +60,6 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -63,7 +68,6 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -90,13 +94,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", - "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", - "dev": true, + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", "dependencies": { - "@babel/parser": "^7.29.8", - "@babel/types": "^7.29.8", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -105,11 +108,22 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", + "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", @@ -121,11 +135,44 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz", + "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/traverse": "^7.29.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/helper-globals": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", - "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz", + "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, "engines": { "node": ">=6.9.0" } @@ -134,7 +181,6 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", - "dev": true, "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" @@ -147,7 +193,6 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", - "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7", @@ -160,11 +205,61 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz", + "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz", + "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz", + "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", - "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -173,7 +268,6 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", - "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -182,7 +276,6 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -191,7 +284,6 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", - "dev": true, "dependencies": { "@babel/template": "^7.29.7", "@babel/types": "^7.29.7" @@ -201,12 +293,11 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", - "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", - "dev": true, + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", "dependencies": { - "@babel/types": "^7.29.8" + "@babel/types": "^7.29.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -215,11 +306,103 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz", + "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz", + "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/plugin-syntax-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz", + "integrity": "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/plugin-transform-modules-commonjs": "^7.29.7", + "@babel/plugin-transform-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/parser": "^7.29.7", @@ -230,17 +413,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", - "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", - "dev": true, + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", "dependencies": { "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.8", + "@babel/generator": "^7.29.7", "@babel/helper-globals": "^7.29.7", - "@babel/parser": "^7.29.8", + "@babel/parser": "^7.29.7", "@babel/template": "^7.29.7", - "@babel/types": "^7.29.8", + "@babel/types": "^7.29.7", "debug": "^4.3.1" }, "engines": { @@ -248,10 +430,9 @@ } }, "node_modules/@babel/types": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", - "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", - "devOptional": true, + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" @@ -260,14 +441,309 @@ "node": ">=6.9.0" } }, + "node_modules/@base-ui/react": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@base-ui/react/-/react-1.7.0.tgz", + "integrity": "sha512-j+8QjX44C32jrXD/qyEAGpFr70FRpGL2CY61mQd9nBPWN737CK0xxD1ceJ055rW4RtdvFDT1e7otzdlfxvsYug==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@base-ui/utils": "0.3.2", + "@floating-ui/react-dom": "^2.1.9", + "@floating-ui/utils": "^0.2.12", + "use-sync-external-store": "^1.6.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@date-fns/tz": "^1.2.0", + "@types/react": "^17 || ^18 || ^19", + "date-fns": "^4.0.0", + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@date-fns/tz": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "date-fns": { + "optional": true + } + } + }, + "node_modules/@base-ui/utils": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@base-ui/utils/-/utils-0.3.2.tgz", + "integrity": "sha512-oWy1aq/I2GmYjpl4PhEAhzflF8VPGKgZeq0xAWTbfD5KBWyxcN0ZP2+WHSUm/5Z6lVMBDLReLcoXwSYoRc/zNQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@floating-ui/utils": "^0.2.12", + "reselect": "^5.2.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "@types/react": "^17 || ^18 || ^19", + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@dotenvx/dotenvx": { + "version": "1.75.1", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.75.1.tgz", + "integrity": "sha512-/BITOC9dmS/edY2zQwZNicQ059O6RKabtQfyEafV0nGtfYRNHYy1DIPiYVcov40+tob9hfmBnbR963dS+EQ1DQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@dotenvx/primitives": "^0.8.0", + "commander": "^11.1.0", + "conf": "^10.2.0", + "dotenv": "^17.2.1", + "enquirer": "^2.4.1", + "env-paths": "^2.2.1", + "execa": "^5.1.1", + "fdir": "^6.2.0", + "ignore": "^5.3.0", + "object-treeify": "1.1.33", + "open": "^8.4.2", + "picomatch": "^4.0.4", + "systeminformation": "^5.22.11", + "undici": "^7.11.0", + "which": "^4.0.0", + "yocto-spinner": "^1.1.0" + }, + "bin": { + "dotenvx": "src/cli/dotenvx.js" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/@dotenvx/dotenvx/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@dotenvx/dotenvx/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@dotenvx/primitives": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@dotenvx/primitives/-/primitives-0.8.0.tgz", + "integrity": "sha512-VYJy0uhFm9zTJ1TxBaW/pA8bjbOM/OttaNMwZ1RHG4JKyRG7DhSdiqD1ipQoAyoD22olUtxbP78W9xY3Wd11bg==", + "license": "BSD-3-Clause" + }, "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.3.tgz", + "integrity": "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==", "dev": true, "optional": true, + "peer": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.1", + "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" } }, @@ -281,19 +757,21 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz", + "integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==", "dev": true, + "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", - "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -424,6 +902,56 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.8.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", + "license": "MIT" + }, + "node_modules/@hono/node-server": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.0.tgz", + "integrity": "sha512-XovyyCCnBzW+zKu+z/zq8hwNs4KOR5rEMAOxo2f40Q5xoOI37IMm6MIg2COOUtUApo0i6850MTBKH2u4QLGIqg==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "hono": "^4" + } + }, "node_modules/@humanfs/core": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", @@ -489,78 +1017,64 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=18" } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz", - "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", "cpu": [ "arm64" ], + "license": "Apache-2.0", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.3.2" + "@img/sharp-libvips-darwin-arm64": "1.2.4" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz", - "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.3.2" - } - }, - "node_modules/@img/sharp-freebsd-wasm32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz", - "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==", - "optional": true, - "os": [ - "freebsd" - ], - "dependencies": { - "@img/sharp-wasm32": "0.35.3" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "@img/sharp-libvips-darwin-x64": "1.2.4" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz", - "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", "cpu": [ "arm64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" @@ -570,12 +1084,13 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz", - "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", "cpu": [ "x64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" @@ -585,12 +1100,13 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz", - "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", "cpu": [ "arm" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -600,12 +1116,13 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz", - "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", "cpu": [ "arm64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -615,12 +1132,13 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz", - "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", "cpu": [ "ppc64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -630,12 +1148,13 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz", - "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", "cpu": [ "riscv64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -645,12 +1164,13 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz", - "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", "cpu": [ "s390x" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -660,12 +1180,13 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz", - "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", "cpu": [ "x64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -675,12 +1196,13 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz", - "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", "cpu": [ "arm64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -690,12 +1212,13 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz", - "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", "cpu": [ "x64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -705,255 +1228,252 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz", - "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", "cpu": [ "arm" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.3.2" + "@img/sharp-libvips-linux-arm": "1.2.4" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz", - "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", "cpu": [ "arm64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.3.2" + "@img/sharp-libvips-linux-arm64": "1.2.4" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz", - "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", "cpu": [ "ppc64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.3.2" + "@img/sharp-libvips-linux-ppc64": "1.2.4" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz", - "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", "cpu": [ "riscv64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.3.2" + "@img/sharp-libvips-linux-riscv64": "1.2.4" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz", - "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", "cpu": [ "s390x" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.3.2" + "@img/sharp-libvips-linux-s390x": "1.2.4" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz", - "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.3.2" + "@img/sharp-libvips-linux-x64": "1.2.4" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz", - "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", "cpu": [ "arm64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.3.2" + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz", - "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.3.2" + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz", - "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.11.1" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-webcontainers-wasm32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz", - "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", "cpu": [ "wasm32" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { - "@img/sharp-wasm32": "0.35.3" + "@emnapi/runtime": "^1.7.0" }, "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz", - "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", "cpu": [ "arm64" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz", - "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", "cpu": [ "ia32" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" ], "engines": { - "node": "^20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz", - "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", "cpu": [ "x64" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" @@ -963,7 +1483,6 @@ "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" @@ -973,7 +1492,6 @@ "version": "2.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -983,7 +1501,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -991,92 +1508,121 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", + "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9 || ^2.0.5", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.2.tgz", - "integrity": "sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", "dev": true, "optional": true, "dependencies": { "@tybys/wasm-util": "^0.10.3" }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=23.5.0" - }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" }, "peerDependencies": { - "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", - "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, "node_modules/@next/env": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.0.tgz", - "integrity": "sha512-o9r1S0BNiNreHP9Vs+Qnqd9kviDkJh8xIACY7UFZSmiGbbQRzPBBosvHzAU4TULHOIuOj/18RSsyz2qrREmIFw==" + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.10.tgz", + "integrity": "sha512-zLPxg9M0MEHmygpj5OuxjQ+vHMiy/K7cSp74G8ecYolmgUWw0RwN02tF56npup/+qaI8JB97hQgS/r2Hb6QwVA==", + "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.3.0.tgz", - "integrity": "sha512-OqgJ8PN0d04KcPhDX/PTY5tJUJZxlbrt7O7FBsm4XE0XW2JDrKnDXsc9uo9WUimJGPoo2j+JRGhyXApC//mvbw==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.10.tgz", + "integrity": "sha512-Gs8D2m21VnJeFo9qvYIIqJH94frWerWYu41BprU1pLtRVF7PCQNLiFZZ3fG+iPuj3K83Cwv/rt+msLOy8Qgu3Q==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "4.9.1", "fast-glob": "3.3.1" } }, - "node_modules/@next/eslint-plugin-next/node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@next/eslint-plugin-next/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@next/swc-darwin-arm64": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.0.tgz", - "integrity": "sha512-55hpqq18bEVAlxedlTt3tFqZmKg2nUXT1kn1G/BGEy0R13h3LwtwHPVzzjG6P4LLeOHE32PFDQUVaJEWvBEZBw==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.10.tgz", + "integrity": "sha512-v9IdJCa0H0mbo+8z5zwUpOk1Vj7RjkcI5uNYf5Ws1y6szf/p3Mzl9hLaST8SCt6L9h8NGnruZcd2+o0NTNwDhA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1086,12 +1632,13 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.0.tgz", - "integrity": "sha512-SOi96kSaF5T+0wW4koiM1bWzSPwjzTesC1p3df+FjdOi5LIQkBK/blxh7HdoKnNuI4PURF1OO7TZqtfnbWDSgw==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.10.tgz", + "integrity": "sha512-17IS0jJRViROGmA9uGdNR8VPJpfbnaVG7E9qhso5jDLkmyd0lSDORWxbcKINzcFqzZqGwGtMSnrFRxBpuUYjLQ==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1101,12 +1648,13 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.0.tgz", - "integrity": "sha512-P0gZAoPMF4dyTRzhmkV4PrqVzSOB6t4mC1oI3c4dqijJ+OVEVx5clIXAKR4/uQpsqw2KKM/0D5tVumcR2r5blg==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.10.tgz", + "integrity": "sha512-GRQRsRtuciNJvB54AvvuQTiq0oZtFwa1owQqtZD8wwnGpM2L39MV22kpI72YSXLKIyY40LC66EiLFv4PiicXxg==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -1116,12 +1664,13 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.0.tgz", - "integrity": "sha512-tXXGKJw0m37O0eKJARVTX/TheKPhz0QFVtVVZXmOig+9YKLQOSP6hvf2pxv5DO7CLEJyTHx3Pg043CDQkv1G4Q==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.10.tgz", + "integrity": "sha512-zkN9MQYS7UQBro+FnISUq1itaQjXI9xqISzuQ+2bc921NcJ1x4yPCqrn77tVN6/dOOXaaWVX3k6/bR07pPwK+A==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -1131,12 +1680,13 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.0.tgz", - "integrity": "sha512-pjGxK5EY7yWml78ALejFkWmgHsU7wbFQrISiugpH6FbUJhgEvw3xFZ/EBAtLl7QtL0WdQKiG9eWJ3mOKGTukHw==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.10.tgz", + "integrity": "sha512-iCVJnwvrPYECvA6WM/7+oo+OiTvedIKLxtCLAZP4xZR3nXa1zmzZyLPbYCmWvpd4CvMYF1EMTafd0ii3DygLvA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -1146,12 +1696,13 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.0.tgz", - "integrity": "sha512-sjo++Xx+lomlPs3HRsHWhVDyGG6ms1kGW5EtHLERdII8AyG1i+f6aq68xHREO6AEMlhjTNEWBSmfJfqm9orf7g==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.10.tgz", + "integrity": "sha512-ov2g4H0dHY9bPoOU83m91hWT7Iq5qy13bUnyyshLU3HGR1Ownn0X9QpmDPc5iIUaahTp7f7LeGAhV4DSFtackw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -1161,12 +1712,13 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.0.tgz", - "integrity": "sha512-C5JSgiO54wURdaxdEUIXqkz04uMqC9UmPX1gtDrV/5Tf1UowdWYI8uA5hfFbPolTlp0q4KZ60xlHePNibf0VIw==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.10.tgz", + "integrity": "sha512-DwAnhLX76HQiFFQNgWlcK+JzlnD1rZ+UK/WY0ZMI/deXpvgnesjNYrqcfo1JzBuz4Kf7o3brIBL0glI1junatA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -1176,12 +1728,13 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.0.tgz", - "integrity": "sha512-fDOggsweNb5SSw0ZKVk6U+gxSyGFFlIBY/LBc1r8GUj4u/6t6oArL+Pmkg0MBnsgR+KkdsURilVH4F3GXUGepA==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.10.tgz", + "integrity": "sha512-0JXq3b85Jk9Jg4ntLUbXSPvoDw3gpZou7twuKdoFG2jOw635v7+IiXfTaa0TxVMyx78pUjnrVYwLgjKfX4e6/A==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -1194,7 +1747,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1207,7 +1760,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -1216,7 +1769,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1240,6 +1793,24 @@ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "dev": true }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@swc/helpers": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", @@ -1249,47 +1820,47 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", - "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.2.tgz", + "integrity": "sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg==", "dev": true, "dependencies": { "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.24.1", + "enhanced-resolve": "5.21.6", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.3.3" + "tailwindcss": "4.3.2" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", - "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.2.tgz", + "integrity": "sha512-z8ZgnzX8gdNoWLBLqBPoh/sjnxkwvf9ZuWjnO0l0yIzbLa5/9S+eC5QxGZKRobVHIC3/1BoMWjHblqWjcgFgag==", "dev": true, "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.3.3", - "@tailwindcss/oxide-darwin-arm64": "4.3.3", - "@tailwindcss/oxide-darwin-x64": "4.3.3", - "@tailwindcss/oxide-freebsd-x64": "4.3.3", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", - "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", - "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", - "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", - "@tailwindcss/oxide-linux-x64-musl": "4.3.3", - "@tailwindcss/oxide-wasm32-wasi": "4.3.3", - "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", - "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" + "@tailwindcss/oxide-android-arm64": "4.3.2", + "@tailwindcss/oxide-darwin-arm64": "4.3.2", + "@tailwindcss/oxide-darwin-x64": "4.3.2", + "@tailwindcss/oxide-freebsd-x64": "4.3.2", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.2", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.2", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.2", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.2", + "@tailwindcss/oxide-linux-x64-musl": "4.3.2", + "@tailwindcss/oxide-wasm32-wasi": "4.3.2", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.2", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.2" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", - "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.2.tgz", + "integrity": "sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA==", "cpu": [ "arm64" ], @@ -1303,9 +1874,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", - "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.2.tgz", + "integrity": "sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w==", "cpu": [ "arm64" ], @@ -1319,9 +1890,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", - "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.2.tgz", + "integrity": "sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ==", "cpu": [ "x64" ], @@ -1335,9 +1906,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", - "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.2.tgz", + "integrity": "sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA==", "cpu": [ "x64" ], @@ -1351,9 +1922,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", - "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.2.tgz", + "integrity": "sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w==", "cpu": [ "arm" ], @@ -1367,9 +1938,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", - "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.2.tgz", + "integrity": "sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw==", "cpu": [ "arm64" ], @@ -1383,9 +1954,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", - "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.2.tgz", + "integrity": "sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA==", "cpu": [ "arm64" ], @@ -1399,9 +1970,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", - "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.2.tgz", + "integrity": "sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w==", "cpu": [ "x64" ], @@ -1415,9 +1986,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", - "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.2.tgz", + "integrity": "sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw==", "cpu": [ "x64" ], @@ -1431,9 +2002,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", - "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.2.tgz", + "integrity": "sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -1459,10 +2030,76 @@ "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", - "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz", + "integrity": "sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ==", "cpu": [ "arm64" ], @@ -1476,9 +2113,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", - "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.2.tgz", + "integrity": "sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ==", "cpu": [ "x64" ], @@ -1492,16 +2129,91 @@ } }, "node_modules/@tailwindcss/postcss": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.3.tgz", - "integrity": "sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.2.tgz", + "integrity": "sha512-rjVWYCa7Ngbi5AarT6k8TkxUG3Wl1QKzHdIZVsjZSzf36Jmo2IKZt/NHRAwly8oDkbBOH0YTu+CHuf9jPxMc+g==", "dev": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.3.3", - "@tailwindcss/oxide": "4.3.3", - "postcss": "^8.5.16", - "tailwindcss": "4.3.3" + "@tailwindcss/node": "4.3.2", + "@tailwindcss/oxide": "4.3.2", + "postcss": "^8.5.15", + "tailwindcss": "4.3.2" + } + }, + "node_modules/@ts-morph/common": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz", + "integrity": "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.3", + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@ts-morph/common/node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@ts-morph/common/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@ts-morph/common/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@tybys/wasm-util": { @@ -1542,34 +2254,40 @@ } }, "node_modules/@types/react": { - "version": "19.2.18", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.18.tgz", - "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", - "dev": true, + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "devOptional": true, "dependencies": { "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.4.tgz", - "integrity": "sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "peerDependencies": { "@types/react": "^19.2.0" } }, + "node_modules/@types/validate-npm-package-name": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/validate-npm-package-name/-/validate-npm-package-name-4.0.2.tgz", + "integrity": "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.66.0.tgz", - "integrity": "sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz", + "integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.66.0", - "@typescript-eslint/type-utils": "8.66.0", - "@typescript-eslint/utils": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/type-utils": "8.64.0", + "@typescript-eslint/utils": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -1582,7 +2300,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.66.0", + "@typescript-eslint/parser": "^8.64.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -1597,15 +2315,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.66.0.tgz", - "integrity": "sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz", + "integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.66.0", - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", "debug": "^4.4.3" }, "engines": { @@ -1621,13 +2339,13 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.66.0.tgz", - "integrity": "sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz", + "integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==", "dev": true, "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.66.0", - "@typescript-eslint/types": "^8.66.0", + "@typescript-eslint/tsconfig-utils": "^8.64.0", + "@typescript-eslint/types": "^8.64.0", "debug": "^4.4.3" }, "engines": { @@ -1642,13 +2360,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.66.0.tgz", - "integrity": "sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz", + "integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0" + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1659,9 +2377,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.66.0.tgz", - "integrity": "sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz", + "integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1675,14 +2393,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.66.0.tgz", - "integrity": "sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz", + "integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0", - "@typescript-eslint/utils": "8.66.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/utils": "8.64.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1699,9 +2417,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.66.0.tgz", - "integrity": "sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz", + "integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1712,15 +2430,15 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.66.0.tgz", - "integrity": "sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz", + "integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.66.0", - "@typescript-eslint/tsconfig-utils": "8.66.0", - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0", + "@typescript-eslint/project-service": "8.64.0", + "@typescript-eslint/tsconfig-utils": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1748,24 +2466,24 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", "dev": true, "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "10.2.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", - "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "dependencies": { - "brace-expansion": "^5.0.8" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -1787,15 +2505,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.66.0.tgz", - "integrity": "sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz", + "integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.66.0", - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0" + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1810,12 +2528,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.66.0.tgz", - "integrity": "sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz", + "integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/types": "8.64.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2090,6 +2808,18 @@ "node": ">=14.0.0" } }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", @@ -2100,6 +2830,17 @@ "tslib": "^2.4.0" } }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", @@ -2139,10 +2880,23 @@ "win32" ] }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", - "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2176,6 +2930,63 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2194,8 +3005,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/aria-query": { "version": "5.3.2", @@ -2358,6 +3168,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/ast-types-flow": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", @@ -2373,6 +3195,15 @@ "node": ">= 0.4" } }, + "node_modules/atomically": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", + "license": "MIT", + "engines": { + "node": ">=10.12.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2389,9 +3220,9 @@ } }, "node_modules/axe-core": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.13.0.tgz", - "integrity": "sha512-UzGt8zg7Ny8djbYMhxl2zuEevVa7r2gJjYY5Lwr1xM7+XU2nd6CkIWFTVcCIbAP63vSz71NaVyyuSk9lHKcy0A==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.12.1.tgz", + "integrity": "sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==", "dev": true, "engines": { "node": ">=4" @@ -2422,9 +3253,9 @@ "dev": true }, "node_modules/baseline-browser-mapping": { - "version": "2.11.12", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.12.tgz", - "integrity": "sha512-r7WnVImvVCeFpf2DOXfy41aPWzeNg3H/A2X4dKmy1QL0MSyyk/e7z8ihJ3N6Nn2PsdhkVlqnEfnUE4a05P2aTA==", + "version": "2.10.43", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz", + "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==", "bin": { "baseline-browser-mapping": "dist/cli.cjs" }, @@ -2432,10 +3263,47 @@ "node": ">=6.0.0" } }, + "node_modules/body-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^2.0.0", + "debug": "^4.4.3", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", + "on-finished": "^2.4.1", + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", @@ -2446,7 +3314,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -2455,10 +3323,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", - "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", - "dev": true, + "version": "4.28.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz", + "integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==", "funding": [ { "type": "opencollective", @@ -2474,9 +3341,9 @@ } ], "dependencies": { - "baseline-browser-mapping": "^2.10.44", - "caniuse-lite": "^1.0.30001806", - "electron-to-chromium": "^1.5.393", + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001803", + "electron-to-chromium": "^1.5.389", "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, @@ -2487,6 +3354,30 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/call-bind": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", @@ -2509,7 +3400,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -2522,7 +3412,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" @@ -2538,15 +3427,14 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001807", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001807.tgz", - "integrity": "sha512-daRXJ9EB/rdRgu7kV+TTl1YUKtlsMWblPl2sLnpg9DZae16QCegol6A1SmCE31Lm9mXC1sRWGt/krouH+/dl7Q==", + "version": "1.0.30001805", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001805.tgz", + "integrity": "sha512-52noaS3DubycKSXaU30TwPGIp+POyQSUVa5jBEq3vkRkY0kjyb3LQgvhU6WGyCcyXqVLWO0Cw0Q6BSdD0kUfVA==", "funding": [ { "type": "opencollective", @@ -2578,11 +3466,65 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "license": "MIT" + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2601,23 +3543,194 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/conf": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", + "license": "MIT", + "dependencies": { + "ajv": "^8.6.3", + "ajv-formats": "^2.1.1", + "atomically": "^1.7.0", + "debounce-fn": "^4.0.0", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "json-schema-typed": "^7.0.3", + "onetime": "^5.1.2", + "pkg-up": "^3.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conf/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/conf/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/conf/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/conf/node_modules/json-schema-typed": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==", + "license": "BSD-2-Clause" + }, + "node_modules/conf/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz", + "integrity": "sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==", + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2627,11 +3740,23 @@ "node": ">= 8" } }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true + "devOptional": true }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -2679,22 +3804,36 @@ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debounce-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "dependencies": { "ms": "^2.1.3" }, @@ -2707,12 +3846,63 @@ } } }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -2730,6 +3920,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-properties": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", @@ -2747,6 +3949,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -2756,6 +3967,15 @@ "node": ">=8" } }, + "node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -2768,11 +3988,37 @@ "node": ">=0.10.0" } }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -2782,11 +4028,16 @@ "node": ">= 0.4" } }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, "node_modules/electron-to-chromium": { - "version": "1.5.402", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.402.tgz", - "integrity": "sha512-/oOpMaPT6Yg+6/1XQhyIPlzgj7Ye9zf+nNM2Uh6OcE2G2oNptWazFa+qB2Pdqqbsc9KnIDzgAntoYN0dbwOXwA==", - "dev": true + "version": "1.5.392", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.392.tgz", + "integrity": "sha512-1yQq3VQCZRwsnYc67Oc+1fge6Lwtn0hzi6zmEVkB61Zx21kTbwJAW4dFLadl5Rc1tKhG/kSpYXnfiAhu0f0a1g==" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -2794,10 +4045,19 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/enhanced-resolve": { - "version": "5.24.5", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", - "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", + "version": "5.21.6", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz", + "integrity": "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -2807,6 +4067,37 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-abstract": { "version": "1.24.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", @@ -2897,7 +4188,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -2906,7 +4196,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -2942,7 +4231,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", - "dev": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -3001,11 +4289,16 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, "engines": { "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3078,12 +4371,13 @@ } }, "node_modules/eslint-config-next": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.3.0.tgz", - "integrity": "sha512-lPrf1kHsMJEZqO0uXkNB400c5MGrhrTk3BNX7P0ol4gt61+iUlQfjy9TyIOEA9eOXrf+5+mYbT/JsY8+zqUByQ==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.10.tgz", + "integrity": "sha512-HSybLOY0QKf39i4FWUqPN0xWiNDi6A6UqJmZtgDkS3zMqjXTqULvj/sueXx3cdCG0mVG+qH6k5/qdegklH1d1w==", "dev": true, + "license": "MIT", "dependencies": { - "@next/eslint-plugin-next": "16.3.0", + "@next/eslint-plugin-next": "16.2.10", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", @@ -3200,6 +4494,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -3362,6 +4657,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", @@ -3404,17 +4712,135 @@ "node": ">=0.10.0" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz", + "integrity": "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.6.2.tgz", + "integrity": "sha512-YH4ru+eOJxQABscKFfRCy9R7x9QFGdezclVMwwgFFndzS2Xnm0uo6B0ABZsLhcpeptGv2qvuJVWlQr9gQZoC3A==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "ip-address": "^10.2.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3431,6 +4857,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -3450,15 +4877,46 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", + "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastq": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -3475,7 +4933,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3483,6 +4941,27 @@ "node": ">=8" } }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3513,9 +4992,9 @@ } }, "node_modules/flatted": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", - "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true }, "node_modules/for-each": { @@ -3533,11 +5012,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-extra": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", + "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3574,6 +5084,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/fuzzysort": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-3.1.0.tgz", + "integrity": "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==", + "license": "MIT" + }, "node_modules/generator-function": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", @@ -3587,16 +5103,26 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, "engines": { "node": ">=6.9.0" } }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -3616,11 +5142,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-own-enumerable-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-own-enumerable-keys/-/get-own-enumerable-keys-1.0.0.tgz", + "integrity": "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -3629,6 +5166,22 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", @@ -3647,9 +5200,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.1.tgz", - "integrity": "sha512-Dz/6HxkrxgNehhxLVeyv8sad9UzF2xBVeaKBQNDfJ5XiSXmp2gTR0eO0RWiT2NCKS5aGP9jjkOMggTN90qU50A==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -3702,7 +5255,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -3713,8 +5265,7 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/has-bigints": { "version": "1.1.0", @@ -3768,7 +5319,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -3795,7 +5345,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -3818,11 +5367,64 @@ "hermes-estree": "0.25.1" } }, + "node_modules/hono": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.0.tgz", + "integrity": "sha512-jhunvfHWxd7J5EFfSgH4xsYJzSe/lfqbUCxiyyeaQasUsXeEHXtzVid+7EOGByc5JnFa23SSFL3Y2RV/z1T+eQ==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, "engines": { "node": ">= 4" } @@ -3831,7 +5433,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3852,6 +5453,12 @@ "node": ">=0.8.19" } }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -3863,7 +5470,25 @@ "side-channel": "^1.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.4" + } + }, + "node_modules/ip-address": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.4.0.tgz", + "integrity": "sha512-oSK96Grm3aP6OrS263xVxbNDGVL7rzBtYdpGqlDG8iQdoenDoTs/nkki+DflYbAEE8Xl6o5YxhxlrKvI3nqKXQ==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" } }, "node_modules/is-array-buffer": { @@ -3883,6 +5508,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, "node_modules/is-async-function": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", @@ -4014,6 +5645,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-document.all": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", @@ -4033,7 +5679,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4076,7 +5721,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -4084,6 +5728,48 @@ "node": ">=0.10.0" } }, + "node_modules/is-in-ssh": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz", + "integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container": { + "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==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -4112,7 +5798,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -4133,6 +5819,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -4151,6 +5864,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-regexp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", + "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-set": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", @@ -4178,6 +5903,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", @@ -4226,6 +5963,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakmap": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", @@ -4269,6 +6018,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", @@ -4278,8 +6042,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/iterator.prototype": { "version": "1.1.5", @@ -4307,17 +6070,24 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/jose": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.8.tgz", + "integrity": "sha512-Bsdjwm3Qsd/P0jR+BHDe3LytDfY7WBq2HmCCLIwuVRHMuEC9ae7/R474GIUdF1NgCyZjzVo/A9DOiOBtXq8ZoQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", - "dev": true, + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "funding": [ { "type": "github", @@ -4339,7 +6109,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -4353,12 +6122,24 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -4369,7 +6150,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -4377,6 +6157,18 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -4401,6 +6193,15 @@ "json-buffer": "3.0.1" } }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -4681,6 +6482,12 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4702,6 +6509,46 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4718,11 +6565,19 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "dependencies": { "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.29.0.tgz", + "integrity": "sha512-Xs9QFG5+9sNX04MdKVT4++umA+hJ2qsJVlRlRWHQ7qZobXgMiNHSpZ5eZm8JUoGCdNyoEdXoEwa8HVr0DNjOQg==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -4736,16 +6591,46 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "engines": { "node": ">= 0.4" } }, + "node_modules/media-typer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", + "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -4754,7 +6639,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -4763,6 +6648,52 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", @@ -4779,7 +6710,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4787,13 +6717,12 @@ "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/nanoid": { - "version": "3.3.17", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.17.tgz", - "integrity": "sha512-xQLf0A3HOMlgHq0n247/LRuAOYmB7dXJ/DvAxGvsSBij45XtBSmQycu+F8ODbHwns/XyFZagyL1+J0Offw1E0g==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -4828,16 +6757,26 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/next": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/next/-/next-16.3.0.tgz", - "integrity": "sha512-NEdGOzH+08eTXMUp9UYkA99Nhi5N6Thrhc1jgFOQgfgnGK/dA2hRwBpXep+exdFQrnwlRf/3Wixyp8lLBUpE2A==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/next/-/next-16.2.10.tgz", + "integrity": "sha512-2som5AVXb3kE6Yjine3/mNbBayYF58eguBWIVVUdr1y/L426xyVEgYxgBG+1QC34P2x5E+tcDup6XkuOAX3dCA==", + "license": "MIT", "dependencies": { - "@next/env": "16.3.0", + "@next/env": "16.2.10", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", - "postcss": "8.5.23", + "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "bin": { @@ -4847,15 +6786,15 @@ "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "16.3.0", - "@next/swc-darwin-x64": "16.3.0", - "@next/swc-linux-arm64-gnu": "16.3.0", - "@next/swc-linux-arm64-musl": "16.3.0", - "@next/swc-linux-x64-gnu": "16.3.0", - "@next/swc-linux-x64-musl": "16.3.0", - "@next/swc-win32-arm64-msvc": "16.3.0", - "@next/swc-win32-x64-msvc": "16.3.0", - "sharp": "^0.35.3" + "@next/swc-darwin-arm64": "16.2.10", + "@next/swc-darwin-x64": "16.2.10", + "@next/swc-linux-arm64-gnu": "16.2.10", + "@next/swc-linux-arm64-musl": "16.2.10", + "@next/swc-linux-x64-gnu": "16.2.10", + "@next/swc-linux-x64-musl": "16.2.10", + "@next/swc-win32-arm64-msvc": "16.2.10", + "@next/swc-win32-x64-msvc": "16.2.10", + "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -4881,9 +6820,9 @@ } }, "node_modules/next/node_modules/postcss": { - "version": "8.5.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", - "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -4898,10 +6837,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.16", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" }, "engines": { "node": "^10 || ^12 || >=14" @@ -4926,19 +6866,45 @@ } }, "node_modules/node-releases": { - "version": "2.0.53", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", - "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", - "dev": true, + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4947,7 +6913,6 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -4964,6 +6929,15 @@ "node": ">= 0.4" } }, + "node_modules/object-treeify": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/object.assign": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", @@ -5043,10 +7017,75 @@ "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/open": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/open/-/open-11.0.0.tgz", + "integrity": "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.4.0", + "define-lazy-prop": "^3.0.0", + "is-in-ssh": "^1.0.0", + "is-inside-container": "^1.0.0", + "powershell-utils": "^0.1.0", + "wsl-utils": "^0.3.0" + }, + "engines": { + "node": ">=20" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { @@ -5066,14 +7105,75 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/own-keys": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.2.tgz", - "integrity": "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "dev": true, "dependencies": { - "call-bound": "^1.0.4", - "get-intrinsic": "^1.3.0", + "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" }, @@ -5114,11 +7214,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -5126,6 +7234,51 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5139,7 +7292,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -5150,6 +7302,16 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -5159,7 +7321,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -5167,6 +7329,88 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -5177,10 +7421,9 @@ } }, "node_modules/postcss": { - "version": "8.5.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", - "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", - "dev": true, + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "funding": [ { "type": "opencollective", @@ -5195,8 +7438,9 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.17", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -5204,6 +7448,31 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/powershell-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz", + "integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5213,6 +7482,43 @@ "node": ">= 0.8.0" } }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -5224,6 +7530,19 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5233,11 +7552,26 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "license": "BSD-3-Clause", + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -5251,25 +7585,56 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } }, "node_modules/react": { - "version": "19.2.8", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", - "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.8", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", - "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.8" + "react": "^19.2.4" } }, "node_modules/react-is": { @@ -5278,6 +7643,22 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, + "node_modules/recast": { + "version": "0.23.19", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.19.tgz", + "integrity": "sha512-T98lym7kH+pnZmRaD8yDRdaNqyUbwnbEBx0MuchrzMFOEMray4AO3ZJoTUZ5r78Ao78X/OhzW0DL8GB85w/I2w==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -5320,6 +7701,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reselect": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.2.0.tgz", + "integrity": "sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==", + "license": "MIT" + }, "node_modules/resolve": { "version": "2.0.0-next.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", @@ -5347,7 +7743,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -5361,21 +7756,79 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -5390,6 +7843,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -5446,18 +7900,68 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==" }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/set-function-length": { @@ -5506,59 +8010,159 @@ "node": ">= 0.4" } }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shadcn": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/shadcn/-/shadcn-4.16.2.tgz", + "integrity": "sha512-M1AvZKFWcCzWRDoyApIqJMSLIpY8Ev4uBGuiPLSFmiTbixXhPmzotSTvLzFmBrfoIxG9aIg2dZOETblEaXGUnQ==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/plugin-transform-typescript": "^7.28.0", + "@babel/preset-typescript": "^7.27.1", + "@dotenvx/dotenvx": "^1.48.4", + "@modelcontextprotocol/sdk": "^1.26.0", + "@types/validate-npm-package-name": "^4.0.2", + "browserslist": "^4.26.2", + "commander": "^14.0.0", + "cosmiconfig": "^9.0.0", + "dedent": "^1.6.0", + "deepmerge": "^4.3.1", + "diff": "^8.0.2", + "execa": "^9.6.0", + "fast-glob": "^3.3.3", + "fs-extra": "^11.3.1", + "fuzzysort": "^3.1.0", + "kleur": "^4.1.5", + "open": "^11.0.0", + "ora": "^8.2.0", + "postcss": "^8.5.6", + "postcss-selector-parser": "^7.1.0", + "prompts": "^2.4.2", + "recast": "^0.23.11", + "stringify-object": "^5.0.0", + "tailwind-merge": "^3.0.1", + "ts-morph": "^26.0.0", + "tsconfig-paths": "^4.2.0", + "undici": "^7.27.2", + "validate-npm-package-name": "^7.0.1", + "zod": "^3.24.1", + "zod-to-json-schema": "^3.24.6" + }, + "bin": { + "shadcn": "dist/index.js" + }, + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/shadcn/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/shadcn/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/shadcn/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/shadcn/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/sharp": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz", - "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", "optional": true, "dependencies": { - "@img/colour": "^1.1.0", + "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", - "semver": "^7.8.5" + "semver": "^7.7.3" }, "engines": { - "node": ">=20.9.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.35.3", - "@img/sharp-darwin-x64": "0.35.3", - "@img/sharp-freebsd-wasm32": "0.35.3", - "@img/sharp-libvips-darwin-arm64": "1.3.2", - "@img/sharp-libvips-darwin-x64": "1.3.2", - "@img/sharp-libvips-linux-arm": "1.3.2", - "@img/sharp-libvips-linux-arm64": "1.3.2", - "@img/sharp-libvips-linux-ppc64": "1.3.2", - "@img/sharp-libvips-linux-riscv64": "1.3.2", - "@img/sharp-libvips-linux-s390x": "1.3.2", - "@img/sharp-libvips-linux-x64": "1.3.2", - "@img/sharp-libvips-linuxmusl-arm64": "1.3.2", - "@img/sharp-libvips-linuxmusl-x64": "1.3.2", - "@img/sharp-linux-arm": "0.35.3", - "@img/sharp-linux-arm64": "0.35.3", - "@img/sharp-linux-ppc64": "0.35.3", - "@img/sharp-linux-riscv64": "0.35.3", - "@img/sharp-linux-s390x": "0.35.3", - "@img/sharp-linux-x64": "0.35.3", - "@img/sharp-linuxmusl-arm64": "0.35.3", - "@img/sharp-linuxmusl-x64": "0.35.3", - "@img/sharp-webcontainers-wasm32": "0.35.3", - "@img/sharp-win32-arm64": "0.35.3", - "@img/sharp-win32-ia32": "0.35.3", - "@img/sharp-win32-x64": "0.35.3" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" } }, "node_modules/sharp/node_modules/semver": { "version": "7.8.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", "optional": true, "bin": { "semver": "bin/semver.js" @@ -5571,7 +8175,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5583,7 +8186,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -5592,7 +8194,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", @@ -5611,7 +8212,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" @@ -5627,7 +8227,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -5645,7 +8244,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -5660,6 +8258,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -5674,6 +8299,27 @@ "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", "dev": true }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -5687,6 +8333,56 @@ "node": ">= 0.4" } }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/string.prototype.includes": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", @@ -5795,15 +8491,67 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-5.0.0.tgz", + "integrity": "sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-keys": "^1.0.0", + "is-obj": "^3.0.0", + "is-regexp": "^3.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/stringify-object?sponsor=1" + } + }, + "node_modules/stringify-object/node_modules/is-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-3.0.0.tgz", + "integrity": "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, "engines": { "node": ">=4" } }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -5862,10 +8610,46 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/systeminformation": { + "version": "5.33.1", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.33.1.tgz", + "integrity": "sha512-DEN6ICHk3Tk0Uf/hrAHh7xlt7iL5CJFBtPZinA0H62DrGG/KPKqq/Nzj6lCXPS4Ay/sf/14zNnk9LpqKzBIc+w==", + "license": "MIT", + "os": [ + "darwin", + "linux", + "win32", + "freebsd", + "openbsd", + "netbsd", + "sunos", + "android" + ], + "bin": { + "systeminformation": "lib/cli.js" + }, + "engines": { + "node": ">=10.0.0" + }, + "funding": { + "type": "Buy me a coffee", + "url": "https://www.buymeacoffee.com/systeminfo" + } + }, + "node_modules/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", - "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.2.tgz", + "integrity": "sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA==", "dev": true }, "node_modules/tapable": { @@ -5881,6 +8665,12 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", @@ -5930,7 +8720,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -5938,6 +8728,15 @@ "node": ">=8.0" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -5950,6 +8749,16 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-morph": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-26.0.0.tgz", + "integrity": "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==", + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.27.0", + "code-block-writer": "^13.0.3" + } + }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -5979,6 +8788,15 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -5991,6 +8809,37 @@ "node": ">= 0.8.0" } }, + "node_modules/type-is": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "license": "MIT", + "dependencies": { + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", @@ -6069,7 +8918,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6079,15 +8928,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.66.0.tgz", - "integrity": "sha512-QlEbBPz/RuJ1XUHj29nm3t0F/O/cSlEnntozqPOYHnnTGAXFamnMBu5i9Vn6vhUPHGAjR+Vl+5J8vPN/BMUrJw==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.64.0.tgz", + "integrity": "sha512-0qg+pDNMnqYzqH9AnNK+39tejHvsShUOUUoRUgtnTGE7QuMZhiFDnozq8nHJVq+Wae6NMLKNWLg5WmkcC/ndyQ==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.66.0", - "@typescript-eslint/parser": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0", - "@typescript-eslint/utils": "8.66.0" + "@typescript-eslint/eslint-plugin": "8.64.0", + "@typescript-eslint/parser": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/utils": "8.64.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6119,12 +8968,51 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz", + "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/unrs-resolver": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", @@ -6166,7 +9054,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, "funding": [ { "type": "opencollective", @@ -6201,11 +9088,43 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/validate-npm-package-name": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz", + "integrity": "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==", + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -6310,11 +9229,32 @@ "node": ">=0.10.0" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/wsl-utils": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.3.1.tgz", + "integrity": "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0", + "powershell-utils": "^0.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yocto-queue": { "version": "0.1.0", @@ -6328,15 +9268,50 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yocto-spinner": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-1.2.2.tgz", + "integrity": "sha512-DODGl1wJjA/s5pnJFKau9lIYHT81lnhob1i3e1TjxZRxEhWRKl74nTbWE6H5KlkViQQTo/Z29YFdxzTZAMY3ng==", + "license": "MIT", + "dependencies": { + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18.19" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz", + "integrity": "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zod": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } + }, "node_modules/zod-validation-error": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", diff --git a/my-app/package.json b/my-app/package.json index 6c1cde0..b14637e 100644 --- a/my-app/package.json +++ b/my-app/package.json @@ -9,18 +9,25 @@ "lint": "eslint" }, "dependencies": { - "next": "16.3.0", - "react": "19.2.8", - "react-dom": "19.2.8" + "@base-ui/react": "^1.6.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^1.26.0", + "next": "16.2.10", + "react": "19.2.4", + "react-dom": "19.2.4", + "shadcn": "^4.14.0", + "tailwind-merge": "^3.6.0", + "tw-animate-css": "^1.4.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", "@types/node": "^20", - "@types/react": "^19", + "@types/react": "^19.2.17", "@types/react-dom": "^19", "babel-plugin-react-compiler": "1.0.0", "eslint": "^9", - "eslint-config-next": "16.3.0", + "eslint-config-next": "16.2.10", "tailwindcss": "^4", "typescript": "^5" } diff --git a/my-app/public/assets/images/login/WEG-login-page.jpg b/my-app/public/assets/images/login/WEG-login-page.jpg new file mode 100644 index 0000000..7f4bb61 Binary files /dev/null and b/my-app/public/assets/images/login/WEG-login-page.jpg differ diff --git a/my-app/public/assets/images/logo/LogoETitulo (1).svg b/my-app/public/assets/images/logo/LogoETitulo (1).svg new file mode 100644 index 0000000..885147d --- /dev/null +++ b/my-app/public/assets/images/logo/LogoETitulo (1).svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/my-app/public/assets/images/logo/logo-title-blue.svg b/my-app/public/assets/images/logo/logo-title-blue.svg new file mode 100644 index 0000000..402f499 --- /dev/null +++ b/my-app/public/assets/images/logo/logo-title-blue.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/my-app/public/assets/images/logo/logo-title-sapphire.svg b/my-app/public/assets/images/logo/logo-title-sapphire.svg new file mode 100644 index 0000000..b00ea34 --- /dev/null +++ b/my-app/public/assets/images/logo/logo-title-sapphire.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/my-app/public/assets/images/logo/logo-title-white.svg b/my-app/public/assets/images/logo/logo-title-white.svg new file mode 100644 index 0000000..885147d --- /dev/null +++ b/my-app/public/assets/images/logo/logo-title-white.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/my-app/public/assets/images/logo/logo-weg.png b/my-app/public/assets/images/logo/logo-weg.png new file mode 100644 index 0000000..9618de4 Binary files /dev/null and b/my-app/public/assets/images/logo/logo-weg.png differ diff --git a/my-app/public/assets/images/logo/logo-weg.svg b/my-app/public/assets/images/logo/logo-weg.svg new file mode 100644 index 0000000..5a5bc4d --- /dev/null +++ b/my-app/public/assets/images/logo/logo-weg.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/my-app/public/file.svg b/my-app/public/file.svg deleted file mode 100644 index 004145c..0000000 --- a/my-app/public/file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/my-app/public/globe.svg b/my-app/public/globe.svg deleted file mode 100644 index 567f17b..0000000 --- a/my-app/public/globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/my-app/public/next.svg b/my-app/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/my-app/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/my-app/public/vercel.svg b/my-app/public/vercel.svg deleted file mode 100644 index 7705396..0000000 --- a/my-app/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/my-app/public/window.svg b/my-app/public/window.svg deleted file mode 100644 index b2b2a44..0000000 --- a/my-app/public/window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/my-app/src/app/admin/classes/page.tsx b/my-app/src/app/admin/classes/page.tsx new file mode 100644 index 0000000..8c93260 --- /dev/null +++ b/my-app/src/app/admin/classes/page.tsx @@ -0,0 +1,170 @@ +"use client"; + +import { useEffect, useState } from 'react'; + +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Button, buttonVariants } from "@/components/ui/button"; +import { mockClasses } from "@/lib/mock-data"; +import type { ClassDTO } from "@/types"; +import { Plus, GraduationCap, Edit } from "lucide-react"; +import Link from "next/link"; +import { cn } from "@/lib/utils"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { getClasses, updateClass } from '@/lib/application-api'; + +export default function TurmasPage() { + const [classes, setClasses] = useState(mockClasses); + const [editing, setEditing] = useState(null); + const [formName, setFormName] = useState(''); + const [formPeriod, setFormPeriod] = useState(''); + const [error, setError] = useState(''); + const [saving, setSaving] = useState(false); + + useEffect(() => { + getClasses().then(setClasses).catch((loadError) => { + setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar as turmas.'); + }); + }, []); + + const openEdit = (item: ClassDTO) => { + setEditing(item); + setFormName(item.name); + setFormPeriod(item.period); + }; + + const handleSave = async () => { + if (!editing || !formName.trim() || !formPeriod.trim()) return; + setSaving(true); + try { + const saved = await updateClass({ ...editing, name: formName.trim(), period: formPeriod.trim() }); + setClasses((current) => current.map((item) => item.id === saved.id ? saved : item)); + setEditing(null); + setError(''); + } catch (saveError) { + setError(saveError instanceof Error ? saveError.message : 'Não foi possível atualizar a turma.'); + } finally { + setSaving(false); + } + }; + const columns: DataTableColumn[] = [ + { + key: "name", + header: "Turma", + sortable: true, + render: (cls) => ( +
+
+ +
+
+

{cls.name}

+

Código: {cls.code}

+
+
+ ), + }, + { + key: "courseName", + header: "Curso Vinculado", + render: (cls) => ( + {cls.courseName} + ), + }, + { + key: "period", + header: "Período", + render: (cls) => ( + {cls.period} + ), + }, + { + key: "occupancy", + header: "Ocupação", + render: (cls) => ( + + {cls.totalStudents} / {cls.maxStudents} alunos + + ), + }, + { + key: "status", + header: "Status", + render: (cls) => { + if (cls.status === "IN_PROGRESS") return Em Andamento; + if (cls.status === "PLANNED") return Planejada; + return Finalizada; + }, + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: (item) => ( + + ), + }, + ]; + + return ( + +
+ + Nova Turma + + } + /> + + {error && ( +
{error}
+ )} + row.id} + /> +
+ !open && setEditing(null)}> + + Editar turma +
+ + +
+ + + + +
+
+
+ ); +} diff --git a/my-app/src/app/admin/courses/page.tsx b/my-app/src/app/admin/courses/page.tsx new file mode 100644 index 0000000..0571997 --- /dev/null +++ b/my-app/src/app/admin/courses/page.tsx @@ -0,0 +1,376 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogDescription, +} from "@/components/ui/dialog"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { ToastCard } from "@/components/ui/toast-card"; +import { mockCourses } from "@/lib/mock-data"; +import type { CourseDTO } from "@/types"; +import { Edit, Plus, Trash2 } from "lucide-react"; +import { createCourse, deleteCourse, getCourses, updateCourse } from '@/lib/application-api'; + +export default function CursosAdminPage() { + const [courses, setCourses] = useState(mockCourses); + const [filterTab, setFilterTab] = useState("ALL"); + const [editingCourse, setEditingCourse] = useState(null); + const [isEditOpen, setIsEditOpen] = useState(false); + const [isDeleteOpen, setIsDeleteOpen] = useState(false); + const [deletingCourse, setDeletingCourse] = useState(null); + const [successMsg, setSuccessMsg] = useState(""); + const [toastVariant, setToastVariant] = useState<"success" | "destructive">("success"); + const [error, setError] = useState(""); + const [saving, setSaving] = useState(false); + + useEffect(() => { + getCourses().then(setCourses).catch((loadError) => { + setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar os cursos.'); + }); + }, []); + + // Form state + const [formName, setFormName] = useState(""); + const [formCode, setFormCode] = useState(""); + const [formCoordinator, setFormCoordinator] = useState(""); + const [formStatus, setFormStatus] = useState<"ACTIVE" | "COMPLETED">("ACTIVE"); + + const filteredCourses = courses.filter((course) => { + if (filterTab === "ACTIVE") return course.status === "ACTIVE"; + if (filterTab === "COMPLETED") return course.status === "COMPLETED"; + return true; + }); + + const openEdit = (course: CourseDTO) => { + setEditingCourse(course); + setFormName(course.name); + setFormCode(course.code); + setFormCoordinator(course.coordinatorName); + setFormStatus(course.status === "COMPLETED" ? "COMPLETED" : "ACTIVE"); + setIsEditOpen(true); + }; + + const openDelete = (course: CourseDTO) => { + setDeletingCourse(course); + setIsDeleteOpen(true); + }; + + const handleSaveEdit = async () => { + if (!editingCourse) return; + const updated = { + ...editingCourse, + name: formName.trim(), code: formCode.trim(), + coordinatorName: formCoordinator.trim(), status: formStatus, + }; + setSaving(true); + setError(''); + try { + const saved = await updateCourse(updated); + setCourses((prev) => prev.map((course) => course.id === saved.id ? saved : course)); + setIsEditOpen(false); + setToastVariant("success"); + setSuccessMsg('Curso atualizado com sucesso!'); + setTimeout(() => setSuccessMsg(""), 7000); + } catch (saveError) { + setError(saveError instanceof Error ? saveError.message : 'Não foi possível atualizar o curso.'); + } finally { + setSaving(false); + } + }; + + const handleCreate = async () => { + if (!formName.trim() || !formCode.trim()) return; + const input: Omit = { + name: formName.trim(), + code: formCode.trim(), + coordinatorName: formCoordinator.trim(), + totalStudents: 0, + status: formStatus, + }; + setSaving(true); + setError(''); + try { + const created = await createCourse(input); + setCourses((prev) => [...prev, created]); + setFormName(""); + setFormCode(""); + setFormCoordinator(""); + setFormStatus("ACTIVE"); + setToastVariant("success"); + setSuccessMsg('Curso criado com sucesso!'); + setTimeout(() => setSuccessMsg(""), 7000); + } catch (saveError) { + setError(saveError instanceof Error ? saveError.message : 'Não foi possível criar o curso.'); + } finally { + setSaving(false); + } + }; + + const handleConfirmDelete = async () => { + if (!deletingCourse) return; + setSaving(true); + setError(''); + try { + await deleteCourse(deletingCourse.id); + setCourses((prev) => prev.filter((c) => c.id !== deletingCourse.id)); + setIsDeleteOpen(false); + setToastVariant("destructive"); + setSuccessMsg(`Curso "${deletingCourse.name}" excluído com sucesso.`); + setTimeout(() => setSuccessMsg(""), 7000); + } catch (deleteError) { + setError(deleteError instanceof Error ? deleteError.message : 'Não foi possível excluir o curso.'); + } finally { + setSaving(false); + } + }; + + const columns: DataTableColumn[] = [ + { + key: "name", + header: "Curso Técnico", + sortable: true, + render: (course) => ( +
+
+

{course.name}

+

Código: {course.code}

+
+
+ ), + }, + { + key: "coordinatorName", + header: "Coordenador Responsável", + render: (course) => ( + {course.coordinatorName} + ), + }, + { + key: "totalStudents", + header: "Total Alunos", + sortable: true, + render: (course) => ( + {course.totalStudents} alunos + ), + }, + { + key: "status", + header: "Status", + render: (course) => { + if (course.status === "ACTIVE") return Em Andamento; + if (course.status === "COMPLETED") return Concluído; + return Planejado; + }, + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: (course) => ( +
+ + +
+ ), + }, + ]; + + return ( + +
+ + + {error && ( +
{error}
+ )} + +
+ {/* Lado Esquerdo - Lista de Cursos */} +
+ + + Todos os Cursos + Em Andamento + Concluídos + + + + row.id} + /> +
+ + {/* Lado Direito - Formulário de Novo Curso */} +
+
+

Novo Curso

+

Preencha para cadastrar um novo curso.

+
+ +
{ + e.preventDefault(); + void handleCreate(); + }} + className="space-y-4" + > +
+ + setFormName(e.target.value)} + placeholder="Ex: Técnico em Mecatrônica" + className="h-10 border-slate-200 text-sm" + /> +
+ +
+
+ + setFormCode(e.target.value)} + placeholder="MEC-2024" + className="h-10 border-slate-200 text-sm" + /> +
+
+ + +
+
+ +
+ + setFormCoordinator(e.target.value)} + placeholder="Nome do coordenador" + className="h-10 border-slate-200 text-sm" + /> +
+ + +
+
+
+
+ + {/* Modal de Edição */} + + + + Editar Curso + Altere as informações do curso. + +
+
+ + setFormName(e.target.value)} className="h-10 border-slate-200" /> +
+
+
+ + setFormCode(e.target.value)} className="h-10 border-slate-200" /> +
+
+ + +
+
+
+ + setFormCoordinator(e.target.value)} className="h-10 border-slate-200" /> +
+
+ + + + +
+
+ + {/* Modal de Exclusão */} + + + + Confirmar Exclusão + + Deseja realmente excluir o curso {deletingCourse?.name}? Esta ação não pode ser desfeita. + + + + + + + + + + +
+ ); +} + diff --git a/my-app/src/app/admin/interviews/page.tsx b/my-app/src/app/admin/interviews/page.tsx new file mode 100644 index 0000000..6129654 --- /dev/null +++ b/my-app/src/app/admin/interviews/page.tsx @@ -0,0 +1,102 @@ +"use client"; + +import { useEffect, useState } from 'react'; + +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { mockInterviews } from "@/lib/mock-data"; +import type { InterviewDTO } from "@/types"; +import { Calendar, Clock } from "lucide-react"; +import { getAdminInterviews } from '@/lib/application-api'; + +export default function EntrevistasPage() { + const [interviews, setInterviews] = useState(mockInterviews); + const [error, setError] = useState(''); + + useEffect(() => { + getAdminInterviews().then(setInterviews).catch((loadError) => { + setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar as entrevistas.'); + }); + }, []); + + const columns: DataTableColumn[] = [ + { + key: "candidateName", + header: "Candidato", + sortable: true, + render: (int) => ( +
+

{int.candidateName}

+

{int.candidateEmail}

+
+ ), + }, + { + key: "vacancyTitle", + header: "Vaga Pretendida", + render: (int) => ( + {int.vacancyTitle} + ), + }, + { + key: "scheduledDate", + header: "Data / Horário", + sortable: true, + render: (int) => ( +
+ + {int.scheduledDate} + + + {int.scheduledTime} + +
+ ), + }, + { + key: "interviewerName", + header: "Entrevistador", + render: (int) => ( + {int.interviewerName} + ), + }, + { + key: "status", + header: "Status", + render: (int) => { + if (int.status === "APPROVED") return Aprovado; + if (int.status === "REJECTED") return Reprovado; + if (int.status === "SCHEDULED") return Agendada; + return Pendente; + }, + }, + ]; + + return ( + +
+ + + {error &&
{error}
} + row.id} + /> +
+
+ ); +} diff --git a/my-app/src/app/admin/locations/page.tsx b/my-app/src/app/admin/locations/page.tsx new file mode 100644 index 0000000..ce81df9 --- /dev/null +++ b/my-app/src/app/admin/locations/page.tsx @@ -0,0 +1,425 @@ +"use client"; + +import { FormEvent, useCallback, useEffect, useState } from "react"; +import { Edit, MapPin, Plus, RefreshCw, Trash2 } from "lucide-react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + createPlace, + deletePlace, + getPlaces, + updatePlace, + type Place, + type PlaceInput, +} from "@/lib/manager-api"; + +const initialForm: PlaceInput = { + placeName: "", + park: "WEG_I", + section: "IT", +}; + +export default function AdminLocationsPage() { + const [places, setPlaces] = useState([]); + const [loading, setLoading] = useState(true); + const [dialogOpen, setDialogOpen] = useState(false); + const [editingPlace, setEditingPlace] = useState(null); + const [form, setForm] = useState(initialForm); + const [saving, setSaving] = useState(false); + const [deletingId, setDeletingId] = useState(null); + const [error, setError] = useState(""); + const [notice, setNotice] = useState(""); + + const loadPlaces = useCallback(async () => { + setLoading(true); + setError(""); + try { + setPlaces(await getPlaces()); + } catch (requestError) { + setError( + requestError instanceof Error + ? requestError.message + : "Não foi possível carregar os locais." + ); + } finally { + setLoading(false); + } + }, []); + + useEffect(() => { + let active = true; + getPlaces() + .then((data) => active && setPlaces(data)) + .catch((requestError) => { + if (active) { + setError( + requestError instanceof Error + ? requestError.message + : "Não foi possível carregar os locais." + ); + } + }) + .finally(() => active && setLoading(false)); + return () => { + active = false; + }; + }, []); + + const openEditDialog = (place: Place) => { + setEditingPlace(place); + setForm({ + placeName: place.placeName, + park: place.park === "WEG_II" ? "WEG_II" : "WEG_I", + section: place.section, + }); + setError(""); + setDialogOpen(true); + }; + + const closeEditDialog = () => { + setDialogOpen(false); + setEditingPlace(null); + setForm(initialForm); + setError(""); + }; + + const handleSubmit = async (event: FormEvent) => { + event.preventDefault(); + setError(""); + setNotice(""); + + if (!form.placeName.trim() || !form.section.trim()) { + setError("Informe o nome e a seção do local."); + return; + } + + const payload: PlaceInput = { + ...form, + placeName: form.placeName.trim(), + section: form.section.trim(), + }; + + setSaving(true); + try { + // Mantém a lista em sincronia com a API, sem depender de dados mockados. + if (editingPlace) { + const updated = await updatePlace(editingPlace.id, payload); + setPlaces((current) => + current.map((place) => (place.id === updated.id ? updated : place)) + ); + setNotice(`Local “${updated.placeName}” atualizado.`); + setDialogOpen(false); + setEditingPlace(null); + setForm(initialForm); + } else { + const created = await createPlace(payload); + setPlaces((current) => [...current, created]); + setNotice( + `Local “${created.placeName}” criado. Ele já está disponível para novas vagas.` + ); + setForm(initialForm); + } + } catch (requestError) { + setError( + requestError instanceof Error + ? requestError.message + : "Não foi possível salvar o local." + ); + } finally { + setSaving(false); + } + }; + + const handleDelete = async (place: Place) => { + if ( + !window.confirm( + `Excluir o local “${place.placeName}”? Locais associados a vagas podem não ser removidos.` + ) + ) { + return; + } + + setDeletingId(place.id); + setError(""); + setNotice(""); + try { + await deletePlace(place.id); + setPlaces((current) => current.filter((item) => item.id !== place.id)); + setNotice("Local excluído com sucesso."); + } catch (requestError) { + setError( + requestError instanceof Error + ? requestError.message + : "Não foi possível excluir o local." + ); + } finally { + setDeletingId(null); + } + }; + + const columns: DataTableColumn[] = [ + { + key: "placeName", + header: "Local", + sortable: true, + render: (place) => ( +
+
+ +
+

{place.placeName}

+
+ ), + }, + { + key: "park", + header: "Parque", + sortable: true, + render: (place) => ( + + {place.park === "WEG_II" ? "WEG II" : "WEG I"} + + ), + }, + { + key: "section", + header: "Seção", + sortable: true, + render: (place) => ( + {place.section} + ), + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: (place) => ( +
+ + +
+ ), + }, + ]; + + return ( + +
+ void loadPlaces()} disabled={loading}> + + Atualizar + + } + /> + + {error && !dialogOpen && ( +
+ {error} +
+ )} + {notice && ( +
+ {notice} +
+ )} + +
+
+ {loading ? ( +
+ Carregando locais... +
+ ) : ( + row.id} + /> + )} +
+ +
+
+

Novo Local

+

Cadastre um local para disponibilizá-lo nas vagas do gestor.

+
+ +
+
+ + + setForm((current) => ({ ...current, placeName: event.target.value })) + } + placeholder="Ex: Centro de treinamento" + className="mt-1 h-10 border-slate-200 text-sm" + required + /> +
+ +
+ + +
+ +
+ + +
+ + +
+
+
+
+ + !open && closeEditDialog()}> + + + {editingPlace ? "Editar local" : "Criar novo local"} + + Este local será utilizado pelo gestor ao cadastrar uma vaga. + + + +
+ {error && ( +
+ {error} +
+ )} + + + +
+ + + +
+ + + + + +
+
+
+
+ ); +} diff --git a/my-app/src/app/admin/page.tsx b/my-app/src/app/admin/page.tsx new file mode 100644 index 0000000..5d1667b --- /dev/null +++ b/my-app/src/app/admin/page.tsx @@ -0,0 +1,135 @@ +"use client"; + +import { useEffect, useState } from "react"; +import Link from "next/link"; +import { + ArrowRight, + BookOpen, + Briefcase, + MapPin, + ShieldCheck, + UserCog, + Users, +} from "lucide-react"; + +import { AppShell, PageHeader } from "@/components/layout"; +import { StatCard } from "@/components/shared/stat-card"; +import { buttonVariants } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { getAppUsers } from "@/lib/application-api"; +import { cn } from "@/lib/utils"; +import type { UserDTO } from "@/types"; + +const adminAreas = [ + { + title: "Cursos", + description: "Gerencie os cursos disponíveis para as turmas", + href: "/admin/courses", + icon: BookOpen, + iconClassName: "bg-violet-500/10 text-violet-600", + }, + { + title: "Vagas", + description: "Acompanhe as vagas cadastradas no sistema", + href: "/admin/vacancies", + icon: Briefcase, + iconClassName: "bg-amber-500/10 text-amber-600", + }, +] as const; + +export default function AdminPage() { + const [users, setUsers] = useState([]); + const [error, setError] = useState(""); + + useEffect(() => { + getAppUsers() + .then(setUsers) + .catch((loadError) => { + setError(loadError instanceof Error ? loadError.message : "Não foi possível carregar os usuários."); + }); + }, []); + + const administrators = users.filter((user) => user.role === "ADMIN").length; + const managers = users.filter((user) => user.role === "MANAGER").length; + const coordinators = users.filter((user) => user.role === "COORDINATOR").length; + + return ( + +
+ + + {error && ( +
+ {error} +
+ )} + +
+ + + + +
+ +
+ + + Usuários +
+
+ +

{users.length} contas cadastradas

+ + Gerenciar usuários + +
+
+ + + + Locais +
+
+ +

Cadastre os locais disponíveis para as vagas

+ + Gerenciar locais + +
+
+ + {adminAreas.map((area) => { + const Icon = area.icon; + + return ( + + + {area.title} +
+
+ +

{area.description}

+ + Gerenciar {area.title.toLowerCase()} + +
+
+ ); + })} +
+
+
+ ); +} diff --git a/my-app/src/app/admin/sections/page.tsx b/my-app/src/app/admin/sections/page.tsx new file mode 100644 index 0000000..216677e --- /dev/null +++ b/my-app/src/app/admin/sections/page.tsx @@ -0,0 +1,415 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogDescription, +} from "@/components/ui/dialog"; +import { ToastCard } from "@/components/ui/toast-card"; +import { Plus, Briefcase, MapPin, Eye, CalendarCheck } from "lucide-react"; +import { readCollection, writeCollection } from '@/lib/offline-store'; + +// ── Tipos do backend ────────────────────────────────────────────────────────── +type Park = "NORTE" | "SUL" | "CENTRO"; +type Section = "PRODUCAO" | "MANUTENCAO" | "QUALIDADE" | "TI" | "LOGISTICA"; + +interface VacancyRef { + id: string; + title: string; + status: "OPEN" | "CLOSED" | "URGENT"; +} + +interface InterviewRef { + id: string; + candidateName: string; + scheduledDate: string; + status: "SCHEDULED" | "APPROVED" | "REJECTED" | "PENDING"; +} + +interface ManagerSectionDTO { + id: string; + placeName: string; + park: Park; + section: Section; + vacancies: VacancyRef[]; + interviews: InterviewRef[]; +} + +// ── Dados Mock alinhados ao backend ────────────────────────────────────────── +const mockSections: ManagerSectionDTO[] = [ + { + id: "sec-1", + placeName: "Unidade Fabril 1 - Jaraguá do Sul", + park: "NORTE", + section: "PRODUCAO", + vacancies: [ + { id: "vac-1", title: "Aprendiz de Montagem Elétrica", status: "OPEN" }, + { id: "vac-2", title: "Operador CNC Aprendiz", status: "URGENT" }, + ], + interviews: [ + { id: "int-1", candidateName: "Gabriel Santos", scheduledDate: "2026-07-25", status: "SCHEDULED" }, + ], + }, + { + id: "sec-2", + placeName: "Unidade Fabril 2 - Guaramirim", + park: "SUL", + section: "MANUTENCAO", + vacancies: [ + { id: "vac-3", title: "Técnico em Manutenção Preventiva", status: "CLOSED" }, + ], + interviews: [ + { id: "int-2", candidateName: "Beatriz Lima", scheduledDate: "2026-07-24", status: "APPROVED" }, + { id: "int-3", candidateName: "Matheus Rocha", scheduledDate: "2026-07-22", status: "REJECTED" }, + ], + }, + { + id: "sec-3", + placeName: "Centro de Treinamento Técnico", + park: "CENTRO", + section: "QUALIDADE", + vacancies: [], + interviews: [], + }, +]; + +const parkLabels: Record = { + NORTE: "Parque Norte", + SUL: "Parque Sul", + CENTRO: "Centro", +}; + +const sectionLabels: Record = { + PRODUCAO: "Produção", + MANUTENCAO: "Manutenção", + QUALIDADE: "Qualidade", + TI: "Tecnologia da Informação", + LOGISTICA: "Logística", +}; + +export default function AdminSectionsPage() { + const [sections, setSections] = useState(mockSections); + const [detailSection, setDetailSection] = useState(null); + const [isDetailOpen, setIsDetailOpen] = useState(false); + const [successMsg, setSuccessMsg] = useState(""); + + // Form state nova seção + const [newPlaceName, setNewPlaceName] = useState(""); + const [newPark, setNewPark] = useState("NORTE"); + const [newSection, setNewSection] = useState
("PRODUCAO"); + + useEffect(() => { + const cached = readCollection('sections', mockSections); + if (cached && cached.length > 0) { + setSections(cached); + } + }, []); + + const handleCreateSection = () => { + if (!newPlaceName.trim()) return; + + const created: ManagerSectionDTO = { + id: `sec-${Date.now()}`, + placeName: newPlaceName.trim(), + park: newPark, + section: newSection, + vacancies: [], + interviews: [], + }; + + const nextState = [created, ...sections]; + setSections(nextState); + writeCollection('sections', nextState); + setNewPlaceName(""); + setNewPark("NORTE"); + setNewSection("PRODUCAO"); + setSuccessMsg("Seção cadastrada com sucesso!"); + setTimeout(() => setSuccessMsg(""), 7000); + }; + + const handleViewDetail = (sectionItem: ManagerSectionDTO) => { + setDetailSection(sectionItem); + setIsDetailOpen(true); + }; + + const columns: DataTableColumn[] = [ + { + key: "placeName", + header: "Local / Unidade", + sortable: true, + render: (s) => ( +
+
+ +
+
+

{s.placeName}

+

ID: {s.id}

+
+
+ ), + }, + { + key: "park", + header: "Parque", + render: (s) => ( + {parkLabels[s.park]} + ), + }, + { + key: "section", + header: "Seção", + render: (s) => ( + {sectionLabels[s.section]} + ), + }, + { + key: "vacancies", + header: "Vagas", + render: (s) => ( +
+ + {s.vacancies.length} + {s.vacancies.some((v) => v.status === "URGENT") && ( + Urgente + )} + {s.vacancies.some((v) => v.status === "OPEN") && !s.vacancies.some((v) => v.status === "URGENT") && ( + Abertas + )} +
+ ), + }, + { + key: "interviews", + header: "Entrevistas", + render: (s) => ( +
+ + {s.interviews.length} +
+ ), + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: (s) => ( + + ), + }, + ]; + + return ( + +
+ + +
+ {/* Lado Esquerdo - Tabela e Stats */} +
+ {/* Stat Cards rápidos */} +
+
+

Total de Seções

+

{sections.length}

+
+
+

Vagas Cadastradas

+

+ {sections.reduce((acc, s) => acc + s.vacancies.length, 0)} +

+
+
+

Entrevistas Registradas

+

+ {sections.reduce((acc, s) => acc + s.interviews.length, 0)} +

+
+
+ + row.id} + /> +
+ + {/* Lado Direito - Nova Seção */} +
+
+

Nova Seção

+

Preencha os campos para cadastrar uma nova seção.

+
+ +
{ + e.preventDefault(); + handleCreateSection(); + }} + className="space-y-4" + > +
+ + setNewPlaceName(e.target.value)} + placeholder="Ex: Unidade Fabril 3 - Blumenau" + className="h-10 border-slate-200 text-sm" + /> +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + {/* Modal de Detalhes */} + + + + + {detailSection?.placeName} + + + {detailSection && `${parkLabels[detailSection.park]} · ${sectionLabels[detailSection.section]}`} + + + + {detailSection && ( +
+
+
+

ID

+

{detailSection.id}

+
+
+

Parque

+

{parkLabels[detailSection.park]}

+
+
+ +
+
+ +

Vagas ({detailSection.vacancies.length})

+
+ {detailSection.vacancies.length === 0 ? ( +

Nenhuma vaga cadastrada nesta seção.

+ ) : ( +
+ {detailSection.vacancies.map((v) => ( +
+ {v.title} + {v.status === "OPEN" && Aberta} + {v.status === "URGENT" && Urgente} + {v.status === "CLOSED" && Fechada} +
+ ))} +
+ )} +
+ +
+
+ +

Entrevistas ({detailSection.interviews.length})

+
+ {detailSection.interviews.length === 0 ? ( +

Nenhuma entrevista registrada nesta seção.

+ ) : ( +
+ {detailSection.interviews.map((i) => ( +
+
+

{i.candidateName}

+

{i.scheduledDate}

+
+ {i.status === "SCHEDULED" && Agendada} + {i.status === "APPROVED" && Aprovada} + {i.status === "REJECTED" && Reprovada} + {i.status === "PENDING" && Pendente} +
+ ))} +
+ )} +
+
+ )} + + + + +
+
+ + {/* Toast de sucesso */} + +
+ ); +} diff --git a/my-app/src/app/admin/users/page.tsx b/my-app/src/app/admin/users/page.tsx new file mode 100644 index 0000000..024b659 --- /dev/null +++ b/my-app/src/app/admin/users/page.tsx @@ -0,0 +1,530 @@ +"use client"; + +import { FormEvent, useEffect, useState } from "react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { + createCoordinator, + createManager, + deleteCoordinator, + deleteManager, + getManagers, + getCoordinators, + type Coordinator, + type CoordinatorInput, + type Manager, + type ManagerInput, + type ManagerSection, + updateCoordinator, + updateManager, +} from "@/lib/manager-api"; +import { deleteAppUser, getAppUsers, updateAppUser } from '@/lib/application-api'; +import type { UserDTO } from "@/types"; +import { UserPlus, Edit, Trash2 } from "lucide-react"; + +type CreatableUserRole = "MANAGER" | "COORDINATOR"; + +type CreateUserForm = CoordinatorInput & { + role: CreatableUserRole; + section: ManagerSection; +}; + +const initialUserForm: CreateUserForm = { + role: "MANAGER", + name: "", + username: "", + email: "", + password: "", + section: "IT", +}; + +const PASSWORD_REQUIREMENTS = + "A senha deve ter no mínimo 14 caracteres, com letra maiúscula, minúscula, número e caractere especial."; + +// A API de gestores não devolve status de atividade, então novos gestores são exibidos como ativos. +function managerToUser(manager: Manager): UserDTO { + return { + id: manager.id, + name: manager.name, + email: manager.email, + role: "MANAGER", + active: true, + }; +} + +function coordinatorToUser(coordinator: Coordinator): UserDTO { + return { + id: coordinator.id, + name: coordinator.name, + email: coordinator.email, + role: "COORDINATOR", + active: true, + }; +} + +export default function UsuariosPage() { + const [users, setUsers] = useState([]); + const [form, setForm] = useState(initialUserForm); + const [saving, setSaving] = useState(false); + const [error, setError] = useState(""); + const [notice, setNotice] = useState(""); + const [editingUser, setEditingUser] = useState(null); + const [deletingUser, setDeletingUser] = useState(null); + const [editName, setEditName] = useState(''); + const [editEmail, setEditEmail] = useState(''); + const [actionSaving, setActionSaving] = useState(false); + + useEffect(() => { + let active = true; + + Promise.all([getManagers(), getCoordinators(), getAppUsers()]) + .then(([managers, coordinators, appUsers]) => { + if (!active) return; + setUsers([ + ...appUsers.filter((user) => user.role === "ADMIN"), + ...managers.map(managerToUser), + ...coordinators.map(coordinatorToUser), + ]); + }) + .catch((requestError) => { + if (!active) return; + setError( + requestError instanceof Error + ? requestError.message + : "Não foi possível carregar os usuários.", + ); + }); + + return () => { + active = false; + }; + }, []); + + const updateForm = ( + field: Field, + value: CreateUserForm[Field], + ) => { + setForm((current) => ({ ...current, [field]: value })); + }; + + const handleCreateUser = async (event: FormEvent) => { + event.preventDefault(); + setError(""); + setNotice(""); + + const commonPayload: CoordinatorInput = { + name: form.name.trim(), + username: form.username.trim(), + email: form.email.trim(), + password: form.password, + }; + + if ( + !commonPayload.name || + !commonPayload.username || + !commonPayload.email || + !commonPayload.password || + (form.role === "MANAGER" && !form.section) + ) { + setError("Preencha todos os campos para criar o usuário."); + return; + } + + // Replica a regra dos DTOs de gestor e coordenador antes de chamar o backend. + const passwordIsValid = + commonPayload.password.length >= 14 && + /[A-Z]/.test(commonPayload.password) && + /[a-z]/.test(commonPayload.password) && + /\d/.test(commonPayload.password) && + /[^A-Za-z0-9]/.test(commonPayload.password); + + if (!passwordIsValid) { + setError(PASSWORD_REQUIREMENTS); + return; + } + + setSaving(true); + try { + const createdUser = + form.role === "MANAGER" + ? managerToUser( + await createManager({ + ...commonPayload, + section: form.section, + } satisfies ManagerInput), + ) + : coordinatorToUser(await createCoordinator(commonPayload)); + + setUsers((current) => [ + ...current.filter((user) => user.id !== createdUser.id), + createdUser, + ]); + const roleLabel = form.role === "MANAGER" ? "Gestor" : "Coordenador"; + setNotice(`${roleLabel} “${createdUser.name}” criado com sucesso.`); + setForm(initialUserForm); + } catch (requestError) { + setError( + requestError instanceof Error + ? requestError.message + : "Não foi possível criar o usuário.", + ); + } finally { + setSaving(false); + } + }; + + const openEditDialog = (user: UserDTO) => { + setEditingUser(user); + setEditName(user.name); + setEditEmail(user.email); + setError(''); + }; + + const handleEditUser = async () => { + if (!editingUser || !editName.trim()) return; + setActionSaving(true); + setError(''); + try { + let updated: UserDTO; + if (editingUser.role === 'MANAGER') { + updated = managerToUser(await updateManager(editingUser.id, { + name: editName.trim(), email: editEmail.trim(), section: 'IT', + })); + } else if (editingUser.role === 'COORDINATOR') { + updated = coordinatorToUser(await updateCoordinator(editingUser.id, { + name: editName.trim(), email: editEmail.trim(), + })); + } else { + updated = await updateAppUser({ ...editingUser, name: editName.trim(), email: editEmail.trim() }); + } + setUsers((current) => current.map((user) => user.id === updated.id ? updated : user)); + setEditingUser(null); + setNotice('Usuário atualizado com sucesso.'); + } catch (saveError) { + setError(saveError instanceof Error ? saveError.message : 'Não foi possível atualizar o usuário.'); + } finally { + setActionSaving(false); + } + }; + + const handleDeleteUser = async () => { + if (!deletingUser) return; + setActionSaving(true); + setError(''); + try { + if (deletingUser.role === 'MANAGER') await deleteManager(deletingUser.id); + else if (deletingUser.role === 'COORDINATOR') await deleteCoordinator(deletingUser.id); + else await deleteAppUser(deletingUser.id); + setUsers((current) => current.filter((user) => user.id !== deletingUser.id)); + setNotice('Usuário excluído com sucesso.'); + setDeletingUser(null); + } catch (deleteError) { + setError(deleteError instanceof Error ? deleteError.message : 'Não foi possível excluir o usuário.'); + } finally { + setActionSaving(false); + } + }; + + const columns: DataTableColumn[] = [ + { + key: "name", + header: "Usuário", + sortable: true, + render: (user) => ( +
+
+

{user.name}

+

{user.email}

+
+
+ ), + }, + { + key: "role", + header: "Papel / Função", + sortable: true, + render: (user) => { + if (user.role === "ADMIN") return Administrador; + if (user.role === "COORDINATOR") return Coordenador; + if (user.role === "MANAGER") return Gestor / Supervisor; + return Perfil desconhecido; + }, + }, + { + key: "active", + header: "Status", + render: (user) => + user.active ? ( + Ativo + ) : ( + Inativo + ), + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: (user) => ( +
+ + +
+ ), + }, + ]; + + return ( + +
+ + + {error && ( +
+ {error} +
+ )} + {notice && ( +
+ {notice} +
+ )} + +
+
+ row.id} + /> +
+ +
+
+

Criar Usuário

+

Cadastre as credenciais para o primeiro acesso.

+
+ +
+
+ + Tipo de Usuário * + +
+ + +
+
+ + + + + + + + {form.role === "MANAGER" && ( + + )} + + + +

{PASSWORD_REQUIREMENTS}

+ + +
+
+
+
+ + !open && setEditingUser(null)}> + + + Editar usuário + Atualize os dados cadastrais do usuário. + +
+ + +
+ + + + +
+
+ + !open && setDeletingUser(null)}> + + + Excluir usuário + Confirma a exclusão de {deletingUser?.name}? Esta ação não pode ser desfeita. + + + + + + + +
+ ); +} diff --git a/my-app/src/app/admin/vacancies/page.tsx b/my-app/src/app/admin/vacancies/page.tsx new file mode 100644 index 0000000..139812b --- /dev/null +++ b/my-app/src/app/admin/vacancies/page.tsx @@ -0,0 +1,389 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogDescription, +} from "@/components/ui/dialog"; +import { ToastCard } from "@/components/ui/toast-card"; +import { mockVacancies } from "@/lib/mock-data"; +import type { VacancyDTO } from "@/types"; +import { Edit, Trash2, Plus } from "lucide-react"; +import { deleteAdminVacancy, getAdminVacancies, updateAdminVacancy } from '@/lib/application-api'; + +export default function VagasPage() { + const [vacancies, setVacancies] = useState(mockVacancies); + const [editingVacancy, setEditingVacancy] = useState(null); + const [isEditOpen, setIsEditOpen] = useState(false); + const [isDeleteOpen, setIsDeleteOpen] = useState(false); + const [deletingVacancy, setDeletingVacancy] = useState(null); + const [successMsg, setSuccessMsg] = useState(""); + const [toastVariant, setToastVariant] = useState<"success" | "destructive">("success"); + const [error, setError] = useState(''); + const [saving, setSaving] = useState(false); + + useEffect(() => { + getAdminVacancies().then(setVacancies).catch((loadError) => { + setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar as vagas.'); + }); + }, []); + + // Form state para edição / criação + const [formTitle, setFormTitle] = useState(""); + const [formDepartment, setFormDepartment] = useState(""); + const [formLocation, setFormLocation] = useState(""); + const [formTotalSpots, setFormTotalSpots] = useState(1); + const [formStatus, setFormStatus] = useState<"OPEN" | "CLOSED" | "URGENT">("OPEN"); + + const openEdit = (vac: VacancyDTO) => { + setEditingVacancy(vac); + setFormTitle(vac.title); + setFormDepartment(vac.department); + setFormLocation(vac.location); + setFormTotalSpots(vac.totalSpots); + setFormStatus(vac.status); + setIsEditOpen(true); + }; + + const openDelete = (vac: VacancyDTO) => { + setDeletingVacancy(vac); + setIsDeleteOpen(true); + }; + + const handleSaveEdit = async () => { + if (!editingVacancy) return; + setSaving(true); + setError(''); + try { + const saved = await updateAdminVacancy({ + ...editingVacancy, title: formTitle.trim(), department: formDepartment.trim(), + location: formLocation.trim(), totalSpots: formTotalSpots, status: formStatus, + }); + setVacancies((prev) => prev.map((item) => item.id === saved.id ? saved : item)); + setIsEditOpen(false); + setToastVariant("success"); + setSuccessMsg('Vaga atualizada com sucesso!'); + setTimeout(() => setSuccessMsg(""), 7000); + } catch (saveError) { + setError(saveError instanceof Error ? saveError.message : 'Não foi possível atualizar a vaga.'); + } finally { + setSaving(false); + } + }; + + const handleCreate = () => { + if (!formTitle.trim() || !formDepartment.trim() || !formLocation.trim()) return; + const newVac: VacancyDTO = { + id: `vac-${Date.now()}`, + title: formTitle.trim(), + department: formDepartment.trim(), + location: formLocation.trim(), + totalSpots: formTotalSpots, + filledSpots: 0, + status: formStatus, + }; + setVacancies((prev) => [...prev, newVac]); + setFormTitle(""); + setFormDepartment(""); + setFormLocation(""); + setFormTotalSpots(1); + setFormStatus("OPEN"); + setToastVariant("success"); + setSuccessMsg("Vaga criada com sucesso!"); + setTimeout(() => setSuccessMsg(""), 7000); + }; + + const handleConfirmDelete = async () => { + if (!deletingVacancy) return; + setSaving(true); + setError(''); + try { + await deleteAdminVacancy(deletingVacancy.id); + setVacancies((prev) => prev.filter((v) => v.id !== deletingVacancy.id)); + setIsDeleteOpen(false); + setToastVariant("destructive"); + setSuccessMsg(`Vaga "${deletingVacancy.title}" excluída com sucesso.`); + setTimeout(() => setSuccessMsg(""), 7000); + } catch (deleteError) { + setError(deleteError instanceof Error ? deleteError.message : 'Não foi possível excluir a vaga.'); + } finally { + setSaving(false); + } + }; + + const columns: DataTableColumn[] = [ + { + key: "title", + header: "Título da Vaga", + sortable: true, + render: (vac) => ( +
+

{vac.title}

+

{vac.department}

+
+ ), + }, + { + key: "location", + header: "Localização", + render: (vac) => ( + {vac.location} + ), + }, + { + key: "spots", + header: "Vagas Preenchidas", + render: (vac) => ( +
+ + {vac.filledSpots} / {vac.totalSpots} + +
+
+
+
+ ), + }, + { + key: "status", + header: "Status", + render: (vac) => { + if (vac.status === "OPEN") return Aberta; + if (vac.status === "URGENT") return Urgente; + return Fechada; + }, + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: (vac) => ( +
+ + +
+ ), + }, + ]; + + return ( + +
+ + + {error &&
{error}
} + +
+ {/* Lado Esquerdo - Tabela de Vagas */} +
+ row.id} + /> +
+ + {/* Lado Direito - Criar Nova Vaga */} +
+
+

Nova Vaga

+

Preencha as informações para abrir uma nova vaga no sistema.

+
+ +
{ + e.preventDefault(); + handleCreate(); + }} + className="space-y-4" + > +
+ + setFormTitle(e.target.value)} + placeholder="Ex: Aprendiz de Montagem Elétrica" + className="h-10 border-slate-200 text-sm" + /> +
+ +
+
+ + setFormDepartment(e.target.value)} + placeholder="Ex: Produção" + className="h-10 border-slate-200 text-sm" + /> +
+
+ + setFormLocation(e.target.value)} + placeholder="Ex: Unidade Fabril 1" + className="h-10 border-slate-200 text-sm" + /> +
+
+ +
+
+ + setFormTotalSpots(Number(e.target.value))} + className="h-10 border-slate-200 text-sm" + /> +
+
+ + +
+
+ + +
+
+
+
+ + {/* Modal Edição */} + + + + Editar Vaga + + Altere as informações da vaga e salve para atualizar o sistema. + + +
+
+ + setFormTitle(e.target.value)} className="h-10 border-slate-200" /> +
+
+
+ + setFormDepartment(e.target.value)} className="h-10 border-slate-200" /> +
+
+ + setFormLocation(e.target.value)} className="h-10 border-slate-200" /> +
+
+
+
+ + setFormTotalSpots(Number(e.target.value))} className="h-10 border-slate-200" /> +
+
+ + +
+
+
+ + + + +
+
+ + {/* Modal Confirmação Exclusão */} + + + + Confirmar Exclusão + + Deseja realmente excluir a vaga {deletingVacancy?.title}? Esta ação não pode ser desfeita. + + + + + + + + + + {/* Toast de sucesso */} + +
+ ); +} diff --git a/my-app/src/app/backend/[...path]/route.ts b/my-app/src/app/backend/[...path]/route.ts new file mode 100644 index 0000000..198e979 --- /dev/null +++ b/my-app/src/app/backend/[...path]/route.ts @@ -0,0 +1,111 @@ +import { NextRequest } from "next/server"; + +export const dynamic = "force-dynamic"; + +const API_TARGET = + process.env.API_PROXY_TARGET || + "http://localhost:8080/api"; + +const REQUEST_HEADERS_TO_REMOVE = [ + "connection", + "content-length", + "host", + "origin", +]; + +// Mantém o contrato JSON da API mesmo quando a infraestrutura retorna uma página HTML. +function unavailableResponse(status = 503) { + return Response.json( + { + message: + status === 504 + ? "O servidor demorou demais para responder. Tente novamente em alguns minutos." + : "O servidor está temporariamente indisponível. Tente novamente em alguns minutos.", + }, + { + status, + headers: { "Cache-Control": "no-store" }, + }, + ); +} + +function buildTargetUrl(request: NextRequest, path: string[]) { + const base = API_TARGET.endsWith("/") ? API_TARGET : `${API_TARGET}/`; + const targetUrl = new URL(path.map(encodeURIComponent).join("/"), base); + targetUrl.search = request.nextUrl.search; + return targetUrl; +} + +async function proxy( + request: NextRequest, + context: { params: Promise<{ path: string[] }> }, +) { + const { path } = await context.params; + const headers = new Headers(request.headers); + + for (const header of REQUEST_HEADERS_TO_REMOVE) { + headers.delete(header); + } + headers.set("accept-encoding", "identity"); + + const hasBody = request.method !== "GET" && request.method !== "HEAD"; + let upstream: Response; + + try { + upstream = await fetch(buildTargetUrl(request, path), { + method: request.method, + headers, + body: hasBody ? await request.arrayBuffer() : undefined, + redirect: "manual", + cache: "no-store", + // Evita que uma indisponibilidade do serviço deixe a requisição aberta indefinidamente. + signal: AbortSignal.timeout(30_000), + }); + } catch (error) { + return unavailableResponse( + error instanceof DOMException && error.name === "TimeoutError" ? 504 : 503, + ); + } + + const contentType = upstream.headers.get("content-type") || ""; + // A página de erro da hospedagem não deve ser repassada como mensagem para a interface. + if (!upstream.ok && contentType.includes("text/html")) { + return unavailableResponse(upstream.status >= 500 ? upstream.status : 502); + } + + const responseHeaders = new Headers(upstream.headers); + responseHeaders.delete("content-encoding"); + responseHeaders.delete("content-length"); + responseHeaders.delete("transfer-encoding"); + + // The backend is mounted at /api and scopes XSRF-TOKEN to that path. From + // the browser's perspective requests use /backend, so the original cookie + // would never be sent back to this proxy. Re-scope only the cookie path; + // security attributes (HttpOnly, SameSite, Secure, Max-Age) are preserved. + const upstreamHeaders = upstream.headers as Headers & { + getSetCookie?: () => string[]; + }; + const setCookies = upstreamHeaders.getSetCookie?.() + ?? (upstream.headers.get("set-cookie") ? [upstream.headers.get("set-cookie") as string] : []); + if (setCookies.length > 0) { + responseHeaders.delete("set-cookie"); + for (const cookie of setCookies) { + responseHeaders.append( + "set-cookie", + cookie.replace(/Path=\/api(?=;|$)/gi, "Path=/"), + ); + } + } + + return new Response(upstream.body, { + status: upstream.status, + headers: responseHeaders, + }); +} + +export const GET = proxy; +export const POST = proxy; +export const PUT = proxy; +export const PATCH = proxy; +export const DELETE = proxy; +export const OPTIONS = proxy; diff --git a/my-app/src/app/classes/[id]/page.tsx b/my-app/src/app/classes/[id]/page.tsx new file mode 100644 index 0000000..4e40892 --- /dev/null +++ b/my-app/src/app/classes/[id]/page.tsx @@ -0,0 +1,64 @@ +'use client'; + +import { use, useEffect, useState } from 'react'; +import Link from 'next/link'; +import { ArrowLeft, GraduationCap, Users } from 'lucide-react'; +import { AppShell, PageHeader } from '@/components/layout'; +import { Badge } from '@/components/ui/badge'; +import { buttonVariants } from '@/components/ui/button'; +import { getAppStudents, getClasses } from '@/lib/application-api'; +import { cn } from '@/lib/utils'; +import type { ClassDTO, StudentDTO } from '@/types'; + +export default function ClassDetailPage({ params }: { params: Promise<{ id: string }> }) { + const { id } = use(params); + const [classItem, setClassItem] = useState(null); + const [students, setStudents] = useState([]); + const [error, setError] = useState(''); + + useEffect(() => { + Promise.all([getClasses(), getAppStudents()]) + .then(([classes, studentData]) => { + const found = classes.find((item) => item.id === id); + if (!found) { + setError('Turma não encontrada.'); + return; + } + setClassItem(found); + setStudents(studentData.filter((student) => student.className === found.name)); + }) + .catch((loadError) => setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar a turma.')); + }, [id]); + + return ( + +
+ + Voltar + + } + /> + {error &&
{error}
} + {classItem && ( +
+

Código

{classItem.code}

+

Ocupação

{classItem.totalStudents} / {classItem.maxStudents}

+

Status

{classItem.status === 'IN_PROGRESS' ? 'Em andamento' : 'Planejada'}
+
+ )} +
+

Alunos da turma

+ {students.length === 0 ?

Nenhum aluno vinculado.

: ( +
+ {students.map((student) => {student.name}{student.registration})} +
+ )} +
+
+
+ ); +} diff --git a/my-app/src/app/classes/new/page.tsx b/my-app/src/app/classes/new/page.tsx new file mode 100644 index 0000000..181c27f --- /dev/null +++ b/my-app/src/app/classes/new/page.tsx @@ -0,0 +1,229 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { useRouter } from "next/navigation"; +import { AppShell, PageHeader } from "@/components/layout"; +import { Button, buttonVariants } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Checkbox } from "@/components/ui/checkbox"; +import { Save, ArrowLeft } from "lucide-react"; +import Link from "next/link"; +import { cn } from "@/lib/utils"; +import { createClass, getAppStudents, getCourses } from '@/lib/application-api'; +import type { CourseDTO, StudentDTO } from '@/types'; + +export default function NovaTurmaPage() { + const router = useRouter(); + const [selectedStudents, setSelectedStudents] = useState([]); + const [classCode, setClassCode] = useState(""); + const [course, setCourse] = useState(""); + const [period, setPeriod] = useState(""); + const [startDate, setStartDate] = useState(""); + const [finishDate, setFinishDate] = useState(""); + const [courses, setCourses] = useState([]); + const [students, setStudents] = useState([]); + const [saving, setSaving] = useState(false); + const [error, setError] = useState(""); + + useEffect(() => { + Promise.all([getCourses(), getAppStudents()]) + .then(([courseData, studentData]) => { + setCourses(courseData); + setStudents(studentData); + }) + .catch((loadError) => setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar os dados.')); + }, []); + + const toggleStudent = (id: string) => { + setSelectedStudents((prev) => + prev.includes(id) ? prev.filter((sId) => sId !== id) : [...prev, id] + ); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + const selectedCourse = courses.find((item) => item.id === course); + if (!selectedCourse) { + setError('Selecione um curso válido.'); + return; + } + if (!startDate || !finishDate || finishDate < startDate) { + setError('Informe um período de datas válido para a turma.'); + return; + } + setSaving(true); + setError(''); + try { + await createClass({ + name: `${selectedCourse.name} - ${classCode.trim()}`, code: classCode.trim(), + courseId: selectedCourse.id, courseName: selectedCourse.name, period, + startDate, finishDate, + totalStudents: selectedStudents.length, maxStudents: Math.max(25, selectedStudents.length), + status: 'PLANNED', studentIds: selectedStudents, + }); + router.push('/classes'); + } catch (saveError) { + setError(saveError instanceof Error ? saveError.message : 'Não foi possível cadastrar a turma.'); + } finally { + setSaving(false); + } + }; + + return ( + +
+ + Voltar + + } + /> + + {error && ( +
{error}
+ )} +
+ + + Informações da Turma + + +
+ + setClassCode(e.target.value)} + required + /> +
+ +
+ + +
+ +
+ + +
+ +
+ + setStartDate(e.target.value)} + required + /> +
+ +
+ + setFinishDate(e.target.value)} + required + /> +
+
+
+ + {/* Student Selection List */} + + +
+ Vincular Alunos +

+ Selecione os alunos disponíveis para integrar esta turma ({selectedStudents.length} selecionados) +

+
+
+ + {students.map((student) => ( +
+
+ toggleStudent(student.id)} + /> +
+ +

+ Matrícula: {student.registration} | Curso atual: {student.courseName} +

+
+
+
+ ))} +
+
+ +
+ + Cancelar + + +
+
+
+
+ ); +} diff --git a/my-app/src/app/classes/page.tsx b/my-app/src/app/classes/page.tsx new file mode 100644 index 0000000..4c7db77 --- /dev/null +++ b/my-app/src/app/classes/page.tsx @@ -0,0 +1,307 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogDescription, +} from "@/components/ui/dialog"; +import { ToastCard } from "@/components/ui/toast-card"; +import type { ClassDTO } from "@/types"; +import { GraduationCap, Eye, Save, Trash2 } from "lucide-react"; +import Link from "next/link"; +import { cn } from "@/lib/utils"; +import { getClasses } from '@/lib/application-api'; +import { mockCourses } from "@/lib/mock-data"; + +export default function TurmasPage() { + const [classes, setClasses] = useState([]); + const [error, setError] = useState(''); + const [className, setClassName] = useState(""); + const [classCode, setClassCode] = useState(""); + const [course, setCourse] = useState(""); + const [period, setPeriod] = useState(""); + const [successMsg, setSuccessMsg] = useState(""); + const [toastVariant, setToastVariant] = useState<"success" | "destructive">("success"); + const [deletingClass, setDeletingClass] = useState(null); + const [isDeleteOpen, setIsDeleteOpen] = useState(false); + + useEffect(() => { + getClasses().then(setClasses).catch((loadError) => { + setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar as turmas.'); + }); + }, []); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (!className.trim() || !classCode.trim() || !course || !period) { + setToastVariant("destructive"); + setSuccessMsg("Preencha todos os campos obrigatórios (*)."); + setTimeout(() => setSuccessMsg(""), 7000); + return; + } + const newClass: ClassDTO = { + id: `cls-${Date.now()}`, + name: className.trim(), + code: classCode.trim(), + courseName: mockCourses.find((c) => c.id === course)?.name || "Curso Geral", + period, + maxStudents: 30, + totalStudents: 0, + status: "PLANNED", + }; + setClasses((prev) => [newClass, ...prev]); + setClassName(""); + setClassCode(""); + setCourse(""); + setPeriod(""); + setToastVariant("success"); + setSuccessMsg("Turma cadastrada com sucesso!"); + setTimeout(() => setSuccessMsg(""), 7000); + }; + + const openDelete = (cls: ClassDTO) => { + setDeletingClass(cls); + setIsDeleteOpen(true); + }; + + const handleConfirmDelete = () => { + if (!deletingClass) return; + setClasses((prev) => prev.filter((c) => c.id !== deletingClass.id)); + setIsDeleteOpen(false); + setToastVariant("destructive"); + setSuccessMsg(`Turma "${deletingClass.name}" excluída com sucesso.`); + setTimeout(() => setSuccessMsg(""), 7000); + }; + + const columns: DataTableColumn[] = [ + { + key: "name", + header: "Turma", + sortable: true, + render: (cls) => ( +
+
+ +
+
+

{cls.name}

+

Código: {cls.code}

+
+
+ ), + }, + { + key: "courseName", + header: "Curso Vinculado", + render: (cls) => ( + {cls.courseName} + ), + }, + { + key: "period", + header: "Período", + render: (cls) => ( + {cls.period} + ), + }, + { + key: "occupancy", + header: "Ocupação", + render: (cls) => ( +
+
+ {cls.totalStudents} / {cls.maxStudents} + {Math.round((cls.totalStudents / cls.maxStudents) * 100)}% +
+
+
+
+
+ ), + }, + { + key: "status", + header: "Status", + render: (cls) => { + if (cls.status === "IN_PROGRESS") return Em Andamento; + if (cls.status === "PLANNED") return Planejada; + return Finalizada; + }, + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: (cls) => ( +
+ + Ver Alunos + + +
+ ), + }, + ]; + + return ( + +
+ + + {error &&
{error}
} + +
+ {/* Lado Esquerdo - Tabela de Turmas */} +
+ row.id} + /> +
+ + {/* Lado Direito - Cadastrar Turma */} +
+
+

Cadastrar Turma

+

Preencha os dados da turma para efetuar o cadastro.

+
+ +
+
+ + setClassName(e.target.value)} + className="mt-1 h-10 border-slate-200 text-sm" + /> +
+ +
+ + setClassCode(e.target.value)} + className="mt-1 h-10 border-slate-200 text-sm" + /> +
+ +
+ + +
+ +
+ + +
+ + +
+
+
+
+ + {/* Modal de Exclusão */} + + + + Confirmar Exclusão + + Deseja realmente excluir a turma {deletingClass?.name}? Esta ação não pode ser desfeita. + + + + + + + + + + +
+ ); +} + + diff --git a/my-app/src/app/coordinator/direct/page.tsx b/my-app/src/app/coordinator/direct/page.tsx new file mode 100644 index 0000000..7e511d9 --- /dev/null +++ b/my-app/src/app/coordinator/direct/page.tsx @@ -0,0 +1,294 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogDescription, +} from "@/components/ui/dialog"; +import type { StudentDTO, VacancyDTO } from "@/types"; +import { Users, Briefcase, Search, ChevronRight, CheckCircle2, ArrowLeft } from "lucide-react"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { directStudentToVacancy, getAppStudents } from '@/lib/application-api'; +import { getVacancies } from '@/lib/manager-api'; + +type Step = "select-vacancy" | "select-student"; + +export default function CoordinatorDirectPage() { + const [step, setStep] = useState("select-vacancy"); + const [searchVacancy, setSearchVacancy] = useState(""); + const [searchStudent, setSearchStudent] = useState(""); + const [selectedVacancy, setSelectedVacancy] = useState(null); + const [directedStudentId, setDirectedStudentId] = useState(null); + const [isConfirmOpen, setIsConfirmOpen] = useState(false); + const [pendingStudent, setPendingStudent] = useState(null); + const [successMsg, setSuccessMsg] = useState(""); + const [vacancies, setVacancies] = useState([]); + const [students, setStudents] = useState([]); + const [saving, setSaving] = useState(false); + const [error, setError] = useState(''); + + useEffect(() => { + Promise.all([getVacancies(), getAppStudents()]) + .then(([vacancyData, studentData]) => { + setVacancies(vacancyData.map((item) => ({ + id: item.id, title: item.name, department: item.section, + location: item.park, totalSpots: item.numbersVacancies, + filledSpots: 0, status: 'OPEN', + }))); + setStudents(studentData); + }) + .catch((loadError) => setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar os dados.')); + }, []); + + const openVacancies = vacancies.filter((v) => v.status === "OPEN" || v.status === "URGENT"); + const availableStudents = students.filter((s) => s.status === "ACTIVE"); + + const filteredVacancies = openVacancies.filter( + (v) => + v.title.toLowerCase().includes(searchVacancy.toLowerCase()) || + v.department.toLowerCase().includes(searchVacancy.toLowerCase()) + ); + + const filteredStudents = availableStudents.filter( + (s) => + s.name.toLowerCase().includes(searchStudent.toLowerCase()) || + s.registration.includes(searchStudent) + ); + + const handleSelectVacancy = (vacancy: VacancyDTO) => { + setSelectedVacancy(vacancy); + setStep("select-student"); + }; + + const handleDirectStudent = (student: StudentDTO) => { + setPendingStudent(student); + setIsConfirmOpen(true); + }; + + const handleConfirmDirection = async () => { + if (!pendingStudent || !selectedVacancy) return; + setSaving(true); + setError(''); + try { + await directStudentToVacancy(pendingStudent.id, selectedVacancy.id); + setDirectedStudentId(pendingStudent.id); + setIsConfirmOpen(false); + setSuccessMsg( + `${pendingStudent.name} foi associado(a) à vaga "${selectedVacancy.title}" com sucesso.` + ); + setTimeout(() => setSuccessMsg(""), 6000); + } catch (saveError) { + setIsConfirmOpen(false); + setError(saveError instanceof Error ? saveError.message : 'Não foi possível direcionar o aluno.'); + } finally { + setSaving(false); + } + }; + + return ( + +
+ + + {error &&
{error}
} + + {/* Indicador de Steps */} +
+
+
+ 1 +
+ Selecionar Vaga +
+ +
+
+ 2 +
+ Selecionar Aluno +
+
+ + {/* Step 1 - Vagas em Aberto */} + {step === "select-vacancy" && ( +
+
+ + setSearchVacancy(e.target.value)} + className="pl-10 h-11 bg-white border-slate-200 rounded-xl text-sm" + /> +
+ + {filteredVacancies.length === 0 ? ( +
+ +

Nenhuma vaga em aberto encontrada.

+
+ ) : ( +
+ {filteredVacancies.map((vacancy) => ( + + ))} +
+ )} +
+ )} + + {/* Step 2 - Alunos Disponíveis */} + {step === "select-student" && selectedVacancy && ( +
+ {/* Card da vaga selecionada */} +
+
+
+ +
+
+

Vaga Selecionada

+

{selectedVacancy.title}

+

{selectedVacancy.department} · {selectedVacancy.location}

+
+
+ +
+ +
+ + setSearchStudent(e.target.value)} + className="pl-10 h-11 bg-white border-slate-200 rounded-xl text-sm" + /> +
+ +
+ {filteredStudents.map((student) => { + const initials = student.name.split(" ").map((n) => n[0]).slice(0, 2).join(""); + const isDirected = directedStudentId === student.id; + + return ( +
+
+ + + {initials} + +
+

{student.name}

+

Matrícula: {student.registration} · {student.className}

+

{student.courseName}

+
+
+ +
+
+

+ Frequência: {student.attendanceRate == null ? "Não informada" : `${student.attendanceRate}%`} +

+

+ Nota: {student.performanceGrade == null ? "Não informada" : student.performanceGrade} +

+
+ {isDirected ? ( + + Direcionado + + ) : ( + + )} +
+
+ ); + })} +
+
+ )} +
+ + {/* Modal de Confirmação */} + + + + Confirmar Direcionamento + + Deseja direcionar {pendingStudent?.name} para a vaga{" "} + {selectedVacancy?.title}? A operação somente será concluída se a API persistir o vínculo. + + + + + + + + + + {/* Toast de sucesso */} + {successMsg && ( +
+ {successMsg} +
+ )} +
+ ); +} diff --git a/my-app/src/app/courses/page.tsx b/my-app/src/app/courses/page.tsx new file mode 100644 index 0000000..3e67dcc --- /dev/null +++ b/my-app/src/app/courses/page.tsx @@ -0,0 +1,267 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogDescription, +} from "@/components/ui/dialog"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import type { CourseDTO, StudentDTO } from "@/types"; +import { BookOpen, Users, Eye, ArrowUpRight, Plus } from "lucide-react"; +import Link from "next/link"; +import { cn } from "@/lib/utils"; +import { buttonVariants } from "@/components/ui/button"; +import { createCourse, getAppStudents, getCourses } from '@/lib/application-api'; + +export default function CoordinatorCoursesPage() { + const [filterTab, setFilterTab] = useState("ALL"); + const [selectedCourse, setSelectedCourse] = useState(null); + const [isStudentsOpen, setIsStudentsOpen] = useState(false); + const [formName, setFormName] = useState(""); + const [successMsg, setSuccessMsg] = useState(""); + const [courses, setCourses] = useState([]); + const [students, setStudents] = useState([]); + const [error, setError] = useState(""); + const [saving, setSaving] = useState(false); + + useEffect(() => { + Promise.all([getCourses(), getAppStudents()]).then(([courseData, studentData]) => { + setCourses(courseData); + setStudents(studentData); + }).catch((loadError) => { + setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar os cursos.'); + }); + }, []); + + const filteredCourses = courses.filter((c) => { + if (filterTab === "ACTIVE") return c.status === "ACTIVE"; + if (filterTab === "COMPLETED") return c.status === "COMPLETED"; + return true; + }); + + const courseStudents = (course: CourseDTO): StudentDTO[] => + students.filter((s) => s.courseName === course.name); + + const handleViewStudents = (course: CourseDTO) => { + setSelectedCourse(course); + setIsStudentsOpen(true); + }; + + const handleCreate = async () => { + if (!formName.trim()) return; + const newCourse: Omit = { + name: formName, + code: "", + coordinatorName: "Meu Coordenador", + totalStudents: 0, + status: "ACTIVE", + }; + setSaving(true); + setError(''); + try { + const created = await createCourse(newCourse); + setCourses((prev) => [...prev, created]); + setFormName(""); + setSuccessMsg("Curso criado com sucesso!"); + setTimeout(() => setSuccessMsg(""), 4000); + } catch (saveError) { + setError(saveError instanceof Error ? saveError.message : 'Não foi possível criar o curso.'); + } finally { + setSaving(false); + } + }; + + const columns: DataTableColumn[] = [ + { + key: "name", + header: "Curso Técnico", + sortable: true, + render: (course) => ( +
+
+ +
+
+

{course.name}

+

Código: {course.code}

+
+
+ ), + }, + { + key: "totalStudents", + header: "Alunos Matriculados", + sortable: true, + render: (course) => ( +
+ + {course.totalStudents} alunos +
+ ), + }, + { + key: "status", + header: "Status", + render: (course) => { + if (course.status === "ACTIVE") return Em Andamento; + if (course.status === "COMPLETED") return Concluído; + return Planejado; + }, + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: (course) => ( +
+ + + Turmas + +
+ ), + }, + ]; + + return ( + +
+ + + {error && ( +
{error}
+ )} +
+
+ + + Todos os Cursos + Em Andamento + Concluídos + + + + row.id} + /> +
+ +
+
+

Novo Curso

+

Preencha os dados para cadastrar um novo curso.

+
+ +
{ + event.preventDefault(); + void handleCreate(); + }} + className="space-y-4" + > +
+ + setFormName(event.target.value)} + placeholder="Ex: Técnico em Mecatrônica" + className="mt-1 h-10 border-slate-200 text-sm" + /> +
+ + +
+
+
+
+ + {/* Modal - Alunos do Curso */} + + + + + Alunos — {selectedCourse?.name} + + + Alunos matriculados neste curso. Clique em "Ver Detalhes" para acessar o perfil completo. + + +
+ {selectedCourse && courseStudents(selectedCourse).length === 0 ? ( +

Nenhum aluno encontrado para este curso.

+ ) : ( + selectedCourse && + courseStudents(selectedCourse).map((s) => ( +
+
+

{s.name}

+

Mat: {s.registration} · {s.className}

+
+ setIsStudentsOpen(false)} + > + Detalhes + +
+ )) + )} +
+ + + +
+
+ + {successMsg && ( +
+ {successMsg} +
+ )} +
+ ); +} diff --git a/my-app/src/app/dashboard/page.tsx b/my-app/src/app/dashboard/page.tsx new file mode 100644 index 0000000..a543751 --- /dev/null +++ b/my-app/src/app/dashboard/page.tsx @@ -0,0 +1,163 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { StatCard } from "@/components/shared/stat-card"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Progress } from "@/components/ui/progress"; +import { buttonVariants } from "@/components/ui/button"; +import type { ClassDTO, StudentDTO, VacancyDTO } from "@/types"; +import { getAdminVacancies, getAppStudents, getClasses } from '@/lib/application-api'; +import { Users, GraduationCap, ArrowUpRight, Briefcase, Plus } from "lucide-react"; +import Link from "next/link"; +import { cn } from "@/lib/utils"; + +export default function DashboardPage() { + const [vacancies, setVacancies] = useState([]); + const [students, setStudents] = useState([]); + const [classes, setClasses] = useState([]); + const [error, setError] = useState(''); + + useEffect(() => { + Promise.all([getAdminVacancies(), getAppStudents(), getClasses()]) + .then(([vacancyData, studentData, classData]) => { + setVacancies(vacancyData); + setStudents(studentData); + setClasses(classData); + }) + .catch((loadError) => { + setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar o painel.'); + }); + }, []); + + const totalStudents = students.length; + const activeClasses = classes.filter((item) => item.status === "IN_PROGRESS").length; + const totalVacancies = vacancies.length; + + const vacancyColumns: DataTableColumn[] = [ + { + key: "title", + header: "Vaga", + sortable: true, + render: (vacancy) => ( +
+

{vacancy.title}

+ {/* Department + location collapsed into one line to keep the row height consistent with other tables in the app. */} +

{vacancy.department} · {vacancy.location}

+
+ ), + }, + { + key: "filledSpots", + header: "Preenchimento", + render: (vacancy) => { + // Math.round avoids displaying e.g. "66.666...%" when totalSpots doesn't divide evenly. + const pct = Math.round((vacancy.filledSpots / vacancy.totalSpots) * 100); + return ( +
+
+ {vacancy.filledSpots} / {vacancy.totalSpots} vagas + {pct}% +
+ +
+ ); + }, + }, + { + key: "status", + header: "Status", + render: (vacancy) => { + // URGENT takes priority in the else-if chain — it signals HR action needed, + // whereas CLOSED is a terminal state that just needs acknowledgement. + if (vacancy.status === "CLOSED") return Encerrada; + if (vacancy.status === "URGENT") return Urgente; + return Aberta; + }, + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: () => ( + + Detalhes + + ), + }, + ]; + + return ( + +
+ + Nova Turma + + } + /> + + {error && ( +
+ {error} +
+ )} + +
+ {/* Vacancies table — spans 2 of 3 columns so the stat sidebar doesn't compete for attention. */} +
+
+
+

Vagas Criadas

+

Visão geral das vagas abertas nas unidades fabris

+
+ + Ver todos + +
+ + {/* pageSize=5 is intentional: keeps the card within viewport height on 1080p without scrolling. */} + row.id} + /> + +
+ {/* Stats Grid */} +
+ + + +
+
+
+
+ ); +} diff --git a/my-app/src/app/favicon.ico b/my-app/src/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/my-app/src/app/favicon.ico and /dev/null differ diff --git a/my-app/src/app/globals.css b/my-app/src/app/globals.css index a2dc41e..d05eb05 100644 --- a/my-app/src/app/globals.css +++ b/my-app/src/app/globals.css @@ -1,26 +1,196 @@ @import "tailwindcss"; +@import "tw-animate-css"; -:root { - --background: #ffffff; - --foreground: #171717; -} +@custom-variant dark (&:is(.dark *)); + +/* ============================================================ + Quick Transfer — Design Tokens (Light Mode Only) + All values mapped from DESIGN_SYSTEM.md Phase 1 audit. + ============================================================ */ @theme inline { - --color-background: var(--background); + /* Typography */ + --font-heading: "Segoe UI", Arial, sans-serif; + --font-sans: "Segoe UI", Arial, sans-serif; + + /* Radius scale */ + --radius-sm: calc(var(--radius) * 0.5); + --radius-md: calc(var(--radius) * 1); + --radius-lg: calc(var(--radius) * 1.5); + --radius-xl: calc(var(--radius) * 2); + --radius-2xl: calc(var(--radius) * 2.5); + --radius-3xl: calc(var(--radius) * 3); + --radius-4xl: calc(var(--radius) * 3.5); + + /* shadcn semantic color mappings */ + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); --color-foreground: var(--foreground); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); + --color-background: var(--background); + + /* ── Extended palette: status colors ── */ + --color-status-success: var(--status-success); + --color-status-success-foreground: var(--status-success-foreground); + --color-status-danger: var(--status-danger); + --color-status-danger-foreground: var(--status-danger-foreground); + --color-status-warning: var(--status-warning); + --color-status-warning-foreground: var(--status-warning-foreground); + --color-status-info: var(--status-info); + --color-status-info-foreground: var(--status-info-foreground); + --color-status-neutral: var(--status-neutral); + --color-status-neutral-foreground: var(--status-neutral-foreground); + + /* ── Extended palette: primary scale (Navy) ── */ + --color-primary-50: #ECF1FF; /* ── The side bar color ── */ + --color-primary-100: #D5E3FF; + --color-primary-200: #A7C8FF; + --color-primary-300: #89ACE7; + --color-primary-400: #6E92CA; + --color-primary-500: #5478AF; + --color-primary-600: #3A5F94; + --color-primary-700: #00579D; + --color-primary-800: #00335C; + --color-primary-900: #001E40; + --color-primary-950: #000000; + + /* ── Extended palette: secondary scale (Cyan/Teal) ── */ + --color-secondary-50: #E3F3FF; + --color-secondary-100: #C4E7FF; + --color-secondary-200: #7BD0FF; + --color-secondary-300: #2DB7F2; + --color-secondary-400: #009BD1; + --color-secondary-500: #0080AD; + --color-secondary-600: #00668A; + --color-secondary-700: #004C69; + --color-secondary-800: #00354A; + --color-secondary-900: #001E2C; + + /* ── Extended palette: tertiary scale (Blue-Gray) ── */ + --color-tertiary-50: #E9F1FF; + --color-tertiary-100: #D4E4FA; + --color-tertiary-200: #B9C8DE; + --color-tertiary-300: #9DACC2; + --color-tertiary-400: #8392A6; + --color-tertiary-500: #69788C; + --color-tertiary-600: #516072; + --color-tertiary-700: #39485A; + --color-tertiary-800: #233143; + --color-tertiary-900: #0D1C2D; + + /* ── Extended palette: neutral scale ── */ + --color-neutral-50: #EFF1F3; + --color-neutral-100: #E0E3E5; + --color-neutral-200: #C4C7C9; + --color-neutral-300: #A9ABAD; + --color-neutral-400: #8E9193; + --color-neutral-500: #747779; + --color-neutral-600: #5C5F61; + --color-neutral-700: #444749; + --color-neutral-800: #2D3133; + --color-neutral-900: #191C1E; } -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } +:root { + /* ── Base semantic tokens (light mode) ── */ + --background: #EFF1F3; + --foreground: #191C1E; + --card: #FFFFFF; + --card-foreground: #191C1E; + --popover: #FFFFFF; + --popover-foreground: #191C1E; + + /* Primary = Navy blue #003061 */ + --primary: #003061; + --primary-foreground: #FFFFFF; + + /* Secondary = Cyan/Teal */ + --secondary: #E3F3FF; + --secondary-foreground: #004C69; + + /* Muted */ + --muted: #E0E3E5; + --muted-foreground: #5C5F61; + + /* Accent = Light blue highlight */ + --accent: #ECF1FF; + --accent-foreground: #001E40; + + /* Destructive = Red */ + --destructive:rgb(218, 0, 0); + + /* Borders & Inputs */ + --border: #C4C7C9; + --input: #A9ABAD; + --ring: #003061; + + /* Radius base = 8px */ + --radius: 0.5rem; + + /* ── Sidebar tokens (dark navy) ── */ + --sidebar: #ECF1FF; + --sidebar-foreground: #E0E3E5; + --sidebar-primary: #003061; + --sidebar-primary-foreground: #FFFFFF; + --sidebar-accent: #003061; + --sidebar-accent-foreground: #FFFFFF; + --sidebar-border: rgba(255, 255, 255, 0.1); + --sidebar-ring: #5478AF; + + /* ── Chart colors ── */ + --chart-1: #003061; + --chart-2: #1F477B; + --chart-3: #3A5F94; + --chart-4: #5478AF; + --chart-5: #6E92CA; + + /* ── Status colors ── */ + --status-success: #DCFCE7; + --status-success-foreground: #166534; + --status-danger: #FEE2E2; + --status-danger-foreground: #991B1B; + --status-warning: #FEF3C7; + --status-warning-foreground: #92400E; + --status-info: #D5E3FF; + --status-info-foreground: #001E40; + --status-neutral: #EFF1F3; + --status-neutral-foreground: #444749; } -body { - background: var(--background); - color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } + html { + @apply font-sans; + } } diff --git a/my-app/src/app/layout.tsx b/my-app/src/app/layout.tsx index 9852c15..221768f 100644 --- a/my-app/src/app/layout.tsx +++ b/my-app/src/app/layout.tsx @@ -1,29 +1,24 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); - export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Quick Transfer", + description: "Sistema de gerenciamento de turmas, alunos e vagas", + icons: { + icon: '/assets/images/logo/logo-weg.png', // Caminho a partir da pasta public/ + }, }; -export default function RootLayout({ children }: LayoutProps<"/">) { +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { return ( - - {children} + + + {children} + ); } diff --git a/my-app/src/app/login/page.tsx b/my-app/src/app/login/page.tsx new file mode 100644 index 0000000..5db463d --- /dev/null +++ b/my-app/src/app/login/page.tsx @@ -0,0 +1,401 @@ +"use client"; + +import "@/app/globals.css"; +import { FormEvent, useState } from "react"; +import Image from "next/image"; +import { useRouter } from "next/navigation"; +import { Input } from "@/components/ui/input"; +import { apiFetch, ApiError } from "@/lib/api"; +import { + AUTH_COOKIE_NAME, + getRedirectPathByRole, + ROLE_COOKIE_NAME, +} from "@/lib/auth"; +import { + authenticateMockUser, + createMockSessionToken, + IS_MOCK_AUTH_ENABLED, + MOCK_AUTH_CREDENTIALS, +} from "@/lib/mock-auth"; +import { UserRole } from "@/types"; + +import { USER_ID_COOKIE_NAME, USER_NAME_COOKIE_NAME } from '@/lib/auth'; + +type AuthenticatedUser = { + id: string; + name: string; + username: string; + role: UserRole; +}; + +// Password policy enforced by the backend on /auth/first-access. +// Duplicated here to give immediate feedback without a round-trip. +const PASSWORD_REQUIREMENTS = + "A nova senha deve ter ao menos 14 caracteres, uma letra maiúscula, um número e um caractere especial."; + +// Maps ApiError status codes to user-friendly messages. +// 401 and 404 are intentionally vague to avoid user enumeration. +function friendlyLoginError(error: unknown) { + if (!(error instanceof Error)) { + return "Erro inesperado ao realizar o login. Tente novamente."; + } + + if (error instanceof ApiError) { + if (error.status === 401) return "Usuário ou senha inválidos."; + if (error.status === 404) return "Usuário não encontrado."; + // Status 0 or 5xx means a network/server failure — the ApiError already has a good message. + if (error.status === 0 || error.status >= 500) return error.message; + } + + if (error.message === "Failed to fetch") { + return "Não foi possível acessar o servidor. Verifique se a API está ligada."; + } + + return error.message || "Não foi possível realizar o login."; +} + +// Runtime shape check before writing cookies and redirecting. +// The backend contract is informal — the response could change without a +// type-safe client being generated; this guards against silent breakage. +function isAuthenticatedUser(value: unknown): value is AuthenticatedUser { + if (typeof value !== "object" || value === null) return false; + + const user = value as Record; + return ( + typeof user.id === "string" && + typeof user.name === "string" && + typeof user.username === "string" && + typeof user.role === "string" && + ["ADMIN", "COORDINATOR", "MANAGER"].includes(user.role) + ); +} + +export default function Login() { + const router = useRouter(); + + const [usuario, setUsuario] = useState(""); + const [senha, setSenha] = useState(""); + const [novaSenha, setNovaSenha] = useState(""); + const [confirmacaoSenha, setConfirmacaoSenha] = useState(""); + const [primeiroAcesso, setPrimeiroAcesso] = useState(false); + const [carregando, setCarregando] = useState(false); + const [erro, setErro] = useState(""); + + const finishLogin = ( + authenticatedUser: AuthenticatedUser, + mockSessionToken?: string + ) => { + const secure = window.location.protocol === "https:" ? "; secure" : ""; + // Role cookie must be JS-readable (no HttpOnly) so client components can + // read it to render role-specific UI without a server round-trip. + document.cookie = `${ROLE_COOKIE_NAME}=${encodeURIComponent(authenticatedUser.role)}; path=/; max-age=86400; samesite=strict${secure}`; + document.cookie = `${USER_ID_COOKIE_NAME}=${encodeURIComponent(authenticatedUser.id)}; path=/; max-age=86400; samesite=strict${secure}`; + document.cookie = `${USER_NAME_COOKIE_NAME}=${encodeURIComponent(authenticatedUser.name)}; path=/; max-age=86400; samesite=strict${secure}`; + + // In a real login the backend sets the HttpOnly JWT cookie itself in the + // Set-Cookie response header. Only the mock path needs to set it client-side. + if (mockSessionToken) { + // 8h (28800s) matches the mock token TTL set in createMockSessionToken. + document.cookie = `${AUTH_COOKIE_NAME}=${encodeURIComponent(mockSessionToken)}; path=/; max-age=28800; samesite=strict${secure}`; + } + + // router.replace keeps the login page out of browser history so the back + // button doesn't return users to the login form after signing in. + router.replace(getRedirectPathByRole(authenticatedUser.role)); + router.refresh(); + }; + + const authenticate = async (username: string, password: string) => { + const authenticatedUser = await apiFetch("/auth/login", { + method: "POST", + body: JSON.stringify({ username, password }), + }); + + if (!isAuthenticatedUser(authenticatedUser)) { + throw new ApiError("O servidor retornou uma resposta de autenticação inválida.", 502); + } + + finishLogin(authenticatedUser); + }; + + const handleLogin = async () => { + const username = usuario.trim(); + + // The mock username is checked first to skip the API entirely — avoids + // waiting for a timeout when the backend is down during development. + if (IS_MOCK_AUTH_ENABLED && username === MOCK_AUTH_CREDENTIALS.username) { + const mockUser = authenticateMockUser(username, senha); + + if (!mockUser) { + setErro("Senha do usuário de contingência inválida."); + return; + } + + finishLogin(mockUser, createMockSessionToken(mockUser)); + return; + } + + try { + await authenticate(username, senha); + } catch (error: unknown) { + // Per the current backend contract, 403 on the public login endpoint + // means "valid credentials but first access — you must set a password." + // This is an unusual use of 403 but is intentional on the backend side. + if (error instanceof ApiError && error.status === 403) { + setPrimeiroAcesso(true); + setErro("Primeiro acesso identificado. Defina sua nova senha para continuar."); + return; + } + + setErro(friendlyLoginError(error)); + } + }; + + const handleFirstAccess = async () => { + if (novaSenha !== confirmacaoSenha) { + setErro("A confirmação não corresponde à nova senha."); + return; + } + + // Client-side validation mirrors the backend's password policy to give + // instant feedback — the backend still validates independently. + const passwordIsValid = + novaSenha.length >= 14 && + /[A-Z]/.test(novaSenha) && + /[0-9]/.test(novaSenha) && + /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(novaSenha); + + if (!passwordIsValid) { + setErro(PASSWORD_REQUIREMENTS); + return; + } + + const username = usuario.trim(); + + try { + await apiFetch("/auth/first-access", { + method: "POST", + body: JSON.stringify({ + username, + currentPassword: senha, + newPassword: novaSenha, + }), + }); + // Immediately log in with the new password — avoids a second manual login. + await authenticate(username, novaSenha); + } catch (error: unknown) { + setErro(friendlyLoginError(error)); + } + }; + + const handleSubmit = async (event: FormEvent) => { + event.preventDefault(); + setErro(""); + setCarregando(true); + + try { + if (primeiroAcesso) { + await handleFirstAccess(); + } else { + await handleLogin(); + } + } finally { + // Always clear loading state, even if navigation is in progress — + // prevents the button from staying disabled if the redirect is slow. + setCarregando(false); + } + }; + + const cancelFirstAccess = () => { + setPrimeiroAcesso(false); + setSenha(""); + setNovaSenha(""); + setConfirmacaoSenha(""); + setErro(""); + }; + + return ( +
+ {/* Decorative full-bleed background image — hidden on mobile to give the + login form more space. aria-hidden via empty alt. */} +
+ +
+
+ +
+
+ Logo WEG +
+ +
+

+ {primeiroAcesso ? "Primeiro acesso" : "Login"} +

+ +
+ + {erro && ( +
+ {erro} +
+ )} + + {/* Mock auth hint — only shown in non-production environments where + IS_MOCK_AUTH_ENABLED is true, to guide developers. */} + {IS_MOCK_AUTH_ENABLED && !primeiroAcesso && ( +
+

Acesso de contingência

+

+ Usuário: {MOCK_AUTH_CREDENTIALS.username} +

+

+ Senha: {MOCK_AUTH_CREDENTIALS.password} +

+

+ Permite navegar como administrador sem consultar a API. +

+
+ )} + +
+
+ + setUsuario(event.target.value)} + required + // Locked during first-access flow — username was already accepted. + disabled={primeiroAcesso || carregando} + className="w-full text-[16px] font-medium rounded-xl border border-primary-600 bg-background px-4 py-5 outline-none transition focus:border-primary-800 focus:bg-accent" + /> +
+ + {!primeiroAcesso && ( +
+ + setSenha(event.target.value)} + required + disabled={carregando} + className="w-full mb-5 text-[16px] font-medium rounded-xl border border-primary-600 bg-background px-4 py-5 outline-none transition focus:border-primary-800 focus:bg-accent" + /> +
+ )} + + {primeiroAcesso && ( + <> +
+ + setNovaSenha(event.target.value)} + required + disabled={carregando} + className="w-full rounded-xl border border-primary-600 bg-background px-4 py-5 text-[16px] font-medium" + /> +
+ +
+ + setConfirmacaoSenha(event.target.value)} + required + disabled={carregando} + className="w-full rounded-xl border border-primary-600 bg-background px-4 py-5 text-[16px] font-medium" + /> +
+ +

+ {PASSWORD_REQUIREMENTS} +

+ + )} + + + + {primeiroAcesso && ( + + )} +
+
+
+
+ ); +} diff --git a/my-app/src/app/manager/interviews/page.tsx b/my-app/src/app/manager/interviews/page.tsx new file mode 100644 index 0000000..37893c7 --- /dev/null +++ b/my-app/src/app/manager/interviews/page.tsx @@ -0,0 +1,305 @@ +"use client"; + +import { useCallback, useEffect, useMemo, useState } from "react"; +import Link from "next/link"; +import { + CalendarClock, + Mail, + MapPin, + Plus, + RefreshCw, + UserRound, +} from "lucide-react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { Button, buttonVariants } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { cn } from "@/lib/utils"; +import { + getInterviews, + getStudents, + sendInterviewEmail, + type Interview, + type Student, +} from "@/lib/manager-api"; + +export default function ManagerInterviewsPage() { + const [interviews, setInterviews] = useState([]); + const [students, setStudents] = useState([]); + const [search, setSearch] = useState(""); + const [loading, setLoading] = useState(true); + const [sendingId, setSendingId] = useState(null); + const [error, setError] = useState(""); + const [notice, setNotice] = useState(""); + const [referenceTime] = useState(() => Date.now()); + + // Mantém a ordenação e a atualização de estado iguais na carga inicial e + // nas atualizações solicitadas pelo gestor. + const applyData = useCallback( + (interviewData: Interview[], studentData: Student[]) => { + setInterviews( + [...interviewData].sort( + (first, second) => + new Date(first.dateTime).getTime() - + new Date(second.dateTime).getTime() + ) + ); + setStudents(studentData); + }, + [] + ); + + const loadData = useCallback(async () => { + setLoading(true); + setError(""); + + try { + const [interviewData, studentData] = await Promise.all([ + getInterviews(), + getStudents(), + ]); + + applyData(interviewData, studentData); + } catch (requestError) { + setError( + requestError instanceof Error + ? requestError.message + : "Não foi possível carregar as entrevistas." + ); + } finally { + setLoading(false); + } + }, [applyData]); + + useEffect(() => { + let active = true; + + // O carregamento inicial atualiza o estado somente após a resposta da API, + // respeitando a regra de efeitos do React e evitando atualização após unmount. + Promise.all([getInterviews(), getStudents()]) + .then(([interviewData, studentData]) => { + if (active) applyData(interviewData, studentData); + }) + .catch((requestError) => { + if (!active) return; + setError( + requestError instanceof Error + ? requestError.message + : "Não foi possível carregar as entrevistas." + ); + }) + .finally(() => { + if (active) setLoading(false); + }); + + return () => { + active = false; + }; + }, [applyData]); + + const filteredInterviews = useMemo(() => { + const query = search.trim().toLocaleLowerCase("pt-BR"); + if (!query) return interviews; + + return interviews.filter((interview) => + [ + interview.nameStudent, + interview.nameManager, + interview.interviewerName, + interview.park, + interview.section, + ] + .join(" ") + .toLocaleLowerCase("pt-BR") + .includes(query) + ); + }, [interviews, search]); + + const handleSendInvitation = async (interview: Interview) => { + // A entrevista retorna o nome do aluno, enquanto o endpoint de envio exige + // o e-mail. Relacionamos os dados já carregados antes de chamar a API. + const student = students.find( + (item) => item.name === interview.nameStudent + ); + + if (!student) { + setError("Não foi possível localizar o e-mail do aluno desta entrevista."); + return; + } + + setSendingId(interview.id); + setError(""); + setNotice(""); + + try { + await sendInterviewEmail(interview.id, student.email); + setNotice(`Convite enviado para ${student.email}.`); + } catch (requestError) { + setError( + requestError instanceof Error + ? requestError.message + : "Não foi possível enviar o convite." + ); + } finally { + setSendingId(null); + } + }; + + const upcomingInterviews = interviews.filter( + (interview) => new Date(interview.dateTime).getTime() >= referenceTime + ).length; + + return ( + +
+ + + + + Agendar pela vaga + +
+ } + /> + + {error && ( +
+ {error} +
+ )} + + {notice && ( +
+ {notice} +
+ )} + +
+ setSearch(event.target.value)} + placeholder="Buscar por aluno, gestor ou local..." + /> +
+ + {loading ? ( +
+ Carregando entrevistas... +
+ ) : filteredInterviews.length === 0 ? ( +
+ +

+ Nenhuma entrevista encontrada +

+
+ ) : ( +
+ {filteredInterviews.map((interview) => { + const date = new Date(interview.dateTime); + const isPast = date.getTime() < referenceTime; + + return ( +
+
+
+ +
+ +
+
+

+ {interview.nameStudent} +

+ + {isPast ? "Realizada" : "Agendada"} + +
+ +

+ {date.toLocaleDateString("pt-BR", { + dateStyle: "long", + })}{" "} + às{" "} + {date.toLocaleTimeString("pt-BR", { + hour: "2-digit", + minute: "2-digit", + })} +

+ +
+ + + {interview.park} · {interview.section} + + + + {interview.nameManager} + +
+
+
+ + +
+ ); + })} +
+ )} +
+ + ); +} diff --git a/my-app/src/app/manager/locations/page.tsx b/my-app/src/app/manager/locations/page.tsx new file mode 100644 index 0000000..de0fcb4 --- /dev/null +++ b/my-app/src/app/manager/locations/page.tsx @@ -0,0 +1,5 @@ +import { redirect } from "next/navigation"; + +export default function LegacyManagerLocationsPage() { + redirect("/manager/vacancies"); +} diff --git a/my-app/src/app/manager/students/[id]/page.tsx b/my-app/src/app/manager/students/[id]/page.tsx new file mode 100644 index 0000000..102f5a3 --- /dev/null +++ b/my-app/src/app/manager/students/[id]/page.tsx @@ -0,0 +1,107 @@ +"use client"; + +import { use, useEffect, useState } from "react"; +import Link from "next/link"; +import { ArrowLeft, Award, Mail } from "lucide-react"; + +import { AppShell, PageHeader } from "@/components/layout"; +import { Avatar, AvatarFallback } from "@/components/ui/avatar"; +import { Badge } from "@/components/ui/badge"; +import { buttonVariants } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Progress } from "@/components/ui/progress"; +import { getAppStudents } from "@/lib/application-api"; +import { cn } from "@/lib/utils"; +import type { StudentDTO } from "@/types"; + +interface PageProps { + params: Promise<{ id: string }>; +} + +export default function ManagerStudentDetailsPage({ params }: PageProps) { + const { id } = use(params); + const [student, setStudent] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(""); + + useEffect(() => { + let active = true; + getAppStudents() + .then((students) => { + if (!active) return; + const found = students.find((item) => item.id === id); + if (found) setStudent(found); + else setError("Aluno não encontrado."); + }) + .catch((loadError) => { + if (active) { + setError(loadError instanceof Error ? loadError.message : "Não foi possível carregar o aluno."); + } + }) + .finally(() => { + if (active) setLoading(false); + }); + return () => { + active = false; + }; + }, [id]); + + if (loading) { + return

Carregando aluno...

; + } + + if (!student) { + return ( + +
+ {error || "Aluno não encontrado."} +
+ + Voltar + +
+ ); + } + + const initials = student.name.split(" ").map((part) => part[0]).slice(0, 2).join(""); + + return ( + +
+ + Voltar + + } + /> + + + + + {initials} + + {student.name} +
{student.status === "ACTIVE" ? "Ativo" : student.status === "COMPLETED" ? "Concluído" : "Pausado"}
+
+ +
{student.email}
+
{student.courseName} · {student.className}
+
+
+ Média de desempenho + {student.performanceGrade == null ? "Não informada" : `${student.performanceGrade} / 10`} +
+ {student.performanceGrade != null && } +
+

+ Habilidades, frequência e histórico não são retornados neste endpoint da API. +

+
+
+
+
+ ); +} diff --git a/my-app/src/app/manager/students/page.tsx b/my-app/src/app/manager/students/page.tsx new file mode 100644 index 0000000..f869718 --- /dev/null +++ b/my-app/src/app/manager/students/page.tsx @@ -0,0 +1,129 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { AppShell, PageHeader } from "@/components/layout"; +import { DataTable, type DataTableColumn } from "@/components/shared/data-table"; +import { Badge } from "@/components/ui/badge"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { buttonVariants } from "@/components/ui/button"; +import type { StudentDTO } from "@/types"; +import Link from "next/link"; +import { Eye } from "lucide-react"; +import { cn } from "@/lib/utils"; +import { getStudents } from '@/lib/manager-api'; + +export default function ManagerStudentsPage() { + const [students, setStudents] = useState([]); + const [error, setError] = useState(''); + + useEffect(() => { + getStudents().then((data) => { + setStudents(data.map((student) => ({ + id: student.id, + name: student.name, + registration: student.acronym, + email: student.email, + courseName: student.course, + className: student.course, + status: 'ACTIVE', + performanceGrade: student.averageGrade, + }))); + }).catch((loadError) => setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar os alunos.')); + }, []); + + const columns: DataTableColumn[] = [ + { + key: "name", + header: "Aluno", + sortable: true, + render: (student) => { + const initials = student.name + .split(" ") + .map((n) => n[0]) + .slice(0, 2) + .join(""); + return ( +
+ + + + {initials} + + +
+
+

{student.name}

+
+

Matrícula: {student.registration}

+
+
+ ); + }, + }, + { + key: "courseName", + header: "Curso / Turma", + render: (student) => ( +
+

{student.courseName}

+

{student.className}

+
+ ), + }, + { + key: "attendanceRate", + header: "Frequência", + sortable: true, + render: (student) => ( + + {student.attendanceRate == null ? "Não informado" : `${student.attendanceRate}%`} + + ), + }, + { + key: "status", + header: "Status", + render: (student) => { + if (student.status === "ACTIVE") return Disponível; + return Em Análise; + }, + }, + { + key: "actions", + header: "Ações", + className: "text-right", + render: (student) => ( + + Ver Perfil + + ), + }, + ]; + + return ( + +
+ + + {error &&
{error}
} +
+ row.id} + /> +
+
+
+ ); +} diff --git a/my-app/src/app/manager/vacancies/[id]/page.tsx b/my-app/src/app/manager/vacancies/[id]/page.tsx new file mode 100644 index 0000000..fb35ebc --- /dev/null +++ b/my-app/src/app/manager/vacancies/[id]/page.tsx @@ -0,0 +1,653 @@ +"use client"; + +import { use, useEffect, useState } from "react"; +import { AppShell } from "@/components/layout"; +import { Input } from "@/components/ui/input"; +import { Slider } from "@/components/ui/slider"; +import { Switch } from "@/components/ui/switch"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Search, Ban } from "lucide-react"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { InterviewSchedulingModal } from "@/components/features/manager/interview-scheduling-modal"; +import { + createInterview, + areaLabels, + shiftLabels, + getManagers, + getPlaces, + getStudents, + getVacancy, + getVacancyRequirements, + updateVacancy, + type Manager, + type Place, + type VacancyArea, + type VacancyShift, + type VacancyRequirement, +} from '@/lib/manager-api'; + +interface Candidate { + id: string; + name: string; + classGroup: string; + matchPercentage?: number; + email?: string; + avatarUrl?: string; +} + +import { USER_ID_COOKIE_NAME } from '@/lib/auth'; + +function currentUserId() { + if (typeof document === 'undefined') return undefined; + const match = document.cookie.match(new RegExp(`(?:^|;\\s*)${USER_ID_COOKIE_NAME}=([^;]*)`)); + return match ? decodeURIComponent(match[1]) : undefined; +} + +interface PageProps { + params: Promise<{ id: string }>; +} + +export default function ManagerVacancyDetailPage({ params }: PageProps) { + const resolvedParams = use(params); + const router = useRouter(); + + const [jobTitle, setJobTitle] = useState("Analista de Dados Sênior"); + const [department, setDepartment] = useState("Tecnologia da Informação"); + const [description, setDescription] = useState( + "Responsável por analisar grandes volumes de dados industriais, gerar relatórios de eficiência e propor otimizações em processos fabris." + ); + const [spots, setSpots] = useState(0); + const [candidateSearch, setCandidateSearch] = useState(""); + const [candidates, setCandidates] = useState([]); + const [places, setPlaces] = useState([]); + const [managers, setManagers] = useState([]); + const [placeId, setPlaceId] = useState(""); + const [shift, setShift] = useState('FIRST'); + const [area, setArea] = useState('IT'); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(""); + + const [req1Level, setReq1Level] = useState(8); + const [req1Priority, setReq1Priority] = useState(true); + + const [req2Level, setReq2Level] = useState(7); + const [req2Priority, setReq2Priority] = useState(false); + const [extraRequirements, setExtraRequirements] = useState([]); + + // Modo de visualização (somente leitura por padrão) vs modo de edição + const [isViewMode, setIsViewMode] = useState(true); + + // Suporta múltiplos alunos alocados respeitando o limite de vagas (spots) + const [assignedStudentIds, setAssignedStudentIds] = useState([]); + const [rejectedStudentIds, setRejectedStudentIds] = useState([]); + const isEditing = resolvedParams.id !== "new" && resolvedParams.id !== "vac-new"; + + // Estado do Modal de Agendamento de Entrevista e Notificações + const [isModalOpen, setIsModalOpen] = useState(false); + const [selectedCandidate, setSelectedCandidate] = useState(null); + const [interviewSuccessMessage, setInterviewSuccessMessage] = useState(""); + + useEffect(() => { + let active = true; + Promise.all([ + getVacancy(resolvedParams.id), + getStudents(), + getPlaces(), + getManagers(), + getVacancyRequirements(resolvedParams.id), + ]).then(([vacancy, studentData, placeData, managerData, requirements]) => { + if (!active) return; + setJobTitle(vacancy.name); + setDepartment(areaLabels[vacancy.area] ?? vacancy.area); + setArea(vacancy.area as VacancyArea); + setDescription(vacancy.description); + setSpots(vacancy.numbersVacancies); + setShift(vacancy.shift as VacancyShift); + setPlaces(placeData); + const authenticatedManager = managerData.find((manager) => manager.id === currentUserId()); + setManagers(authenticatedManager ? [authenticatedManager] : []); + const technical = requirements.find((item) => item.id === 'python'); + const socioemotional = requirements.find((item) => item.id === 'problem-solving'); + if (technical) { + setReq1Level(technical.level); + setReq1Priority(technical.priority); + } + if (socioemotional) { + setReq2Level(socioemotional.level); + setReq2Priority(socioemotional.priority); + } + setExtraRequirements(requirements.filter((item) => item.id !== 'python' && item.id !== 'problem-solving')); + const selectedPlace = placeData.find( + (item) => item.park === vacancy.park && item.section === vacancy.section + ); + setPlaceId(selectedPlace?.id ?? placeData[0]?.id ?? ''); + setCandidates(studentData.map((student) => ({ + id: student.id, + name: student.name, + email: student.email, + classGroup: student.course, + matchPercentage: student.averageGrade == null + ? undefined + : Math.round(student.averageGrade * 10), + }))); + setAssignedStudentIds([]); + setRejectedStudentIds([]); + }).catch((loadError) => { + if (active) setError(loadError instanceof Error ? loadError.message : 'Não foi possível carregar a vaga.'); + }).finally(() => { + if (active) setLoading(false); + }); + return () => { active = false; }; + }, [resolvedParams.id]); + + const handleOpenInterviewModal = (candidate?: Candidate) => { + if (candidate) setSelectedCandidate(candidate); + setIsModalOpen(true); + }; + + const handleConfirmInterview = async (data: { date: string; time: string; vacancyId: string }) => { + if (!selectedCandidate) throw new Error('Selecione um candidato.'); + if (!managers[0]) throw new Error('Não foi possível identificar o gestor autenticado.'); + await createInterview({ + interviewerName: managers[0].name, + dateTime: `${data.date}T${data.time}:00`, + placeId, + studentId: selectedCandidate.id, + managerId: managers[0].id, + vacancyId: resolvedParams.id, + }); + setInterviewSuccessMessage( + `Entrevista agendada com sucesso para ${selectedCandidate?.name} no dia ${data.date} às ${data.time}.` + ); + setTimeout(() => setInterviewSuccessMessage(""), 6000); + }; + + const handleSaveVacancy = async () => { + setError(''); + try { + await updateVacancy(resolvedParams.id, { + name: jobTitle.trim(), + description: description.trim(), + numbersVacancies: spots, + area, + shift, + placeId, + }); + setIsViewMode(true); + } catch (saveError) { + setError(saveError instanceof Error ? saveError.message : 'Não foi possível atualizar a vaga.'); + return; + } + setInterviewSuccessMessage( + isEditing ? "Alterações da vaga salvas com sucesso!" : "Vaga criada com sucesso!" + ); + setTimeout(() => setInterviewSuccessMessage(""), 5000); + }; + + const handleAssignStudent = (candidate: Candidate, e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + setError( + `Não é possível alocar ${candidate.name}: a API não informa a qual vaga o aluno está associado. A ação foi bloqueada para evitar um vínculo global incorreto.` + ); + }; + + const handleRejectCandidate = (candidate: Candidate, e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + setError( + `Não é possível recusar ${candidate.name} nesta vaga: a API só permite alterar o status global do aluno.` + ); + }; + + const filteredCandidates = candidates.filter((c) => + c.name.toLowerCase().includes(candidateSearch.toLowerCase()) + ); + + return ( + +
+ {loading && ( +
+ Carregando dados da vaga... +
+ )} + {error && ( +
+ {error} +
+ )} + {/* Cabeçalho da Vaga */} +
+
+

+ {isEditing ? jobTitle : "Criar Nova Vaga"} +

+

+ {isViewMode + ? "Visualização da vaga. Clique em \"Editar Vaga\" para realizar alterações." + : isEditing + ? "Atualize as informações e requisitos da vaga para ajustar o perfil recomendado" + : "Preencha os campos abaixo para disponibilizar uma nova vaga para os alunos"} +

+
+ +
+ {isViewMode ? ( + + ) : ( + <> + + + + )} +
+
+ +
+ {/* Formulário Esquerdo - Detalhes da Vaga */} +
+ {/* Bloco 1: Informações Básicas */} +
+

Informações Básicas

+ +
+
+ + setJobTitle(e.target.value)} + disabled={isViewMode} + className="h-10 bg-white border-slate-200 rounded-lg text-sm font-medium" + /> +
+ +
+ + +
+
+ +
+ +