From 5d891f345bcadce27e9c26fead066f7b0b4f3c58 Mon Sep 17 00:00:00 2001 From: Pedro Ferreira Date: Thu, 25 Sep 2025 20:02:37 -0300 Subject: [PATCH 01/20] fix: problemas de dependencia e compatibilide das dependencias MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit airbyte_cdk acusando falta de arquivos necessários e httpx gera conflito com o airbyte:latest --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index f518f5a..271ff40 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -airbyte==0.25.1 +airbyte==0.31.3 FastAPI==0.115.9 uvicorn==0.34.3 psycopg2-binary==2.9.10 @@ -13,7 +13,7 @@ pytest==7.4.0 pytest-asyncio==0.21.1 pytest-mock==3.12.0 pytest-cov==4.1.0 -httpx==0.24.1 +httpx requests-mock==1.11.0 torch>=2.2.0,<2.8.0 From 74e19af999339bf84cd2d0cbb7d90027e4d09816 Mon Sep 17 00:00:00 2001 From: Livia Hombre <152039280+liviahombre@users.noreply.github.com> Date: Wed, 1 Oct 2025 06:49:14 -0300 Subject: [PATCH 02/20] =?UTF-8?q?docs:=20cria=C3=A7=C3=A3o=20de=20backlog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backlog.md | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 backlog.md diff --git a/backlog.md b/backlog.md new file mode 100644 index 0000000..31e45e5 --- /dev/null +++ b/backlog.md @@ -0,0 +1,108 @@ +## Backlog de Features + +### Feature 1: Autenticação de Usuário e Controle de Acesso + +- **Descrição (PT):** Desenvolvimento completo do subsistema de autenticação. Deve incluir **Registro** e **Login** seguro de usuários. Implementação de **Controle de Acesso (ACL)** para que cada usuário possa **apenas visualizar e gerenciar seus próprios repositórios e dados**. Este é o alicerce de segurança do sistema. +- **Prioridade:** Alta (Essencial para segurança e personalização) +- **Estimativa de Complexidade:** Alta +- **Status:** To Do + +--- + +### Feature 2: Gerenciamento Dinâmico de Token + +- **Descrição (PT):** Criação de uma funcionalidade direta na interface do usuário (UI) que permita ao usuário **inserir, visualizar (parcialmente) e atualizar o token de acesso** ao repositório (ex: GitHub Token). Essa gestão deve ser feita de forma segura e imediata, **eliminando a necessidade de configuração manual em arquivos** ou no backend. +- **Prioridade:** Média +- **Estimativa de Complexidade:** Baixa +- **Status:** To Do + +--- + +### Feature 3: Memória Contextual com LangChain + +- **Descrição (PT):** Implementação de uma **camada de memória** nas interações com a IA, utilizando a biblioteca **LangChain**. O objetivo é que a IA consiga **lembrar e referenciar informações de interações anteriores** na mesma conversa, permitindo um fluxo de diálogo contínuo, coerente e com contexto mantido. +- **Prioridade:** Alta (Core do valor da IA) +- **Estimativa de Complexidade:** Alta +- **Status:** To Do + +--- + +### Feature 5: Geração de Gráficos e Visualização de Dados + +- **Descrição (PT):** Capacidade de o sistema **responder a interações do usuário gerando gráficos (charts)**. Deve ser integrada a bibliotecas de visualização (ex: Matplotlib/Pandas) para renderizar e exibir dados estruturados de forma visual e analítica diretamente na interface do chat. +- **Prioridade:** Média +- **Estimativa de Complexidade:** Média +- **Status:** To Do + +--- + +### Feature 6: Design de Frontend e Usabilidade (UX) + +- **Descrição (PT):** Criação e implementação de uma **Interface de Usuário (UI) responsiva** e moderna, garantindo excelente experiência em desktop e dispositivos móveis. **Melhoria da UX** para que a aplicação (especialmente containers Docker) possa ser iniciada com **mínima ou nenhuma configuração manual**. +- **Prioridade:** Média +- **Estimativa de Complexidade:** Média +- **Status:** To Do + +--- + +### Feature 7: Padronização de Respostas da IA + +- **Descrição (PT):** Definição e implementação de um **sistema de controle de parâmetros** (como 'temperature', 'top\_p' e 'estilo/formato de saída') para garantir que as respostas da IA sejam **consistentes, previsíveis e adequadas ao contexto técnico**. Isso garante a confiabilidade das respostas. +- **Prioridade:** Baixa +- **Estimativa de Complexidade:** Baixa +- **Status:** To Do + +--- + +## Planejamento de Sprints + +### Sprint 1: Kickoff e Entregas Rápidas (01/10/2025 -- 07/10/2025) + +*Foco na configuração inicial e entrega das funcionalidades mais simples (Baixa Complexidade).* + +- **Issue:** Feature 7 - Padronização de Respostas da IA +- **Issue:** Feature 2 - Gerenciamento Dinâmico de Token + +--- + +### Sprint 2: Interface Inicial e Usabilidade (08/10/2025 -- 21/10/2025) + +*Foco na primeira parte do Frontend e na melhoria da experiência de uso inicial.* + +- **Issue:** Feature 6 (Parte 1) - Implementação da UI Responsiva e Estrutura Básica do Frontend + +--- + +### Sprint 3: Fechamento da Entrega 1 (22/10/2025 -- 31/10/2025) + +*Foco na entrega de valor analítico e na conclusão da UX. **Garante a conclusão antes de 02/11/2025.*** + +- **Issue:** Feature 5 - Geração de Gráficos e Visualização de Dados +- **Issue:** Feature 6 (Parte 2) - Configuração de Containers Prontos para Uso + +--- + +### Sprint 4: O Core da IA - Memória (03/11/2025 -- 16/11/2025) + +*Foco na feature mais importante para a qualidade das conversas da IA (Alta Complexidade).* + +- **Issue:** Feature 3 - Memória Contextual com LangChain + +--- + +### Sprint 5: Segurança e Personalização (17/11/2025 -- 30/11/2025) + +*Foco na conclusão do projeto com a entrega da funcionalidade de segurança e personalização. **Garante a conclusão na data de 30/11/2025.*** + +- **Issue:** Feature 1 - Autenticação de Usuário e Controle de Acesso + +--- + +## Marcos de Grandes Entregas (Milestones) + +Esta seção resume o que será entregue em cada um dos marcos cruciais do projeto: + +| Data da Entrega | Sprint de Conclusão | Features Entregues (Escopo) | +| :--- | :--- | :--- | +| **02/11/2025** | Sprint 3 | Todas as funcionalidades de **Baixa e Média Complexidade** e a **Estrutura Básica do Produto** estarão prontas. Isso inclui: Padronização da IA (F7), Gerenciamento de Token (F2), UI Responsiva (F6-p1), Geração de Gráficos (F5) e Containers Prontos (F6-p2). | +| **30/11/2025** | Sprint 5 | O **Produto Completo** será entregue. As funcionalidades de **Alta Complexidade** estarão finalizadas, incluindo: Memória Contextual (F3) e Autenticação/Controle de Acesso (F1). | From 29a174dfa8fd14afb5fb1eeed3ae4bbd15144e88 Mon Sep 17 00:00:00 2001 From: Livia Hombre <152039280+liviahombre@users.noreply.github.com> Date: Thu, 2 Oct 2025 08:32:05 -0300 Subject: [PATCH 03/20] =?UTF-8?q?docs:=20altera=C3=A7=C3=B5es=20backlog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backlog.md | 71 ++++++++++++++++++------------------------------------ 1 file changed, 24 insertions(+), 47 deletions(-) diff --git a/backlog.md b/backlog.md index 31e45e5..0cbfc53 100644 --- a/backlog.md +++ b/backlog.md @@ -1,34 +1,30 @@ ## Backlog de Features ### Feature 1: Autenticação de Usuário e Controle de Acesso - - **Descrição (PT):** Desenvolvimento completo do subsistema de autenticação. Deve incluir **Registro** e **Login** seguro de usuários. Implementação de **Controle de Acesso (ACL)** para que cada usuário possa **apenas visualizar e gerenciar seus próprios repositórios e dados**. Este é o alicerce de segurança do sistema. -- **Prioridade:** Alta (Essencial para segurança e personalização) +- **Prioridade:** Alta - **Estimativa de Complexidade:** Alta - **Status:** To Do --- ### Feature 2: Gerenciamento Dinâmico de Token - - **Descrição (PT):** Criação de uma funcionalidade direta na interface do usuário (UI) que permita ao usuário **inserir, visualizar (parcialmente) e atualizar o token de acesso** ao repositório (ex: GitHub Token). Essa gestão deve ser feita de forma segura e imediata, **eliminando a necessidade de configuração manual em arquivos** ou no backend. - **Prioridade:** Média -- **Estimativa de Complexidade:** Baixa +- **Estimativa de Complexidade:** Alta - **Status:** To Do --- ### Feature 3: Memória Contextual com LangChain - - **Descrição (PT):** Implementação de uma **camada de memória** nas interações com a IA, utilizando a biblioteca **LangChain**. O objetivo é que a IA consiga **lembrar e referenciar informações de interações anteriores** na mesma conversa, permitindo um fluxo de diálogo contínuo, coerente e com contexto mantido. -- **Prioridade:** Alta (Core do valor da IA) -- **Estimativa de Complexidade:** Alta +- **Prioridade:** Alta +- **Estimativa de Complexidade:** Média - **Status:** To Do --- -### Feature 5: Geração de Gráficos e Visualização de Dados - +### Feature 4: Geração de Gráficos e Visualização de Dados - **Descrição (PT):** Capacidade de o sistema **responder a interações do usuário gerando gráficos (charts)**. Deve ser integrada a bibliotecas de visualização (ex: Matplotlib/Pandas) para renderizar e exibir dados estruturados de forma visual e analítica diretamente na interface do chat. - **Prioridade:** Média - **Estimativa de Complexidade:** Média @@ -36,18 +32,16 @@ --- -### Feature 6: Design de Frontend e Usabilidade (UX) - +### Feature 5: Design de Frontend e Usabilidade (UX) - **Descrição (PT):** Criação e implementação de uma **Interface de Usuário (UI) responsiva** e moderna, garantindo excelente experiência em desktop e dispositivos móveis. **Melhoria da UX** para que a aplicação (especialmente containers Docker) possa ser iniciada com **mínima ou nenhuma configuração manual**. - **Prioridade:** Média -- **Estimativa de Complexidade:** Média +- **Estimativa de Complexidade:** Baixa - **Status:** To Do --- -### Feature 7: Padronização de Respostas da IA - -- **Descrição (PT):** Definição e implementação de um **sistema de controle de parâmetros** (como 'temperature', 'top\_p' e 'estilo/formato de saída') para garantir que as respostas da IA sejam **consistentes, previsíveis e adequadas ao contexto técnico**. Isso garante a confiabilidade das respostas. +### Feature 6: Padronização de Respostas da IA +- **Descrição (PT):** Definição e implementação de um **sistema de controle de parâmetros** (como 'temperature', 'top_p' e 'estilo/formato de saída') para garantir que as respostas da IA sejam **consistentes, previsíveis e adequadas ao contexto técnico**. Isso garante a confiabilidade das respostas. - **Prioridade:** Baixa - **Estimativa de Complexidade:** Baixa - **Status:** To Do @@ -56,53 +50,36 @@ ## Planejamento de Sprints -### Sprint 1: Kickoff e Entregas Rápidas (01/10/2025 -- 07/10/2025) - -*Foco na configuração inicial e entrega das funcionalidades mais simples (Baixa Complexidade).* - -- **Issue:** Feature 7 - Padronização de Respostas da IA -- **Issue:** Feature 2 - Gerenciamento Dinâmico de Token +### Sprint 1: **Base da IA e Respostas Consistentes** (02/10/2025 -- 08/10/2025) +- **Issue:** Feature 6 - Padronização de Respostas da IA --- -### Sprint 2: Interface Inicial e Usabilidade (08/10/2025 -- 21/10/2025) - -*Foco na primeira parte do Frontend e na melhoria da experiência de uso inicial.* - -- **Issue:** Feature 6 (Parte 1) - Implementação da UI Responsiva e Estrutura Básica do Frontend +### Sprint 2: **Primeiros Recursos Inteligentes** (09/10/2025 -- 22/10/2025) +- **Issue:** Feature 3 - Memória Contextual com LangChain +- **Issue:** Feature 4 - Geração de Gráficos e Visualização de Dados --- -### Sprint 3: Fechamento da Entrega 1 (22/10/2025 -- 31/10/2025) - -*Foco na entrega de valor analítico e na conclusão da UX. **Garante a conclusão antes de 02/11/2025.*** - -- **Issue:** Feature 5 - Geração de Gráficos e Visualização de Dados -- **Issue:** Feature 6 (Parte 2) - Configuração de Containers Prontos para Uso +### Sprint 3: **Experiência do Usuário e Interface** (23/10/2025 -- 31/10/2025) +- **Issue:** Feature 5 - Design de Frontend e Usabilidade (UX) --- -### Sprint 4: O Core da IA - Memória (03/11/2025 -- 16/11/2025) - -*Foco na feature mais importante para a qualidade das conversas da IA (Alta Complexidade).* - -- **Issue:** Feature 3 - Memória Contextual com LangChain +### Sprint 4: **Segurança e Integrações Críticas** (03/11/2025 -- 16/11/2025) +- **Issue:** Feature 1 - Autenticação de Usuário e Controle de Acesso +- **Issue:** Feature 2 - Gerenciamento Dinâmico de Token --- -### Sprint 5: Segurança e Personalização (17/11/2025 -- 30/11/2025) - -*Foco na conclusão do projeto com a entrega da funcionalidade de segurança e personalização. **Garante a conclusão na data de 30/11/2025.*** - -- **Issue:** Feature 1 - Autenticação de Usuário e Controle de Acesso +### Sprint 5: **Estabilização e Revisão Final** (17/11/2025 -- 30/11/2025) +- **Issue:** Revisão e correção de problemas das issues realizadas anteriormente --- ## Marcos de Grandes Entregas (Milestones) -Esta seção resume o que será entregue em cada um dos marcos cruciais do projeto: - -| Data da Entrega | Sprint de Conclusão | Features Entregues (Escopo) | +| Data da Entrega | Sprints Inclusas | Features Entregues (Escopo) | | :--- | :--- | :--- | -| **02/11/2025** | Sprint 3 | Todas as funcionalidades de **Baixa e Média Complexidade** e a **Estrutura Básica do Produto** estarão prontas. Isso inclui: Padronização da IA (F7), Gerenciamento de Token (F2), UI Responsiva (F6-p1), Geração de Gráficos (F5) e Containers Prontos (F6-p2). | -| **30/11/2025** | Sprint 5 | O **Produto Completo** será entregue. As funcionalidades de **Alta Complexidade** estarão finalizadas, incluindo: Memória Contextual (F3) e Autenticação/Controle de Acesso (F1). | +| **02/11/2025** | Sprint 1 + Sprint 2 | Funcionalidades de **Baixa e Média Complexidade** entregues: Padronização da IA (F6), Memória Contextual (F3) e Geração de Gráficos (F4). | +| **30/11/2025** | Sprint 3 + Sprint 4 + Sprint 5 | Funcionalidades de **Alta Complexidade** entregues: Design de Frontend e Usabilidade (F5), Autenticação/Controle de Acesso (F1) e Gerenciamento Dinâmico de Token (F2). Além disso, inclui o período de estabilização e revisão final (Sprint 5). | From 2fcc9bab2772712259b509232f03c7642263d78d Mon Sep 17 00:00:00 2001 From: Livia Hombre <152039280+liviahombre@users.noreply.github.com> Date: Thu, 2 Oct 2025 08:53:09 -0300 Subject: [PATCH 04/20] =?UTF-8?q?docs:=20altera=C3=A7=C3=B5es=20backlog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backlog.md | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/backlog.md b/backlog.md index 0cbfc53..627499c 100644 --- a/backlog.md +++ b/backlog.md @@ -48,31 +48,44 @@ --- -## Planejamento de Sprints +## Planejamento de Sprints (1 semana cada) -### Sprint 1: **Base da IA e Respostas Consistentes** (02/10/2025 -- 08/10/2025) -- **Issue:** Feature 6 - Padronização de Respostas da IA +### Sprint 1: **Memória Inicial com LangChain** (02/10/2025 -- 08/10/2025) +- **Issue:** Feature 3 - Memória Contextual com LangChain --- -### Sprint 2: **Primeiros Recursos Inteligentes** (09/10/2025 -- 22/10/2025) -- **Issue:** Feature 3 - Memória Contextual com LangChain +### Sprint 2: **Visualização e Gráficos** (09/10/2025 -- 15/10/2025) - **Issue:** Feature 4 - Geração de Gráficos e Visualização de Dados --- -### Sprint 3: **Experiência do Usuário e Interface** (23/10/2025 -- 31/10/2025) +### Sprint 3: **Padronização da IA - Parte 1** (16/10/2025 -- 22/10/2025) +- **Issue:** Feature 6 - Padronização de Respostas da IA (início) + +--- + +### Sprint 4: **Interface e UX** (23/10/2025 -- 29/10/2025) - **Issue:** Feature 5 - Design de Frontend e Usabilidade (UX) --- -### Sprint 4: **Segurança e Integrações Críticas** (03/11/2025 -- 16/11/2025) +### Sprint 5: **Autenticação Segura** (30/10/2025 -- 05/11/2025) - **Issue:** Feature 1 - Autenticação de Usuário e Controle de Acesso -- **Issue:** Feature 2 - Gerenciamento Dinâmico de Token --- -### Sprint 5: **Estabilização e Revisão Final** (17/11/2025 -- 30/11/2025) +### Sprint 6: **Gerenciamento de Token - Parte 1** (06/11/2025 -- 12/11/2025) +- **Issue:** Feature 2 - Gerenciamento Dinâmico de Token (início) + +--- + +### Sprint 7: **Gerenciamento de Token - Parte 2** (13/11/2025 -- 19/11/2025) +- **Issue:** Feature 2 - Gerenciamento Dinâmico de Token (finalização) + +--- + +### Sprint 8: **Estabilização e Revisão Final** (20/11/2025 -- 30/11/2025) - **Issue:** Revisão e correção de problemas das issues realizadas anteriormente --- @@ -81,5 +94,5 @@ | Data da Entrega | Sprints Inclusas | Features Entregues (Escopo) | | :--- | :--- | :--- | -| **02/11/2025** | Sprint 1 + Sprint 2 | Funcionalidades de **Baixa e Média Complexidade** entregues: Padronização da IA (F6), Memória Contextual (F3) e Geração de Gráficos (F4). | -| **30/11/2025** | Sprint 3 + Sprint 4 + Sprint 5 | Funcionalidades de **Alta Complexidade** entregues: Design de Frontend e Usabilidade (F5), Autenticação/Controle de Acesso (F1) e Gerenciamento Dinâmico de Token (F2). Além disso, inclui o período de estabilização e revisão final (Sprint 5). | +| **02/11/2025** | Sprint 1 + Sprint 2 + Sprint 3 | Funcionalidades iniciais entregues: Memória Contextual (F3), Geração de Gráficos (F4) e Padronização da IA - Parte 1 (F6). | +| **30/11/2025** | Sprint 4 + Sprint 5 + Sprint 6 + Sprint 7 + Sprint 8 | Funcionalidades finais entregues: Design de Frontend e Usabilidade (F5), Autenticação/Controle de Acesso (F1), Gerenciamento Dinâmico de Token (F2), e Estabilização/Revisão Final. | From 8b1dcce530c2a6d87ba7600c3d104a4e1a8d5f4d Mon Sep 17 00:00:00 2001 From: aliciacapo Date: Thu, 16 Oct 2025 14:59:00 -0300 Subject: [PATCH 05/20] retirando item desnecessario, adicionando treinamento --- src/api/controller/AskController.py | 16 +-- src/api/database/MyVanna.py | 185 +++++++++++++++++++++++++--- 2 files changed, 174 insertions(+), 27 deletions(-) diff --git a/src/api/controller/AskController.py b/src/api/controller/AskController.py index 2bc33a9..154aefc 100644 --- a/src/api/controller/AskController.py +++ b/src/api/controller/AskController.py @@ -23,22 +23,16 @@ def __init__(self): self.vn.prepare() def ask(self, question: Question): - client = genai.Client(api_key=GEMINI_API_KEY) - - vn = MyVanna(config={ - 'print_prompt': False, - 'print_sql': False, - 'api_key': GEMINI_API_KEY, - 'model_name': GEMINI_MODEL_NAME - }) try: - sql_gerado = vn.generate_sql(question.question) + + + sql_gerado = self.vn.generate_sql(question.question) if "SELECT" not in sql_gerado.upper(): return {"output": "Não consegui entender sua pergunta bem o suficiente para gerar uma resposta SQL válida."} - resultado = vn.run_sql(sql_gerado) + resultado = self.vn.run_sql(sql_gerado) if not resultado: return {"output": "A consulta foi feita, mas não há dados correspondentes no banco."} @@ -54,7 +48,7 @@ def ask(self, question: Question): Gere uma resposta clara e útil para o usuário, explicando o que o resultado significa. """ - response = client.models.generate_content( + response = self.client.models.generate_content( model=GEMINI_MODEL_NAME, contents=prompt, config={ diff --git a/src/api/database/MyVanna.py b/src/api/database/MyVanna.py index 84c2e70..a21ab42 100644 --- a/src/api/database/MyVanna.py +++ b/src/api/database/MyVanna.py @@ -15,12 +15,61 @@ DB_PASSWORD = env["DB_PASSWORD"] DB_URL = env["DB_URL"] -class MyVanna(ChromaDB_VectorStore, GoogleGeminiChat): +class ChromaDB_VectorStoreReset(ChromaDB_VectorStore): def __init__(self, config=None): if config is None: config = {} - ChromaDB_VectorStore.__init__(self, config=config) + # Força o reset na inicialização + config["reset_on_init"] = config.get("reset_on_init", True) + + super().__init__(config=config) + + # Limpa as coleções após a inicialização padrão + if config["reset_on_init"]: + self._reset_collections() + + # Recria as coleções vazias + collection_metadata = config.get("collection_metadata", None) + self.documentation_collection = self.chroma_client.get_or_create_collection( + name="documentation", + embedding_function=self.embedding_function, + metadata=collection_metadata, + ) + self.ddl_collection = self.chroma_client.get_or_create_collection( + name="ddl", + embedding_function=self.embedding_function, + metadata=collection_metadata, + ) + self.sql_collection = self.chroma_client.get_or_create_collection( + name="sql", + embedding_function=self.embedding_function, + metadata=collection_metadata, + ) + + def _reset_collections(self): + """Limpa todas as coleções existentes""" + try: + self.chroma_client.delete_collection("documentation") + except Exception: + pass + + try: + self.chroma_client.delete_collection("ddl") + except Exception: + pass + + try: + self.chroma_client.delete_collection("sql") + except Exception: + pass + +class MyVanna(ChromaDB_VectorStoreReset, GoogleGeminiChat): + def __init__(self, config=None): + if config is None: + config = {} + + ChromaDB_VectorStoreReset.__init__(self, config=config) GEMINI_API_KEY = config.get('api_key') GEMINI_MODEL_NAME = config.get('model_name') @@ -123,32 +172,134 @@ def prepare(self): password = DB_PASSWORD ) - schema = self.get_schema() - - self.train(ddl=self.schema) + self.train(ddl=self.get_schema()) self.train(documentation=""" - A tabela repository armazena os repositórios, identificados por um ID único e nome. +Table: user_info + + id: Bigint primary key with default value from sequence + + login: Required username field (character varying) + + html_url: Required profile URL field (text) + +Table: milestone + + id: Bigint primary key with default value from sequence + + repository_id: Associated repository ID (integer, required) + + title: Milestone title (text, required) + + description: Milestone description (text, optional) + + number: Milestone number (integer, required) + + state: Milestone state (character varying, required) + + created_at: Creation timestamp with time zone + + updated_at: Update timestamp with time zone + + creator: Creator user ID (bigint, required) + +Table: repository + + id: Integer primary key with default value from sequence + + name: Repository name (character varying, required) + +Table: branch + + id: Bigint primary key with default value from sequence + + name: Branch name (character varying, required) + + repository_id: Associated repository ID (integer, required) + +Table: issue - A tabela user contém informações dos usuários, como login e URL de perfil. É usada como referência em outras tabelas, como quem criou issues, pull requests e milestones. + id: Bigint primary key with default value from sequence - A tabela milestone representa marcos definidos nos repositórios, contendo título, descrição, número, estado (aberta ou fechada), datas de criação e atualização, o repositório ao qual pertence e o usuário criador. + title: Issue title (text, required) - A tabela issue armazena tarefas ou bugs reportados. Contém título, corpo, número, autor, repositório, milestone relacionada, datas e URL. As atribuições de usuários a uma issue são registradas em issue_assignees. + body: Issue body/description (text, optional) - A tabela pull_requests armazena os pull requests criados nos repositórios. Inclui título, corpo, número, estado, criador, repositório, milestone (opcional), datas e URL. Os responsáveis são registrados em pull_request_assignees. + number: Issue number (integer, required) - A tabela branch armazena os nomes de branches de cada repositório. + html_url: Issue URL (text, optional) - A tabela commits armazena cada commit feito. Cada registro contém o SHA, mensagem, autor (usuário), repositório, branch (opcional), data de criação e URL. Também há referência à tabela de usuários. + created_at: Creation timestamp with time zone - A tabela parents_commits representa a relação entre commits e seus pais (para commits com múltiplos ancestrais, como em merges). Usa o SHA do commit pai e o ID do commit filho. + updated_at: Update timestamp with time zone - A tabela issue_assignees relaciona múltiplos usuários a uma mesma issue, representando atribuições de tarefas. É uma tabela de junção entre issues e usuários. + created_by: Creator user ID (bigint, required) - A tabela pull_request_assignees relaciona múltiplos usuários a um pull request, permitindo registrar quem é responsável por revisar ou aprovar um PR. + repository_id: Associated repository ID (bigint, required) - O modelo garante integridade por meio de chaves estrangeiras, e unicidade de registros por restrições compostas (como número + repositório para issues, pull requests e milestones). + milestone_id: Associated milestone ID (bigint, optional) + +Table: pull_requests + + id: Bigint primary key with default value from sequence + + created_by: Creator user ID (bigint, required) + + repository_id: Associated repository ID (integer, required) + + number: Pull request number (integer, required) + + state: Pull request state (character varying, required) + + title: Pull request title (text, required) + + body: Pull request body/description (text, optional) + + html_url: Pull request URL (text, required) + + created_at: Creation timestamp with time zone + + updated_at: Update timestamp with time zone + + milestone_id: Associated milestone ID (bigint, optional) + +Table: commits + + id: Bigint primary key with default value from sequence + + user_id: Author user ID (bigint, required) + + branch_id: Associated branch ID (integer, optional) + + pull_request_id: Associated pull request ID (bigint, optional) + + created_at: Creation timestamp with time zone + + message: Commit message (text, required) + + sha: Commit SHA hash (character varying, required) + + html_url: Commit URL (text, optional) + +Table: parents_commits + + id: Integer primary key with default value from sequence + + parent_sha: Parent commit SHA hash (character varying, required) + + commit_id: Child commit ID (integer, required) + +Table: issue_assignees + + issue_id: Issue ID (bigint, required, part of primary key) + + user_id: Assigned user ID (bigint, required, part of primary key) + +Table: pull_request_assignees + + pull_request_id: Pull request ID (bigint, required, part of primary key) + + user_id: Assigned user ID (bigint, required, part of primary key) """) self.train(sql=""" @@ -232,3 +383,5 @@ def prepare(self): ORDER BY total_commits DESC; """) + + From a93c2ab67e3795e95b56243c70c82480adfa07ad Mon Sep 17 00:00:00 2001 From: aliciacapo Date: Fri, 24 Oct 2025 19:54:28 -0300 Subject: [PATCH 06/20] ajustando requirements e adicionando lengchain basico --- requirements.txt | 4 +++- src/api/controller/AskController.py | 31 +++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 271ff40..27ad852 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,9 +5,11 @@ psycopg2-binary==2.9.10 python-dotenv==1.1.0 vanna==0.7.9 chromadb -google-generativeai==0.8.5 +google-genai google-cloud-aiplatform==1.96.0 onnxruntime==1.22.0 +langchain-google-genai<1.0.0 +langchain pytest==7.4.0 pytest-asyncio==0.21.1 diff --git a/src/api/controller/AskController.py b/src/api/controller/AskController.py index 154aefc..ba55acc 100644 --- a/src/api/controller/AskController.py +++ b/src/api/controller/AskController.py @@ -1,6 +1,8 @@ from src.assets.pattern.singleton import SingletonMeta from src.api.models import Question, Response +from langchain_google_genai import ChatGoogleGenerativeAI +from langchain.schema import SystemMessage, HumanMessage from google import genai from src.api.database.MyVanna import MyVanna @@ -13,6 +15,15 @@ class AskController(metaclass=SingletonMeta): def __init__(self): self.client = genai.Client(api_key=GEMINI_API_KEY) + self.gen = ChatGoogleGenerativeAI(model=GEMINI_MODEL_NAME, + google_api_key=GEMINI_API_KEY, + temperature=0, + max_tokens=None, + timeout=None, + max_retries=2, + convert_system_message_to_human=True + ) + self.vn = MyVanna(config={ 'print_prompt': False, 'print_sql': False, @@ -26,8 +37,23 @@ def ask(self, question: Question): try: - - sql_gerado = self.vn.generate_sql(question.question) + mensagem = [SystemMessage(content="""Você é um assistente em um sistema que de chat AI, + seu trabalho é receber uma mensagem de um humano e tratar ela para ser processada + por outra IA que possui falhas. Dentro dos tratamentos necessários estão: + -Trocar datas que são dadas em formato que não sejam dias, por exemplo 3 mêses, + e transformar em dias, 90 dias. Outro exemplo, 1 ano e 2 meses, trocar por 425 dias + (serão considerados que os mêses separados terão 30 dias) + -Quando usada a expressão "mudança" referente ao repositório, você trocara por "commit", + por exemplo, "qual foi a ultima mudança feita no repositório?" será trocado por + "qual foi o ultimo commit feito no repositório?) + NÃO explique, NÃO confirme, NÃO dê exemplos. Apenas RETORNE a mensagem tratada. + Mensagem a ser processada:"""),HumanMessage(content=question.question)] + + ai_mensagem = self.gen.invoke(mensagem) + + print(ai_mensagem.content) + + sql_gerado = self.vn.generate_sql(ai_mensagem.content) if "SELECT" not in sql_gerado.upper(): return {"output": "Não consegui entender sua pergunta bem o suficiente para gerar uma resposta SQL válida."} @@ -48,6 +74,7 @@ def ask(self, question: Question): Gere uma resposta clara e útil para o usuário, explicando o que o resultado significa. """ + response = self.client.models.generate_content( model=GEMINI_MODEL_NAME, contents=prompt, From 1d2919c57ca55da5a925b59a65ec3443033d996c Mon Sep 17 00:00:00 2001 From: Vitor Ramos Date: Wed, 29 Oct 2025 10:34:55 -0300 Subject: [PATCH 07/20] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20de=20contexto?= =?UTF-8?q?=20com=20langchain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example.env | 6 +- src/api/controller/AskController.py | 282 ++++++++++++++++++++++++---- 2 files changed, 249 insertions(+), 39 deletions(-) diff --git a/example.env b/example.env index bcee7a6..7476625 100644 --- a/example.env +++ b/example.env @@ -1,5 +1,5 @@ # Airbyte -GITHUB_TOKEN= +GITHUB_TOKEN= "" # Database credentials DB_HOST=db @@ -12,5 +12,5 @@ DB_PASSWORD=postgres DB_URL=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} # Google cloud gemini -GEMINI_API_KEY= -GEMINI_MODEL_NAME=gemini-2.0-flash \ No newline at end of file +GEMINI_API_KEY="" +GEMINI_MODEL_NAME=gemini-2.0-flash diff --git a/src/api/controller/AskController.py b/src/api/controller/AskController.py index ba55acc..0e63ce0 100644 --- a/src/api/controller/AskController.py +++ b/src/api/controller/AskController.py @@ -2,79 +2,178 @@ from src.api.models import Question, Response from langchain_google_genai import ChatGoogleGenerativeAI -from langchain.schema import SystemMessage, HumanMessage +from langchain.schema import SystemMessage, HumanMessage, AIMessage +from langchain.memory import ConversationBufferWindowMemory +from langchain.chains import LLMChain +from langchain.prompts import ( + ChatPromptTemplate, + MessagesPlaceholder, + SystemMessagePromptTemplate, + HumanMessagePromptTemplate, +) from google import genai from src.api.database.MyVanna import MyVanna +import json +from typing import Dict, Optional +import hashlib from src.assets.aux.env import env + # Gemini env vars GEMINI_API_KEY = env["GEMINI_API_KEY"] GEMINI_MODEL_NAME = env["GEMINI_MODEL_NAME"] + class AskController(metaclass=SingletonMeta): def __init__(self): self.client = genai.Client(api_key=GEMINI_API_KEY) - self.gen = ChatGoogleGenerativeAI(model=GEMINI_MODEL_NAME, + # LLM principal para geração de respostas + self.llm = ChatGoogleGenerativeAI( + model=GEMINI_MODEL_NAME, google_api_key=GEMINI_API_KEY, temperature=0, max_tokens=None, timeout=None, max_retries=2, convert_system_message_to_human=True - ) + ) + + # Memória conversacional (mantém últimas 5 interações) + self.memory = ConversationBufferWindowMemory( + k=5, # Número de interações a manter + memory_key="chat_history", + return_messages=True, + input_key="question", + output_key="answer" + ) + + # Chain para pré-processamento com contexto + self.preprocessing_chain = self._create_preprocessing_chain() + # instancia do vanna self.vn = MyVanna(config={ - 'print_prompt': False, + 'print_prompt': False, 'print_sql': False, 'api_key': GEMINI_API_KEY, 'model_name': GEMINI_MODEL_NAME }) - self.vn.prepare() - def ask(self, question: Question): + # Cache simples para queries SQL (em memória) + self.sql_cache: Dict[str, str] = {} + self.result_cache: Dict[str, any] = {} - try: + def _create_preprocessing_chain(self) -> LLMChain: + """Cria chain para pré-processar perguntas com contexto da conversa""" + + system_template = """Você é um assistente especializado em processar perguntas sobre dados do GitHub. + +Sua função é: +1. Analisar o histórico da conversa para entender o contexto +2. Resolver referências contextuais (ex: "e no mês passado?", "mostre mais detalhes", "e o outro repositório?") +3. Normalizar expressões temporais: + - "3 meses" → "90 dias" + - "1 ano e 2 meses" → "425 dias" + - Meses separados = 30 dias cada +4. Normalizar terminologia: + - "mudança" → "commit" + - "alteração" → "commit" +5. Expandir a pergunta com contexto necessário do histórico + +REGRAS CRÍTICAS: +- Se a pergunta fizer referência a algo anterior ("e aquele", "o outro", "também"), inclua o contexto explícito +- Se não houver referência contextual, retorne a pergunta apenas normalizada +- NÃO explique, NÃO confirme, NÃO dê exemplos +- Retorne APENAS a pergunta processada e expandida - mensagem = [SystemMessage(content="""Você é um assistente em um sistema que de chat AI, - seu trabalho é receber uma mensagem de um humano e tratar ela para ser processada - por outra IA que possui falhas. Dentro dos tratamentos necessários estão: - -Trocar datas que são dadas em formato que não sejam dias, por exemplo 3 mêses, - e transformar em dias, 90 dias. Outro exemplo, 1 ano e 2 meses, trocar por 425 dias - (serão considerados que os mêses separados terão 30 dias) - -Quando usada a expressão "mudança" referente ao repositório, você trocara por "commit", - por exemplo, "qual foi a ultima mudança feita no repositório?" será trocado por - "qual foi o ultimo commit feito no repositório?) - NÃO explique, NÃO confirme, NÃO dê exemplos. Apenas RETORNE a mensagem tratada. - Mensagem a ser processada:"""),HumanMessage(content=question.question)] +Histórico da conversa está disponível abaixo.""" - ai_mensagem = self.gen.invoke(mensagem) + prompt = ChatPromptTemplate.from_messages([ + SystemMessagePromptTemplate.from_template(system_template), + MessagesPlaceholder(variable_name="chat_history"), + HumanMessagePromptTemplate.from_template("{question}") + ]) - print(ai_mensagem.content) + return LLMChain( + llm=self.llm, + prompt=prompt, + memory=self.memory, + verbose=False + ) - sql_gerado = self.vn.generate_sql(ai_mensagem.content) + def _get_cache_key(self, text: str) -> str: + """Gera chave de cache baseada no hash da pergunta normalizada""" + normalized = text.lower().strip() + return hashlib.md5(normalized.encode()).hexdigest() - if "SELECT" not in sql_gerado.upper(): - return {"output": "Não consegui entender sua pergunta bem o suficiente para gerar uma resposta SQL válida."} + def _validate_sql(self, sql: str) -> tuple[bool, Optional[str]]: + """Valida SQL gerado para segurança""" + sql_upper = sql.upper().strip() + + # Whitelist: apenas SELECT permitido + if not sql_upper.startswith("SELECT"): + return False, "Apenas queries SELECT são permitidas" + + # Blacklist: operações perigosas + dangerous_keywords = [ + "DELETE", "DROP", "TRUNCATE", "INSERT", + "UPDATE", "ALTER", "CREATE", "GRANT", "REVOKE" + ] + + for keyword in dangerous_keywords: + if keyword in sql_upper: + return False, f"Operação '{keyword}' não é permitida" + + # Limite de complexidade (número de JOINs) + join_count = sql_upper.count("JOIN") + if join_count > 10: + return False, "Query muito complexa (máximo 10 JOINs)" + + return True, None - resultado = self.vn.run_sql(sql_gerado) + def _format_response_with_context(self, question: str, sql: str, result: any) -> str: + """Formata resposta final usando LLM com contexto conversacional""" + + # Recupera histórico da memória + memory_vars = self.memory.load_memory_variables({}) + chat_history = memory_vars.get("chat_history", []) + + # Monta contexto do histórico + history_context = "" + if chat_history: + history_context = "\n\nContexto da conversa anterior:\n" + for msg in chat_history[-3:]: # Últimas 3 mensagens + if isinstance(msg, HumanMessage): + history_context += f"Usuário: {msg.content}\n" + elif isinstance(msg, AIMessage): + history_context += f"Assistente: {msg.content}\n" - if not resultado: - return {"output": "A consulta foi feita, mas não há dados correspondentes no banco."} + prompt = f""" +Você é um assistente especializado em análise de dados do GitHub. - # Prompt mais informativo - prompt = f""" - Você é um assistente que responde perguntas sobre dados extraídos do GitHub. +{history_context} - Pergunta do usuário: "{question.question}" +Pergunta atual: "{question}" - Resultado da consulta SQL: {resultado} +SQL gerado e executado: +```sql +{sql} +``` - Gere uma resposta clara e útil para o usuário, explicando o que o resultado significa. - """ +Resultado da consulta: {result} +Com base no contexto da conversa e nos resultados, gere uma resposta: +1. Clara e direta +2. Em linguagem natural +3. Destacando insights relevantes +4. Relacionando com perguntas anteriores se aplicável +5. Formato estruturado se houver múltiplos dados +Responda de forma conversacional e útil. +""" + + try: response = self.client.models.generate_content( model=GEMINI_MODEL_NAME, contents=prompt, @@ -83,9 +182,120 @@ def ask(self, question: Question): "response_schema": list[Response], } ) + return response.parsed[0].texto + except Exception as e: + # Fallback para resposta simples + return f"Resultado: {result}" + + def ask(self, question: Question, session_id: Optional[str] = None) -> dict: + """ + Processa pergunta com contexto conversacional + + Args: + question: Objeto Question com a pergunta do usuário + session_id: ID da sessão para memória multi-usuário (futuro) + """ + + # --- Dentro de ask() --- + try: + original_question = question.question + + # Etapa 1: Pré-processar com contexto (usando chain) + processed_question = self.preprocessing_chain.invoke({ + "question": original_question + }) + if isinstance(processed_question, dict) and "text" in processed_question: + processed_question = processed_question["text"] + elif not isinstance(processed_question, str): + processed_question = str(processed_question) + + print(f"[Preprocessed] {processed_question}") + + # Etapa 2: Verificar cache de SQL + cache_key = self._get_cache_key(processed_question) + + if cache_key in self.sql_cache: + print(f"[Cache Hit] SQL encontrado no cache") + sql_gerado = self.sql_cache[cache_key] + else: + sql_gerado = self.vn.generate_sql(processed_question) + + is_valid, error_msg = self._validate_sql(sql_gerado) + if not is_valid: + return { + "output": f"Query inválida: {error_msg}", + "error": True + } + + self.sql_cache[cache_key] = sql_gerado + print(f"[Cache Miss] SQL gerado e armazenado") + + print(f"[SQL] {sql_gerado}") + + result_cache_key = hashlib.md5(sql_gerado.encode()).hexdigest() + + if result_cache_key in self.result_cache: + print(f"[Cache Hit] Resultado encontrado no cache") + resultado = self.result_cache[result_cache_key] + else: + resultado = self.vn.run_sql(sql_gerado) + if not resultado: + self.memory.save_context( + inputs={"question": original_question}, + outputs={"answer": "Não há dados correspondentes no banco."} + ) + return { + "output": "A consulta foi executada, mas não há dados correspondentes.", + "sql": sql_gerado + } + + self.result_cache[result_cache_key] = resultado + print(f"[Cache Miss] Resultado obtido e armazenado") + + resposta_formatada = self._format_response_with_context( + question=original_question, + sql=sql_gerado, + result=resultado + ) - texto = response.parsed[0].texto - return {"output": texto} + self.memory.save_context( + inputs={"question": original_question}, + outputs={"answer": resposta_formatada} + ) + + return { + "output": resposta_formatada, + "sql": sql_gerado, + "cached": result_cache_key in self.result_cache + } except Exception as e: - return {"output": f"Ocorreu um erro ao processar sua pergunta: {str(e)}"} \ No newline at end of file + error_msg = f"Erro ao processar pergunta: {str(e)}" + print(f"[Error] {error_msg}") + + self.memory.save_context( + inputs={"question": question.question}, + outputs={"answer": error_msg} + ) + + return { + "output": error_msg, + "error": True + } + + + def clear_memory(self): + """Limpa o histórico da conversa""" + self.memory.clear() + print("[Memory] Histórico limpo") + + def get_conversation_history(self) -> list: + """Retorna o histórico da conversa""" + memory_vars = self.memory.load_memory_variables({}) + return memory_vars.get("chat_history", []) + + def clear_cache(self): + """Limpa os caches de SQL e resultados""" + self.sql_cache.clear() + self.result_cache.clear() + print("[Cache] Caches limpos") \ No newline at end of file From ef6619ab4207a93e0096abdfd076d65a67053366 Mon Sep 17 00:00:00 2001 From: Vitor Ramos Date: Wed, 29 Oct 2025 16:37:14 -0300 Subject: [PATCH 08/20] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20de=20contexto?= =?UTF-8?q?=20e=20gerenciamento=20de=20token=20com=20langchain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/requirements.txt b/requirements.txt index 27ad852..00101b6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,25 +1,14 @@ -airbyte==0.31.3 -FastAPI==0.115.9 -uvicorn==0.34.3 -psycopg2-binary==2.9.10 -python-dotenv==1.1.0 -vanna==0.7.9 -chromadb -google-genai -google-cloud-aiplatform==1.96.0 -onnxruntime==1.22.0 -langchain-google-genai<1.0.0 -langchain - -pytest==7.4.0 -pytest-asyncio==0.21.1 -pytest-mock==3.12.0 -pytest-cov==4.1.0 -httpx -requests-mock==1.11.0 - -torch>=2.2.0,<2.8.0 -transformers>=4.35.0,<5.0.0 -tokenizers>=0.15.0,<1.0.0 -scikit-learn>=1.5.2,<2.0.0 -numpy>=1.21.0,<1.27.0 +annotated-types==0.7.0 +anyio==4.11.0 +certifi==2025.10.5 +exceptiongroup==1.3.0 +h11==0.16.0 +httpcore==1.0.9 +httpx==0.28.1 +idna==3.11 +ollama==0.6.0 +pydantic==2.12.3 +pydantic_core==2.41.4 +sniffio==1.3.1 +typing-inspection==0.4.2 +typing_extensions==4.15.0 From 76e735577579368906316bc8578cf06a12f51f69 Mon Sep 17 00:00:00 2001 From: Vitor Ramos Date: Wed, 29 Oct 2025 21:01:38 -0300 Subject: [PATCH 09/20] =?UTF-8?q?corre=C3=A7=C3=A3o=20de=20implementa?= =?UTF-8?q?=C3=A7=C3=A3o=20de=20contexto=20e=20gerenciamento=20de=20token?= =?UTF-8?q?=20com=20langchain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example.env | 16 ---- src/api/controller/AskController.py | 127 ++++++++++++++++++---------- 2 files changed, 80 insertions(+), 63 deletions(-) delete mode 100644 example.env diff --git a/example.env b/example.env deleted file mode 100644 index 7476625..0000000 --- a/example.env +++ /dev/null @@ -1,16 +0,0 @@ -# Airbyte -GITHUB_TOKEN= "" - -# Database credentials -DB_HOST=db -DB_AB_DESTINATION_HOST=host.docker.internal -DB_PORT=5432 -EXPOSED_DB_PORT=5432 -DB_NAME=databasex -DB_USER=postgres -DB_PASSWORD=postgres -DB_URL=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} - -# Google cloud gemini -GEMINI_API_KEY="" -GEMINI_MODEL_NAME=gemini-2.0-flash diff --git a/src/api/controller/AskController.py b/src/api/controller/AskController.py index 0e63ce0..cd320a4 100644 --- a/src/api/controller/AskController.py +++ b/src/api/controller/AskController.py @@ -4,13 +4,6 @@ from langchain_google_genai import ChatGoogleGenerativeAI from langchain.schema import SystemMessage, HumanMessage, AIMessage from langchain.memory import ConversationBufferWindowMemory -from langchain.chains import LLMChain -from langchain.prompts import ( - ChatPromptTemplate, - MessagesPlaceholder, - SystemMessagePromptTemplate, - HumanMessagePromptTemplate, -) from google import genai from src.api.database.MyVanna import MyVanna import json @@ -48,10 +41,7 @@ def __init__(self): output_key="answer" ) - # Chain para pré-processamento com contexto - self.preprocessing_chain = self._create_preprocessing_chain() - - # instancia do vanna + # Instância do vanna self.vn = MyVanna(config={ 'print_prompt': False, 'print_sql': False, @@ -64,10 +54,29 @@ def __init__(self): self.sql_cache: Dict[str, str] = {} self.result_cache: Dict[str, any] = {} - def _create_preprocessing_chain(self) -> LLMChain: - """Cria chain para pré-processar perguntas com contexto da conversa""" - - system_template = """Você é um assistente especializado em processar perguntas sobre dados do GitHub. + def _preprocess_question(self, question: str) -> str: + """ + Pré-processa a pergunta usando LLM com contexto da memória + Versão simplificada sem LLMChain para evitar problemas de parsing + """ + try: + # Recupera histórico da memória + memory_vars = self.memory.load_memory_variables({}) + chat_history = memory_vars.get("chat_history", []) + + # Monta contexto do histórico + history_text = "" + if chat_history: + history_text = "Histórico da conversa:\n" + for msg in chat_history[-5:]: # Últimas 5 mensagens + if isinstance(msg, HumanMessage): + history_text += f"Usuário: {msg.content}\n" + elif isinstance(msg, AIMessage): + history_text += f"Assistente: {msg.content}\n" + history_text += "\n" + + # Monta o prompt + system_prompt = """Você é um assistente especializado em processar perguntas sobre dados do GitHub. Sua função é: 1. Analisar o histórico da conversa para entender o contexto @@ -85,22 +94,37 @@ def _create_preprocessing_chain(self) -> LLMChain: - Se a pergunta fizer referência a algo anterior ("e aquele", "o outro", "também"), inclua o contexto explícito - Se não houver referência contextual, retorne a pergunta apenas normalizada - NÃO explique, NÃO confirme, NÃO dê exemplos -- Retorne APENAS a pergunta processada e expandida +- Retorne APENAS a pergunta processada e expandida em uma única linha""" -Histórico da conversa está disponível abaixo.""" - - prompt = ChatPromptTemplate.from_messages([ - SystemMessagePromptTemplate.from_template(system_template), - MessagesPlaceholder(variable_name="chat_history"), - HumanMessagePromptTemplate.from_template("{question}") - ]) - - return LLMChain( - llm=self.llm, - prompt=prompt, - memory=self.memory, - verbose=False - ) + # Monta mensagens + messages = [ + SystemMessage(content=system_prompt) + ] + + # Adiciona histórico se existir + if history_text: + messages.append(HumanMessage(content=history_text)) + + # Adiciona pergunta atual + messages.append(HumanMessage(content=f"Pergunta a processar: {question}")) + + # Chama LLM + response = self.llm.invoke(messages) + + # Extrai conteúdo da resposta + if hasattr(response, 'content'): + processed = response.content.strip() + else: + processed = str(response).strip() + + # Remove qualquer explicação extra (pega só a primeira linha) + processed = processed.split('\n')[0].strip() + + return processed + + except Exception as e: + print(f"[Warning] Erro no preprocessing: {e}. Usando pergunta original.") + return question def _get_cache_key(self, text: str) -> str: """Gera chave de cache baseada no hash da pergunta normalizada""" @@ -184,8 +208,9 @@ def _format_response_with_context(self, question: str, sql: str, result: any) -> ) return response.parsed[0].texto except Exception as e: + print(f"[Error] Erro ao formatar resposta: {e}") # Fallback para resposta simples - return f"Resultado: {result}" + return f"Consulta executada com sucesso. Resultado: {result}" def ask(self, question: Question, session_id: Optional[str] = None) -> dict: """ @@ -196,19 +221,12 @@ def ask(self, question: Question, session_id: Optional[str] = None) -> dict: session_id: ID da sessão para memória multi-usuário (futuro) """ - # --- Dentro de ask() --- try: original_question = question.question + print(f"[Original] {original_question}") - # Etapa 1: Pré-processar com contexto (usando chain) - processed_question = self.preprocessing_chain.invoke({ - "question": original_question - }) - if isinstance(processed_question, dict) and "text" in processed_question: - processed_question = processed_question["text"] - elif not isinstance(processed_question, str): - processed_question = str(processed_question) - + # Etapa 1: Pré-processar com contexto + processed_question = self._preprocess_question(original_question) print(f"[Preprocessed] {processed_question}") # Etapa 2: Verificar cache de SQL @@ -218,8 +236,10 @@ def ask(self, question: Question, session_id: Optional[str] = None) -> dict: print(f"[Cache Hit] SQL encontrado no cache") sql_gerado = self.sql_cache[cache_key] else: + # Gerar SQL com Vanna sql_gerado = self.vn.generate_sql(processed_question) + # Validar SQL is_valid, error_msg = self._validate_sql(sql_gerado) if not is_valid: return { @@ -227,19 +247,24 @@ def ask(self, question: Question, session_id: Optional[str] = None) -> dict: "error": True } + # Armazenar no cache self.sql_cache[cache_key] = sql_gerado print(f"[Cache Miss] SQL gerado e armazenado") print(f"[SQL] {sql_gerado}") + # Etapa 3: Verificar cache de resultados result_cache_key = hashlib.md5(sql_gerado.encode()).hexdigest() if result_cache_key in self.result_cache: print(f"[Cache Hit] Resultado encontrado no cache") resultado = self.result_cache[result_cache_key] else: + # Executar SQL resultado = self.vn.run_sql(sql_gerado) + if not resultado: + # Salvar na memória mesmo sem resultado self.memory.save_context( inputs={"question": original_question}, outputs={"answer": "Não há dados correspondentes no banco."} @@ -248,16 +273,19 @@ def ask(self, question: Question, session_id: Optional[str] = None) -> dict: "output": "A consulta foi executada, mas não há dados correspondentes.", "sql": sql_gerado } - + + # Armazenar resultado no cache self.result_cache[result_cache_key] = resultado print(f"[Cache Miss] Resultado obtido e armazenado") + # Etapa 4: Formatar resposta com contexto resposta_formatada = self._format_response_with_context( question=original_question, sql=sql_gerado, result=resultado ) + # Etapa 5: Salvar na memória self.memory.save_context( inputs={"question": original_question}, outputs={"answer": resposta_formatada} @@ -270,20 +298,25 @@ def ask(self, question: Question, session_id: Optional[str] = None) -> dict: } except Exception as e: + import traceback error_msg = f"Erro ao processar pergunta: {str(e)}" print(f"[Error] {error_msg}") + print(f"[Error] Traceback: {traceback.format_exc()}") - self.memory.save_context( - inputs={"question": question.question}, - outputs={"answer": error_msg} - ) + # Salvar erro na memória + try: + self.memory.save_context( + inputs={"question": question.question}, + outputs={"answer": error_msg} + ) + except: + pass return { "output": error_msg, "error": True } - def clear_memory(self): """Limpa o histórico da conversa""" self.memory.clear() From 80f4821fd69d898a419787b40bafd575eb655d6a Mon Sep 17 00:00:00 2001 From: aliciacapo Date: Sat, 1 Nov 2025 21:53:03 -0300 Subject: [PATCH 10/20] adicionando criacao de graficos no chat --- requirements.txt | 3 + src/api/controller/AskController.py | 183 ++++++++++++++++++------- src/api/endpoints/routes.py | 16 ++- src/assets/open_web_ui/pipeline_api.py | 27 ++-- 4 files changed, 155 insertions(+), 74 deletions(-) diff --git a/requirements.txt b/requirements.txt index 27ad852..2bd7127 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,3 +23,6 @@ transformers>=4.35.0,<5.0.0 tokenizers>=0.15.0,<1.0.0 scikit-learn>=1.5.2,<2.0.0 numpy>=1.21.0,<1.27.0 + +matplotlib==3.9.2 +pandas==2.2.3 \ No newline at end of file diff --git a/src/api/controller/AskController.py b/src/api/controller/AskController.py index ba55acc..523d814 100644 --- a/src/api/controller/AskController.py +++ b/src/api/controller/AskController.py @@ -1,6 +1,13 @@ from src.assets.pattern.singleton import SingletonMeta from src.api.models import Question, Response +# Novas imports para gráficos +import io +import os +import uuid +import matplotlib.pyplot as plt +import pandas as pd + from langchain_google_genai import ChatGoogleGenerativeAI from langchain.schema import SystemMessage, HumanMessage from google import genai @@ -11,21 +18,25 @@ GEMINI_API_KEY = env["GEMINI_API_KEY"] GEMINI_MODEL_NAME = env["GEMINI_MODEL_NAME"] + class AskController(metaclass=SingletonMeta): + STATIC_DIR = "src/api/static/graficos/" + def __init__(self): self.client = genai.Client(api_key=GEMINI_API_KEY) - self.gen = ChatGoogleGenerativeAI(model=GEMINI_MODEL_NAME, + self.gen = ChatGoogleGenerativeAI( + model=GEMINI_MODEL_NAME, google_api_key=GEMINI_API_KEY, temperature=0, max_tokens=None, timeout=None, max_retries=2, convert_system_message_to_human=True - ) + ) self.vn = MyVanna(config={ - 'print_prompt': False, + 'print_prompt': False, 'print_sql': False, 'api_key': GEMINI_API_KEY, 'model_name': GEMINI_MODEL_NAME @@ -33,59 +44,125 @@ def __init__(self): self.vn.prepare() - def ask(self, question: Question): + # Garantir que a pasta para gráficos exista + if not os.path.exists(self.STATIC_DIR): + os.makedirs(self.STATIC_DIR) + def ask(self, question: Question): try: - - mensagem = [SystemMessage(content="""Você é um assistente em um sistema que de chat AI, - seu trabalho é receber uma mensagem de um humano e tratar ela para ser processada - por outra IA que possui falhas. Dentro dos tratamentos necessários estão: - -Trocar datas que são dadas em formato que não sejam dias, por exemplo 3 mêses, - e transformar em dias, 90 dias. Outro exemplo, 1 ano e 2 meses, trocar por 425 dias - (serão considerados que os mêses separados terão 30 dias) - -Quando usada a expressão "mudança" referente ao repositório, você trocara por "commit", - por exemplo, "qual foi a ultima mudança feita no repositório?" será trocado por - "qual foi o ultimo commit feito no repositório?) - NÃO explique, NÃO confirme, NÃO dê exemplos. Apenas RETORNE a mensagem tratada. - Mensagem a ser processada:"""),HumanMessage(content=question.question)] - - ai_mensagem = self.gen.invoke(mensagem) - - print(ai_mensagem.content) - - sql_gerado = self.vn.generate_sql(ai_mensagem.content) - - if "SELECT" not in sql_gerado.upper(): - return {"output": "Não consegui entender sua pergunta bem o suficiente para gerar uma resposta SQL válida."} - - resultado = self.vn.run_sql(sql_gerado) - - if not resultado: - return {"output": "A consulta foi feita, mas não há dados correspondentes no banco."} - - # Prompt mais informativo - prompt = f""" - Você é um assistente que responde perguntas sobre dados extraídos do GitHub. - - Pergunta do usuário: "{question.question}" - - Resultado da consulta SQL: {resultado} - - Gere uma resposta clara e útil para o usuário, explicando o que o resultado significa. - """ - - - response = self.client.models.generate_content( - model=GEMINI_MODEL_NAME, - contents=prompt, - config={ - "response_mime_type": "application/json", - "response_schema": list[Response], - } + # Detectar se usuário quer gráfico + gerar_grafico = any( + kw in question.question.lower() + for kw in ["gráfico", "grafico", "chart", "visualizar", "plot"] ) - texto = response.parsed[0].texto - return {"output": texto} + # ----------------------------- + # Pergunta padrão (sem gráfico) + # ----------------------------- + if not gerar_grafico: + mensagem = [ + SystemMessage(content="""Você é um assistente em um sistema que de chat AI, + seu trabalho é receber uma mensagem de um humano e tratar ela para ser processada + por outra IA que possui falhas. Dentro dos tratamentos necessários estão: + -Trocar datas que são dadas em formato que não sejam dias, por exemplo 3 mêses, + e transformar em dias, 90 dias. Outro exemplo, 1 ano e 2 meses, trocar por 425 dias + (serão considerados que os mêses separados terão 30 dias) + -Quando usada a expressão "mudança" referente ao repositório, você trocara por "commit", + por exemplo, "qual foi a ultima mudança feita no repositório?" será trocado por + "qual foi o ultimo commit feito no repositório?") + NÃO explique, NÃO confirme, NÃO dê exemplos. Apenas RETORNE a mensagem tratada. + Mensagem a ser processada:"""), + HumanMessage(content=question.question) + ] + + ai_mensagem = self.gen.invoke(mensagem) + sql_gerado = self.vn.generate_sql(ai_mensagem.content) + + if "SELECT" not in sql_gerado.upper(): + return {"output": "Não consegui entender sua pergunta bem o suficiente para gerar uma resposta SQL válida."} + + resultado = self.vn.run_sql(sql_gerado) + + if not resultado: + return {"output": "A consulta foi feita, mas não há dados correspondentes no banco."} + + prompt = f""" + Você é um assistente que responde perguntas sobre dados extraídos do GitHub. + Pergunta do usuário: "{question.question}" + Resultado da consulta SQL: {resultado} + Gere uma resposta clara e útil para o usuário, explicando o que o resultado significa. + """ + response = self.client.models.generate_content( + model=GEMINI_MODEL_NAME, + contents=prompt, + config={ + "response_mime_type": "application/json", + "response_schema": list[Response], + } + ) + texto = response.parsed[0].texto + return {"output": texto} + + # ----------------------------- + # Pergunta com gráfico + # ----------------------------- + else: + mensagem = [ + SystemMessage(content="""Você é um assistente em um sistema que de chat AI, + seu trabalho é receber uma mensagem de um humano e tratar ela para ser processada + por outra IA que possui falhas. Dentro dos tratamentos necessários estão: + -Trocar datas que são dadas em formato que não sejam dias, por exemplo 3 mêses, + e transformar em dias, 90 dias. Outro exemplo, 1 ano e 2 meses, trocar por 425 dias + (serão considerados que os mêses separados terão 30 dias) + -Quando usada a expressão "mudança" referente ao repositório, você trocara por "commit", + por exemplo, "qual foi a ultima mudança feita no repositório?" será trocado por + "qual foi o ultimo commit feito no repositório?") + retire as palavras faça gráfico da mensagem, + NÃO explique, NÃO confirme, NÃO dê exemplos. Apenas RETORNE a mensagem tratada. + Mensagem a ser processada:"""), + HumanMessage(content=question.question) + ] + + ai_mensagem = self.gen.invoke(mensagem) + sql_gerado = self.vn.generate_sql(ai_mensagem.content) + + if "SELECT" not in sql_gerado.upper(): + return {"output": "Não consegui entender sua pergunta bem o suficiente para gerar uma resposta SQL válida."} + + resultado = self.vn.run_sql(sql_gerado) + + if not resultado: + return {"output": "A consulta foi feita, mas não há dados correspondentes no banco."} + + # ----------------------------- + # Geração do gráfico + # ----------------------------- + df = pd.DataFrame(resultado) + if df.empty: + return {"output": "Não há dados suficientes para gerar um gráfico."} + + plt.figure(figsize=(8,5)) + if df.shape[1] >= 2: + x = df.columns[0] + y = df.columns[1] + plt.bar(df[x], df[y]) + plt.xlabel(x) + plt.ylabel(y) + plt.title("Gráfico gerado a partir dos dados") + else: + plt.plot(df[df.columns[0]]) + plt.title("Gráfico gerado a partir dos dados") + + # Salvar gráfico como arquivo + filename = f"{uuid.uuid4()}.png" + filepath = os.path.join(self.STATIC_DIR, filename) + plt.tight_layout() + plt.savefig(filepath) + plt.close() + + # Montar link clicável + link = f"http://localhost:8000/static/graficos/{filename}" + return {"output": f"Gráfico gerado: [Clique aqui para visualizar]({link})", "grafico_url": link} except Exception as e: - return {"output": f"Ocorreu um erro ao processar sua pergunta: {str(e)}"} \ No newline at end of file + return {"output": f"Ocorreu um erro ao processar sua pergunta: {str(e)}"} \ No newline at end of file diff --git a/src/api/endpoints/routes.py b/src/api/endpoints/routes.py index 7c2f7f0..ac4905d 100644 --- a/src/api/endpoints/routes.py +++ b/src/api/endpoints/routes.py @@ -1,6 +1,8 @@ from fastapi import APIRouter, HTTPException -from src.api.models import Question, Response +from fastapi.responses import FileResponse +from src.api.models import Question from src.api.controller.AskController import AskController +import os router = APIRouter() @@ -11,4 +13,14 @@ async def ask_question(question: Question): try: return ask.ask(question) except Exception as e: - raise HTTPException(status_code=500, detail=str(e)) \ No newline at end of file + raise HTTPException(status_code=500, detail=str(e)) + + +# Endpoint para servir arquivos de gráficos +@router.get("/static/graficos/{filename}") +def serve_grafico(filename: str): + path = os.path.join("src/api/static/graficos", filename) + if os.path.exists(path): + return FileResponse(path) + else: + raise HTTPException(status_code=404, detail="Gráfico não encontrado") \ No newline at end of file diff --git a/src/assets/open_web_ui/pipeline_api.py b/src/assets/open_web_ui/pipeline_api.py index 097e6ef..e2978e5 100644 --- a/src/assets/open_web_ui/pipeline_api.py +++ b/src/assets/open_web_ui/pipeline_api.py @@ -37,9 +37,6 @@ def __init__(self): self.valves = self.Valves() self.last_emit_time = 0.0 # controle de throttle dos status - # -------------------------------------------------------------- - # Utilitário para reportar progresso para o OpenWebUI - # -------------------------------------------------------------- async def _emit_status( self, __event_emitter__: Callable[[dict], Awaitable[None]], @@ -66,19 +63,14 @@ async def _emit_status( ) self.last_emit_time = now - # -------------------------------------------------------------- - # Método principal chamado pelo OpenWebUI - # -------------------------------------------------------------- async def pipe( self, body: dict, __user__: Optional[dict] = None, __event_emitter__: Callable[[dict], Awaitable[None]] = None, - __event_call__: Callable[[dict], Awaitable[dict]] = None, # não usado + __event_call__: Callable[[dict], Awaitable[dict]] = None, ) -> Optional[dict]: - """Envia a última mensagem do usuário à API FastAPI e retorna a resposta.""" - # Recupera a última mensagem do usuário await self._emit_status(__event_emitter__, "info", "Processando entrada...", False) messages = body.get("messages", []) @@ -87,10 +79,8 @@ async def pipe( return {"error": "Nenhuma mensagem encontrada"} last_content = messages[-1]["content"] - # Estrutura de content pode ser: str | list[ {type: text|file} ] question = self._extract_text(last_content) - # Monta request para API FastAPI headers = {"Content-Type": "application/json"} if self.valves.bearer_token: headers["Authorization"] = f"Bearer {self.valves.bearer_token}" @@ -111,28 +101,27 @@ async def pipe( await self._emit_status(__event_emitter__, "error", f"Erro: {exc}", True) return {"error": str(exc)} - # Interpreta resposta da API. try: data = response.json() except ValueError: data = {"output": response.text} - answer = data.get("output") or data + grafico_url = data.get("grafico_url") + if grafico_url: + # link já incluído no output, apenas mostra o texto + answer = data.get("output") + else: + answer = data.get("output") or data - # Acrescenta a resposta ao histórico e devolve ao WebUI body["messages"].append({"role": "assistant", "content": answer}) await self._emit_status(__event_emitter__, "info", "Resposta entregue", True) return answer - # -------------------------------------------------------------- - # Auxiliar: extrair texto da mensagem (lida com arquivos/objetos) - # -------------------------------------------------------------- def _extract_text(self, content) -> str: if isinstance(content, str): return content.replace("Prompt: ", "", 1).strip() - # Caso seja uma lista (arquivos + texto) text_found = "" file_detected = False for item in content: @@ -147,4 +136,4 @@ def _extract_text(self, content) -> str: text_found = f"Recebemos o arquivo {name}, mas ele é muito grande para ser processado." else: text_found = f"Recebemos o arquivo {name}. Ainda não processamos arquivos neste chat." - return text_found or "Arquivo recebido." + return text_found or "Arquivo recebido." \ No newline at end of file From ce119ef6f666c9f3c61bb3d31f71bcfb33170a93 Mon Sep 17 00:00:00 2001 From: thiago fabiano Date: Mon, 10 Nov 2025 10:31:20 -0300 Subject: [PATCH 11/20] docs: adiciona arquivos andes e made --- docs/andes/.gitignore | 1 + docs/andes/artifacts/Oraculo.made | 38 + "docs/andes/artifacts/Or\303\241culo.spark" | 34 + .../Or\303\241culo/ModuleDomain.md" | 89 + .../Or\303\241culo/ModulePropourse.md" | 11 + .../Or\303\241culo/Requisites.md" | 59 + .../documentation/Or\303\241culo/UserCase.md" | 46 + docs/andes/oraculo.andes | 128 + docs/andes/package-lock.json | 13780 ++++++++++++++++ docs/andes/package.json | 5 + docs/made/.gitignore | 1 + docs/made/01_overview.md | 80 + docs/made/02_backlogs.md | 2 + docs/made/03_roadmap.md | 2 + docs/made/_category_.json | 10 + docs/made/db/backlog.json | 3 + docs/made/db/issue.json | 249 + docs/made/db/project.json | 12 + docs/made/db/roadmap.json | 3 + docs/made/db/team.json | 53 + docs/made/db/timebox.json | 407 + docs/made/oraculo.made | 376 + docs/made/project-cfd.svg | 513 + docs/made/project-throughput.svg | 675 + docs/made/sprints/Sprint1.md | 123 + docs/made/sprints/Sprint2.md | 80 + docs/made/sprints/Sprint3.md | 68 + docs/made/sprints/Sprint4.md | 68 + docs/made/sprints/Sprint5.md | 72 + docs/made/sprints/Sprint6.md | 72 + docs/made/sprints/Sprint7.md | 72 + docs/made/sprints/Sprint8.md | 72 + docs/made/sprints/_category_.json | 10 + docs/made/sprints/charts/cfd-Sprint1.svg | 325 + docs/made/sprints/charts/cfd-Sprint2.svg | 325 + docs/made/sprints/charts/cfd-Sprint3.svg | 325 + docs/made/sprints/charts/cfd-Sprint4.svg | 325 + docs/made/sprints/charts/cfd-Sprint5.svg | 325 + docs/made/sprints/charts/cfd-Sprint6.svg | 325 + docs/made/sprints/charts/cfd-Sprint7.svg | 325 + docs/made/sprints/charts/cfd-Sprint8.svg | 357 + docs/made/sprints/charts/throuput-Sprint1.svg | 561 + docs/made/sprints/charts/throuput-Sprint2.svg | 561 + docs/made/sprints/charts/throuput-Sprint3.svg | 561 + docs/made/sprints/charts/throuput-Sprint4.svg | 561 + docs/made/sprints/charts/throuput-Sprint5.svg | 561 + docs/made/sprints/charts/throuput-Sprint6.svg | 561 + docs/made/sprints/charts/throuput-Sprint7.svg | 561 + docs/made/sprints/charts/throuput-Sprint8.svg | 733 + 49 files changed, 24506 insertions(+) create mode 100644 docs/andes/.gitignore create mode 100644 docs/andes/artifacts/Oraculo.made create mode 100644 "docs/andes/artifacts/Or\303\241culo.spark" create mode 100644 "docs/andes/artifacts/documentation/Or\303\241culo/ModuleDomain.md" create mode 100644 "docs/andes/artifacts/documentation/Or\303\241culo/ModulePropourse.md" create mode 100644 "docs/andes/artifacts/documentation/Or\303\241culo/Requisites.md" create mode 100644 "docs/andes/artifacts/documentation/Or\303\241culo/UserCase.md" create mode 100644 docs/andes/oraculo.andes create mode 100644 docs/andes/package-lock.json create mode 100644 docs/andes/package.json create mode 100644 docs/made/.gitignore create mode 100644 docs/made/01_overview.md create mode 100644 docs/made/02_backlogs.md create mode 100644 docs/made/03_roadmap.md create mode 100644 docs/made/_category_.json create mode 100644 docs/made/db/backlog.json create mode 100644 docs/made/db/issue.json create mode 100644 docs/made/db/project.json create mode 100644 docs/made/db/roadmap.json create mode 100644 docs/made/db/team.json create mode 100644 docs/made/db/timebox.json create mode 100644 docs/made/oraculo.made create mode 100644 docs/made/project-cfd.svg create mode 100644 docs/made/project-throughput.svg create mode 100644 docs/made/sprints/Sprint1.md create mode 100644 docs/made/sprints/Sprint2.md create mode 100644 docs/made/sprints/Sprint3.md create mode 100644 docs/made/sprints/Sprint4.md create mode 100644 docs/made/sprints/Sprint5.md create mode 100644 docs/made/sprints/Sprint6.md create mode 100644 docs/made/sprints/Sprint7.md create mode 100644 docs/made/sprints/Sprint8.md create mode 100644 docs/made/sprints/_category_.json create mode 100644 docs/made/sprints/charts/cfd-Sprint1.svg create mode 100644 docs/made/sprints/charts/cfd-Sprint2.svg create mode 100644 docs/made/sprints/charts/cfd-Sprint3.svg create mode 100644 docs/made/sprints/charts/cfd-Sprint4.svg create mode 100644 docs/made/sprints/charts/cfd-Sprint5.svg create mode 100644 docs/made/sprints/charts/cfd-Sprint6.svg create mode 100644 docs/made/sprints/charts/cfd-Sprint7.svg create mode 100644 docs/made/sprints/charts/cfd-Sprint8.svg create mode 100644 docs/made/sprints/charts/throuput-Sprint1.svg create mode 100644 docs/made/sprints/charts/throuput-Sprint2.svg create mode 100644 docs/made/sprints/charts/throuput-Sprint3.svg create mode 100644 docs/made/sprints/charts/throuput-Sprint4.svg create mode 100644 docs/made/sprints/charts/throuput-Sprint5.svg create mode 100644 docs/made/sprints/charts/throuput-Sprint6.svg create mode 100644 docs/made/sprints/charts/throuput-Sprint7.svg create mode 100644 docs/made/sprints/charts/throuput-Sprint8.svg diff --git a/docs/andes/.gitignore b/docs/andes/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/docs/andes/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/docs/andes/artifacts/Oraculo.made b/docs/andes/artifacts/Oraculo.made new file mode 100644 index 0000000..091fa04 --- /dev/null +++ b/docs/andes/artifacts/Oraculo.made @@ -0,0 +1,38 @@ + +project Oraculo { + name: "Oráculo" + description: "Chatbot para análise de repositórios GitHub" + startDate: 2025-11-01 + dueDate: 2025-11-01 +} + +backlog Oraculo { + name: "Oráculo" + description: "Chatbot para análise de repositórios GitHub" + epic Authentication { + name: "Authentication" + } + epic TokenManagement { + name: "TokenManagement" + } + epic ChatInteraction { + name: "ChatInteraction" + } + epic DataVisualization { + name: "DataVisualization" + } + epic domaindiagram { + name: "domaindiagram" + story createmodule_OraculoApp { + name: "Create database infrastruture to module OraculoApp" + observation: "" + task create_module { + name: "Implements domain modules" + } + task create_repository { + name: "Implements data repository" + depends: Oraculo.domaindiagram.createmodule_OraculoApp.create_module + } + } + } +} \ No newline at end of file diff --git "a/docs/andes/artifacts/Or\303\241culo.spark" "b/docs/andes/artifacts/Or\303\241culo.spark" new file mode 100644 index 0000000..12e9311 --- /dev/null +++ "b/docs/andes/artifacts/Or\303\241culo.spark" @@ -0,0 +1,34 @@ + +Configuration { + software_name: "Oráculo" + about: "Chatbot para análise de repositórios GitHub" + language: python +} + +module OraculoApp { + entity User { + username: string + _email: email + password: string + github_token: string + } + entity Repository { + url: string + user ManyToOne User + } + entity Conversation { + conversation_date: date + user ManyToOne User + } + entity Message { + content: string + is_user: boolean + timestamp: date + conversation ManyToOne Conversation + } + enum Priority { + LOW + MEDIUM + HIGH + } +} \ No newline at end of file diff --git "a/docs/andes/artifacts/documentation/Or\303\241culo/ModuleDomain.md" "b/docs/andes/artifacts/documentation/Or\303\241culo/ModuleDomain.md" new file mode 100644 index 0000000..0bedcb9 --- /dev/null +++ "b/docs/andes/artifacts/documentation/Or\303\241culo/ModuleDomain.md" @@ -0,0 +1,89 @@ +--- +title: Domain +sidebar_position 3 +--- + +# Diagrama de Domínio +```plantuml +@startuml + class User { + +string username + +email _email + +string password + +string github_token + + } + class Repository { + +string url + + } + class Conversation { + +date conversation_date + + } + class Message { + +string content + +boolean is_user + +date timestamp + + } + + enum Priority { + low + medium + high + } + + User "1" -- "*" Repository : user + User "1" -- "*" Conversation : user + Conversation "1" -- "*" Message : conversation +@enduml +``` + + +# OraculoApp + +## User +Descrição: Classe Sem Descrição +Tabela 1: atributos da entidade User + +|Nome|Descrição|Meta Dados|Visibilidade| +|-|-|-|-| +|username||`string min: * max: * unique: false blank: false`|Public| +|_email||`email min: * max: * unique: false blank: false`|Public| +|password||`string min: * max: * unique: false blank: false`|Public| +|github_token||`string min: * max: * unique: false blank: false`|Public| + +Autor: Autoria Própria + +## Repository +Descrição: Classe Sem Descrição +Tabela 2: atributos da entidade Repository + +|Nome|Descrição|Meta Dados|Visibilidade| +|-|-|-|-| +|url||`string min: * max: * unique: false blank: false`|Public| + +Autor: Autoria Própria + +## Conversation +Descrição: Classe Sem Descrição +Tabela 3: atributos da entidade Conversation + +|Nome|Descrição|Meta Dados|Visibilidade| +|-|-|-|-| +|conversation_date||`date min: * max: * unique: false blank: false`|Public| + +Autor: Autoria Própria + +## Message +Descrição: Classe Sem Descrição +Tabela 4: atributos da entidade Message + +|Nome|Descrição|Meta Dados|Visibilidade| +|-|-|-|-| +|content||`string min: * max: * unique: false blank: false`|Public| +|is_user||`boolean min: * max: * unique: false blank: false`|Public| +|timestamp||`date min: * max: * unique: false blank: false`|Public| + +Autor: Autoria Própria \ No newline at end of file diff --git "a/docs/andes/artifacts/documentation/Or\303\241culo/ModulePropourse.md" "b/docs/andes/artifacts/documentation/Or\303\241culo/ModulePropourse.md" new file mode 100644 index 0000000..675bbea --- /dev/null +++ "b/docs/andes/artifacts/documentation/Or\303\241culo/ModulePropourse.md" @@ -0,0 +1,11 @@ +--- +title: Proósito do Módulo +sidebar_position 0 +--- + +# Propósito +Auxiliar usuários a obter informações e análises de repositórios GitHub através de IA + + +# Minimundo +Usuários autenticados podem conectar repositórios GitHub e fazer perguntas sobre o código via chat \ No newline at end of file diff --git "a/docs/andes/artifacts/documentation/Or\303\241culo/Requisites.md" "b/docs/andes/artifacts/documentation/Or\303\241culo/Requisites.md" new file mode 100644 index 0000000..39f3936 --- /dev/null +++ "b/docs/andes/artifacts/documentation/Or\303\241culo/Requisites.md" @@ -0,0 +1,59 @@ +--- +title: Requisitos do Módulo +sidebar_position 1 +--- + +# Requisitos Funcionais +| Item | Descrição | Dependências | Habilitados | Atores | +| --- | --- | --- | --- | --- | +| RF01 | O sistema deve permitir registro de usuários com email e senha | | RF02 | | +| RF02 | O sistema deve permitir login seguro de usuários | RF01 | RF03 | | +| RF07 | O sistema deve padronizar respostas da IA com parâmetros controláveis | | | | +| RF06 | O sistema deve gerar gráficos e visualizações de dados | | | | +| RF05 | O sistema deve manter memória contextual das conversas com a IA | | | | +| RF04 | O sistema deve permitir inserir e atualizar token de acesso ao GitHub | | | | +| RF03 | O sistema deve permitir controle de acesso para que usuários vejam apenas seus próprios dados | RF02 | | | + + + +# Requisitos Não Funcionais +| Item | Descrição | Dependências | Habilitados | Atores | +| --- | --- | --- | --- | --- | +| RNF05 | O sistema deve usar LangChain para gerenciamento de memória | | | | +| RNF04 | O frontend deve ser desenvolvido em React | | | | +| RNF03 | O backend deve ser desenvolvido em Django | | | | +| RNF02 | Deve ser uma aplicação responsiva, funcionando bem em desktop e mobile | | | | +| RNF01 | O sistema deve ter autenticação segura com criptografia de senha | | | | + + + +# Regras de Negócio +| Item | Descrição | Dependências | Habilitados | Atores | +| --- | --- | --- | --- | --- | + + + +# Grafos de Dependências + +## Requisitos Funcionais + +```mermaid +graph TD + RF01 --> RF02 + RF02 --> RF03 + +``` + +## Requisitos Nao Funcionais + +```mermaid +graph TD + +``` + +## Regras de Negócio + +```mermaid +graph TD + +``` \ No newline at end of file diff --git "a/docs/andes/artifacts/documentation/Or\303\241culo/UserCase.md" "b/docs/andes/artifacts/documentation/Or\303\241culo/UserCase.md" new file mode 100644 index 0000000..613c5a4 --- /dev/null +++ "b/docs/andes/artifacts/documentation/Or\303\241culo/UserCase.md" @@ -0,0 +1,46 @@ +--- +title: Modelo de Caso de Uso +sidebar_position 2 +--- + +# Caso de Uso + +## AUTHENTICATION: Autenticação e Controle de Acesso + + +## TOKENMANAGEMENT: Gerenciamento de Token + + +## CHATINTERACTION: Interação com Chatbot + + +## DATAVISUALIZATION: Visualização de Dados + + +## Matriz dos Casos de Uso +| Item | Descrição | Dependências | Habilitados | Atores | +| --- | --- | --- | --- | --- | +| DataVisualization | Sistema gera gráficos baseados em dados do repositório | | | | +| ChatInteraction | Usuário interage com a IA mantendo contexto da conversa | | | | +| TokenManagement | Usuário gerencia token de acesso ao GitHub | | | | +| Authentication | Usuário se registra e faz login de forma segura | | | | + + +## Matriz de Dependência dos UC + +```mermaid +graph TD + +``` + +## Matriz dos Eventos +| Item | Descrição | Dependências | Habilitados | Atores | +| --- | --- | --- | --- | --- | + + +## Matriz de Dependêcia dos Eventos + +```mermaid +graph TD + +``` \ No newline at end of file diff --git a/docs/andes/oraculo.andes b/docs/andes/oraculo.andes new file mode 100644 index 0000000..624e328 --- /dev/null +++ b/docs/andes/oraculo.andes @@ -0,0 +1,128 @@ +overview Oraculo { + name: "Oráculo" + description: "Chatbot para análise de repositórios GitHub" + purpose: "Auxiliar usuários a obter informações e análises de repositórios GitHub através de IA" + miniworld: "Usuários autenticados podem conectar repositórios GitHub e fazer perguntas sobre o código via chat" + Architecture: python +} + +requirements Requirements { + name: "Oráculo Requirements" + description: "Requisitos para o funcionamento do sistema Oráculo" + + functional_requirement RF01 { + description: "O sistema deve permitir registro de usuários com email e senha" + priority: "High" + } + + functional_requirement RF02 { + description: "O sistema deve permitir login seguro de usuários" + priority: "High" + depend: Requirements.RF01 + } + + functional_requirement RF03 { + description: "O sistema deve permitir controle de acesso para que usuários vejam apenas seus próprios dados" + priority: "High" + depend: Requirements.RF02 + } + + functional_requirement RF04 { + description: "O sistema deve permitir inserir e atualizar token de acesso ao GitHub" + priority: "High" + } + + functional_requirement RF05 { + description: "O sistema deve manter memória contextual das conversas com a IA" + priority: "High" + } + + functional_requirement RF06 { + description: "O sistema deve gerar gráficos e visualizações de dados" + priority: "Medium" + } + + functional_requirement RF07 { + description: "O sistema deve padronizar respostas da IA com parâmetros controláveis" + priority: "Low" + } + + non_functional_requirement RNF01 { + description: "O sistema deve ter autenticação segura com criptografia de senha" + priority: "High" + } + + non_functional_requirement RNF02 { + description: "Deve ser uma aplicação responsiva, funcionando bem em desktop e mobile" + priority: "High" + } + + non_functional_requirement RNF03 { + description: "O backend deve ser desenvolvido em FastAPI" + priority: "High" + } + + + non_functional_requirement RNF05 { + description: "O sistema deve usar LangChain para gerenciamento de memória" + priority: "High" + } +} + +usecase Authentication { + name: "Autenticação e Controle de Acesso" + description: "Usuário se registra e faz login de forma segura" + requirements: Requirements.RF01 +} + +usecase TokenManagement { + name: "Gerenciamento de Token" + description: "Usuário gerencia token de acesso ao GitHub" + requirements: Requirements.RF04 +} + +usecase ChatInteraction { + name: "Interação com Chatbot" + description: "Usuário interage com a IA mantendo contexto da conversa" + requirements: Requirements.RF05 +} + +usecase DataVisualization { + name: "Visualização de Dados" + description: "Sistema gera gráficos baseados em dados do repositório" + requirements: Requirements.RF06 +} + +module OraculoApp { + description: "Módulo principal da aplicação Oráculo" + + enum Priority { + low + medium + high + } + + entity User { + username: string + _email: email + password: string + github_token: string + } + + entity Repository { + url: string + user ManyToOne User + } + + entity Conversation { + conversation_date: date + user ManyToOne User + } + + entity Message { + content: string + is_user: boolean + timestamp: date + conversation ManyToOne Conversation + } +} \ No newline at end of file diff --git a/docs/andes/package-lock.json b/docs/andes/package-lock.json new file mode 100644 index 0000000..805be81 --- /dev/null +++ b/docs/andes/package-lock.json @@ -0,0 +1,13780 @@ +{ + "name": "andesTest", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "andes-leds-tools": "^0.4.9" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/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==", + "license": "MIT" + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", + "license": "Apache-2.0" + }, + "node_modules/@codingame/monaco-vscode-base-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-base-service-override/-/monaco-vscode-base-service-override-1.85.6.tgz", + "integrity": "sha512-+/vkUTgmRr81sr0fs8Qa6M/swWqhqmy8S4mH5UZkhTUQdLBv7k3ogaRpPcIqvTaqiVnj3ADv77yeL3PGVyhHDA==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-base-service-override/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-base-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-base-service-override/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@codingame/monaco-vscode-configuration-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-configuration-service-override/-/monaco-vscode-configuration-service-override-1.85.6.tgz", + "integrity": "sha512-/8kQpP7SPIe4IZPRdi0XoJwNfOmwcl1kY3UAFKYVbiXmo1bGD7NYHNZhJXuIuVbIV0yjTygs53nly0LeU9HhOw==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-configuration-service-override/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-configuration-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-configuration-service-override/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@codingame/monaco-vscode-editor-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-editor-service-override/-/monaco-vscode-editor-service-override-1.83.16.tgz", + "integrity": "sha512-ePiIxE+KpMTYq92d1AFfjn8FW0BHhivQ5Iv9H0XHoXMrMqEVzdbCvn4QBFKvqvuAz7+QPYfs77X9RuZ8A2wFCg==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/@codingame/monaco-vscode-editor-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-environment-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-environment-service-override/-/monaco-vscode-environment-service-override-1.85.6.tgz", + "integrity": "sha512-J/Td0YnsqEnOortn5J0fVwvZ6fB89jXhKEuDR8o0iV9Eoyirji7c+RGvL+5KJARNsguelc7//b81WW8/o4wMFg==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-environment-service-override/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-environment-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-environment-service-override/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@codingame/monaco-vscode-extensions-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-extensions-service-override/-/monaco-vscode-extensions-service-override-1.85.6.tgz", + "integrity": "sha512-TmjGSd1dDMm65KNlFg58zHNAD60KlpZXN1EExabezbEBHa/gMqLT5JyF3+bBe0tbPJ4R5zmWzvfunh73sgTbLw==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6", + "vscode-semver": "npm:semver@=5.5.0" + } + }, + "node_modules/@codingame/monaco-vscode-extensions-service-override/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-extensions-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-extensions-service-override/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.83.16.tgz", + "integrity": "sha512-agyigI7n6KzjWEgAZJKncuwQldpbjN19Bmr30LFp2ENh/1ezNPYP/SvhkTyQQTL/YDsup3FkkX2NH54fzOia9w==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/@codingame/monaco-vscode-files-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-host-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-host-service-override/-/monaco-vscode-host-service-override-1.85.6.tgz", + "integrity": "sha512-ikmJyG7ev9ERafD7J+y/JtoTPjkibOHxE2OLKxFMMaJsoGQK8dV0DR3geS1xTrEZf8ecCEqC2z4XpnAXr9V9IA==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-host-service-override/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-host-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-host-service-override/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@codingame/monaco-vscode-keybindings-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-keybindings-service-override/-/monaco-vscode-keybindings-service-override-1.83.16.tgz", + "integrity": "sha512-DA7WyFMYwLSJSrapD/H1VOL+84bHy+z5w9TSaX9xSsg4IU63U181Z/iXt2reNdxiKdp8b7xQuIXnmYiwuB72zw==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.83.16", + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/@codingame/monaco-vscode-keybindings-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-languages-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-languages-service-override/-/monaco-vscode-languages-service-override-1.83.16.tgz", + "integrity": "sha512-jijZahNeZXMiTO44EItewiqxfjHY1eja7vQLMes5xQ0G8kaNxRLk6Uv2N04FgcbOtOfPI/YnOK+CLyfOV3fclQ==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.83.16", + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/@codingame/monaco-vscode-languages-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-layout-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-layout-service-override/-/monaco-vscode-layout-service-override-1.85.6.tgz", + "integrity": "sha512-dWj01HuZRDfNIyqjY7py3tYElWaM7hLVkPokWM2/5tUtGr9xyLbKvi5JSeM96sbxpqHszzkR/hiv+4v4fSB+oQ==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-layout-service-override/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-layout-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-layout-service-override/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@codingame/monaco-vscode-model-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-model-service-override/-/monaco-vscode-model-service-override-1.83.16.tgz", + "integrity": "sha512-uvFxzSdxD+PlJ1B9+qCF4gum/bSaMtzmX7YKenGX27CUviOX3JuQlUeMPHgxFn7VlwUxOgxHR99fCieW6h7Y3w==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/@codingame/monaco-vscode-model-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-quickaccess-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-quickaccess-service-override/-/monaco-vscode-quickaccess-service-override-1.85.6.tgz", + "integrity": "sha512-f9PfAg+pWemwBysCtr/MAUA6iwU6/JFvGDakd7N0Nf9o882ozJt9UOHH8SHerPZk5UdqSJtnl7yJsDbmxbUf2Q==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-quickaccess-service-override/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-quickaccess-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-quickaccess-service-override/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@codingame/monaco-vscode-textmate-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-textmate-service-override/-/monaco-vscode-textmate-service-override-1.85.6.tgz", + "integrity": "sha512-v7fJL0nuOFf1Vksuv/KyYbtaUZEVNiNVYZtEKEVIU4k4EabzwbdqmZM7EbL5d3Nm98nuaJIyHNBV9cSmirfOiQ==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6", + "vscode-oniguruma": "1.7.0", + "vscode-textmate": "9.0.0" + } + }, + "node_modules/@codingame/monaco-vscode-textmate-service-override/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-textmate-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-textmate-service-override/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@codingame/monaco-vscode-theme-defaults-default-extension": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-theme-defaults-default-extension/-/monaco-vscode-theme-defaults-default-extension-1.85.6.tgz", + "integrity": "sha512-k8KsrIEKvQNlhoofN62TFtwyCdwuX+nTgX+LsK6GY8Uu5HpmUXyu0eZQFZYZy4D2h3HirPLSbQ02qUfjUwa6hw==", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-theme-defaults-default-extension/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-theme-defaults-default-extension/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-theme-defaults-default-extension/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@codingame/monaco-vscode-theme-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-theme-service-override/-/monaco-vscode-theme-service-override-1.85.6.tgz", + "integrity": "sha512-bFVRVex0eK3VsCL/loLZ8BGE3yqVhkYqDNDJlRIU4jyLA77Z5mz0NESF09wztkh/+TTA5XctBZIqxIe99VftWA==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-theme-service-override/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/@codingame/monaco-vscode-theme-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/@codingame/monaco-vscode-theme-service-override/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@commitlint/config-validator": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.0.0.tgz", + "integrity": "sha512-BeyLMaRIJDdroJuYM2EGhDMGwVBMZna9UiIqV9hxj+J551Ctc6yoGuGSmghOy/qPhBSuhA6oMtbEiTmxECafsg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@commitlint/types": "^20.0.0", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-20.0.0.tgz", + "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.1.0.tgz", + "integrity": "sha512-qo9ER0XiAimATQR5QhvvzePfeDfApi/AFlC1G+YN+ZAY8/Ua6IRrDrxRvQAr+YXUKAxUsTDSp9KXeXLBPsNRWg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@commitlint/config-validator": "^20.0.0", + "@commitlint/execute-rule": "^20.0.0", + "@commitlint/resolve-extends": "^20.1.0", + "@commitlint/types": "^20.0.0", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^6.1.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.1.0.tgz", + "integrity": "sha512-cxKXQrqHjZT3o+XPdqDCwOWVFQiae++uwd9dUBC7f2MdV58ons3uUvASdW7m55eat5sRiQ6xUHyMWMRm6atZWw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@commitlint/config-validator": "^20.0.0", + "@commitlint/types": "^20.0.0", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.0.0.tgz", + "integrity": "sha512-bVUNBqG6aznYcYjTjnc3+Cat/iBgbgpflxbIBTnsHTX0YVpnmINPEkSRWymT2Q8aSH3Y7aKnEbunilkYe8TybA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", + "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", + "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", + "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", + "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", + "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", + "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", + "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", + "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", + "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", + "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", + "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", + "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", + "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", + "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", + "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", + "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", + "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", + "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", + "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", + "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", + "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", + "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", + "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", + "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", + "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", + "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@inversifyjs/common": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@inversifyjs/common/-/common-1.4.0.tgz", + "integrity": "sha512-qfRJ/3iOlCL/VfJq8+4o5X4oA14cZSBbpAmHsYj8EsIit1xDndoOl0xKOyglKtQD4u4gdNVxMHx4RWARk/I4QA==", + "license": "MIT" + }, + "node_modules/@inversifyjs/core": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@inversifyjs/core/-/core-1.3.5.tgz", + "integrity": "sha512-B4MFXabhNTAmrfgB+yeD6wd/GIvmvWC6IQ8Rh/j2C3Ix69kmqwz9pr8Jt3E+Nho9aEHOQCZaGmrALgtqRd+oEQ==", + "license": "MIT", + "dependencies": { + "@inversifyjs/common": "1.4.0", + "@inversifyjs/reflect-metadata-utils": "0.2.4" + } + }, + "node_modules/@inversifyjs/reflect-metadata-utils": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@inversifyjs/reflect-metadata-utils/-/reflect-metadata-utils-0.2.4.tgz", + "integrity": "sha512-u95rV3lKfG+NT2Uy/5vNzoDujos8vN8O18SSA5UyhxsGYd4GLQn/eUsGXfOsfa7m34eKrDelTKRUX1m/BcNX5w==", + "license": "MIT", + "peerDependencies": { + "reflect-metadata": "0.2.2" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/core": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/endpoint": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz", + "integrity": "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/graphql": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", + "license": "MIT", + "dependencies": { + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-13.2.1.tgz", + "integrity": "sha512-Tj4PkZyIL6eBMYcG/76QGsedF0+dWVeLhYprTmuFVVxzDW7PQh23tM0TP0z+1MvSkxB29YFZwnUX+cXfTiSdyw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^15.0.1" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-26.0.0.tgz", + "integrity": "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA==", + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-15.0.2.tgz", + "integrity": "sha512-rR+5VRjhYSer7sC51krfCctQhVTmjyUMAaShfPB8mscVa8tSoLyon3coxQmXu0ahJoLVWl8dSGD/3OGZlFV44Q==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^26.0.0" + } + }, + "node_modules/@octokit/plugin-retry": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-8.0.3.tgz", + "integrity": "sha512-vKGx1i3MC0za53IzYBSBXcrhmd+daQDzuZfYDd52X5S0M2otf3kVZTVP8bLA3EkU0lTvd1WEC2OlNNa4G+dohA==", + "license": "MIT", + "dependencies": { + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=7" + } + }, + "node_modules/@octokit/plugin-throttling": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-11.0.3.tgz", + "integrity": "sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": "^7.0.0" + } + }, + "node_modules/@octokit/request": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.6.tgz", + "integrity": "sha512-FO+UgZCUu+pPnZAR+iKdUt64kPE7QW7ciqpldaMXaNzixz5Jld8dJ31LAUewk0cfSRkNSRKyqG438ba9c/qDlQ==", + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^11.0.2", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "fast-content-type-parse": "^3.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/request-error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.0.2.tgz", + "integrity": "sha512-U8piOROoQQUyExw5c6dTkU3GKxts5/ERRThIauNL7yaRoeXW0q/5bgHWT7JfWBw1UyrbK8ERId2wVkcB32n0uQ==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "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/@semantic-release/commit-analyzer": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-13.0.1.tgz", + "integrity": "sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==", + "license": "MIT", + "dependencies": { + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", + "debug": "^4.0.0", + "import-from-esm": "^2.0.0", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@semantic-release/github": { + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-11.0.6.tgz", + "integrity": "sha512-ctDzdSMrT3H+pwKBPdyCPty6Y47X8dSrjd3aPZ5KKIKKWTwZBE9De8GtsH3TyAlw3Uyo2stegMx6rJMXKpJwJA==", + "license": "MIT", + "dependencies": { + "@octokit/core": "^7.0.0", + "@octokit/plugin-paginate-rest": "^13.0.0", + "@octokit/plugin-retry": "^8.0.0", + "@octokit/plugin-throttling": "^11.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^7.0.0", + "lodash-es": "^4.17.21", + "mime": "^4.0.0", + "p-filter": "^4.0.0", + "tinyglobby": "^0.2.14", + "url-join": "^5.0.0" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=24.1.0" + } + }, + "node_modules/@semantic-release/npm": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.2.tgz", + "integrity": "sha512-+M9/Lb35IgnlUO6OSJ40Ie+hUsZLuph2fqXC/qrKn0fMvUU/jiCjpoL6zEm69vzcmaZJ8yNKtMBEKHWN49WBbQ==", + "license": "MIT", + "dependencies": { + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "execa": "^9.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^10.9.3", + "rc": "^1.2.8", + "read-pkg": "^9.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@semantic-release/npm/node_modules/normalize-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.0.tgz", + "integrity": "sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.1.0.tgz", + "integrity": "sha512-CcyDRk7xq+ON/20YNR+1I/jP7BYKICr1uKd1HHpROSnnTdGqOTburi4jcRiTYz0cpfhxSloQO3cGhnoot7IEkA==", + "license": "MIT", + "dependencies": { + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", + "debug": "^4.0.0", + "get-stream": "^7.0.0", + "import-from-esm": "^2.0.0", + "into-stream": "^7.0.0", + "lodash-es": "^4.17.21", + "read-package-up": "^11.0.0" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", + "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/into-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", + "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", + "license": "MIT", + "dependencies": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.2.tgz", + "integrity": "sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@types/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha512-xuK4kuYgV6/auME6nVp78i9B22jBUYZUCTl64fpJ3O7qWRxK5uRya5yrkBAlSU17k3EVf0DwT7NUjCo5wZD8OA==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.9.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz", + "integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==", + "license": "MIT", + "optional": true, + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "license": "MIT" + }, + "node_modules/@vitest/coverage-v8": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", + "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^1.0.2", + "ast-v8-to-istanbul": "^0.3.3", + "debug": "^4.4.1", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.17", + "magicast": "^0.3.5", + "std-env": "^3.9.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "3.2.4", + "vitest": "3.2.4" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "license": "MIT", + "peer": true, + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "license": "MIT", + "peer": true, + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.22.tgz", + "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.4", + "@vue/shared": "3.5.22", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-core/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz", + "integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz", + "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.4", + "@vue/compiler-core": "3.5.22", + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.19", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz", + "integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.22.tgz", + "integrity": "sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.22.tgz", + "integrity": "sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz", + "integrity": "sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.22", + "@vue/runtime-core": "3.5.22", + "@vue/shared": "3.5.22", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.22.tgz", + "integrity": "sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22" + }, + "peerDependencies": { + "vue": "3.5.22" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz", + "integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "license": "MIT", + "dependencies": { + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "optional": true, + "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/andes-leds-tools": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/andes-leds-tools/-/andes-leds-tools-0.4.9.tgz", + "integrity": "sha512-2IG1tJnhUk89Wfcvgahgvybyg+sC0pJCdZn+OyF/NlvjegLionlalNu3iFWWzfZHNZ++YBhl1M4UJ1JMQp1gnA==", + "license": "Apache-2.0", + "dependencies": { + "@codingame/monaco-vscode-editor-service-override": "1.83.16", + "@codingame/monaco-vscode-keybindings-service-override": "1.83.16", + "andes-lib": "^0.1.47", + "axios": "^1.7.2", + "c8": "^10.1.3", + "chalk": "~5.3.0", + "commander": "~11.0.0", + "dotenv": "^16.4.5", + "langium": "~3.0.0", + "made-cli": "^1.0.3", + "monaco-editor": "npm:@codingame/monaco-editor-treemended@1.83.16", + "monaco-editor-workers": "~0.44.0", + "monaco-editor-wrapper": "^3.6.0", + "monaco-languageclient": "~7.2.0", + "spark-leds-beta": "^0.2.6" + }, + "bin": { + "andes-cli": "bin/cli.js" + }, + "engines": { + "node": ">=18.0.0", + "vscode": "^1.67.0" + } + }, + "node_modules/andes-lib": { + "version": "0.1.50", + "resolved": "https://registry.npmjs.org/andes-lib/-/andes-lib-0.1.50.tgz", + "integrity": "sha512-0AtdIKp9gLc9qQ7DrWinCZESOSbuOYdh832IQpkitKqvmlnEmlnOTOTHyW047V+h31S/AUPyT4B5XFzuet7BqA==", + "license": "MIT", + "dependencies": { + "@vitest/coverage-v8": "^3.2.4", + "commitizen": "^4.3.1", + "coverage": "^0.4.1" + }, + "bin": { + "generate": "dist/index.js" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", + "license": "MIT", + "dependencies": { + "file-type": "^4.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/archive-type/node_modules/file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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==", + "license": "Python-2.0" + }, + "node_modules/argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "license": "MIT" + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "license": "MIT" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.8.tgz", + "integrity": "sha512-szgSZqUxI5T8mLKvS7WTjF9is+MVbOeLADU73IseOcrqhxr/VAvy6wfoVE39KnKzA7JRhjF5eUagNlHwvZPlKQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^9.0.1" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autocompleter": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/autocompleter/-/autocompleter-9.3.2.tgz", + "integrity": "sha512-rLbf2TLGOD7y+gOS36ksrZdIsvoHa2KXc2A7503w+NBRPrcF73zzFeYBxEcV/iMPjaBH3jFhNIYObZ7zt1fkCQ==", + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.1.tgz", + "integrity": "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "license": "Apache-2.0" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "license": "MIT", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "license": "MIT" + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", + "license": "MIT" + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/c8": { + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz", + "integrity": "sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==", + "license": "ISC", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.1", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^7.0.1", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "monocart-coverage-reports": "^2" + }, + "peerDependenciesMeta": { + "monocart-coverage-reports": { + "optional": true + } + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==", + "license": "MIT", + "dependencies": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caw": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", + "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", + "license": "MIT", + "dependencies": { + "get-proxy": "^2.0.0", + "isurl": "^1.0.0-alpha5", + "tunnel-agent": "^0.6.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "license": "MIT", + "peer": true, + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "license": "MIT" + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 16" + } + }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "license": "MIT", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/clean-stack": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.3.0.tgz", + "integrity": "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "license": "ISC", + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-highlight/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cli-highlight/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cli-highlight/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cli-highlight/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "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/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/co": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", + "integrity": "sha512-CQsjCRiNObI8AtTsNIBDRMQ4oMR83CzEswHYahClvul7gKk+lDQiOKv+5qh7LQWf5sh6jkZNispz/QlsZxyNgA==", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", + "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/commitizen": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.1.tgz", + "integrity": "sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==", + "license": "MIT", + "dependencies": { + "cachedir": "2.3.0", + "cz-conventional-changelog": "3.3.0", + "dedent": "0.7.0", + "detect-indent": "6.1.0", + "find-node-modules": "^2.1.2", + "find-root": "1.1.0", + "fs-extra": "9.1.0", + "glob": "7.2.3", + "inquirer": "8.2.5", + "is-utf8": "^0.2.1", + "lodash": "4.17.21", + "minimist": "1.2.7", + "strip-bom": "4.0.0", + "strip-json-comments": "3.1.1" + }, + "bin": { + "commitizen": "bin/commitizen", + "cz": "bin/git-cz", + "git-cz": "bin/git-cz" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/consolidate": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", + "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", + "deprecated": "Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog", + "license": "MIT", + "dependencies": { + "bluebird": "^3.1.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/conventional-changelog-angular": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.1.0.tgz", + "integrity": "sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==", + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.2.0.tgz", + "integrity": "sha512-Y2aW4596l9AEvFJRwFGJGiQjt2sBYTjPD18DdvxX9Vpz0Z7HQ+g1Z+6iYDAm1vR3QOJrDBkRHixHK/+FhkR6Pw==", + "license": "MIT", + "dependencies": { + "conventional-commits-filter": "^5.0.0", + "handlebars": "^4.7.7", + "meow": "^13.0.0", + "semver": "^7.5.2" + }, + "bin": { + "conventional-changelog-writer": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-commit-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz", + "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", + "license": "ISC" + }, + "node_modules/conventional-commits-filter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz", + "integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-commits-parser": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.2.1.tgz", + "integrity": "sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==", + "license": "MIT", + "dependencies": { + "meow": "^13.0.0" + }, + "bin": { + "conventional-commits-parser": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/convert-hrtime": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", + "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "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/cosmiconfig-typescript-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz", + "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "jiti": "^2.6.1" + }, + "engines": { + "node": ">=v18" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=9", + "typescript": ">=5" + } + }, + "node_modules/coverage": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/coverage/-/coverage-0.4.1.tgz", + "integrity": "sha512-Nwe6RSpwaUR6R++b5QukGrbu3rpeSOGZ805f6IXwG63pIaJZ7NV5osfDgJ43Fz0B9IwXha+jwArWB8Tpngi8lA==", + "license": "ISC", + "dependencies": { + "c8": "^5.0.1", + "foreground-child": "^1.5.6", + "normalize-package-data": "^2.5.0", + "slash": "^3.0.0", + "test-exclude": "^5.2.3", + "which": "^1.3.1", + "yargs-parser": "^13.1.1" + }, + "bin": { + "coverage": "index.js" + } + }, + "node_modules/coverage/node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "license": "MIT" + }, + "node_modules/coverage/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coverage/node_modules/c8": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/c8/-/c8-5.0.4.tgz", + "integrity": "sha512-MgWIJ3HYe4NTtqwD+v16OdHvfqSzSLOmsptMuUxkzsYMoZzEeUv3yVep2d84qFjgio/3WbVEd9bkYQCFSDKeMw==", + "license": "ISC", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "find-up": "^4.0.0", + "foreground-child": "^2.0.0", + "furi": "^1.3.0", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-report": "^2.0.8", + "istanbul-reports": "^2.2.6", + "rimraf": "^3.0.0", + "test-exclude": "^5.2.3", + "v8-to-istanbul": "^3.2.3", + "yargs": "^14.0.0", + "yargs-parser": "^14.0.0" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/coverage/node_modules/c8/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/coverage/node_modules/c8/node_modules/yargs-parser": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-14.0.0.tgz", + "integrity": "sha512-zn/Mnx+tbFjkCFUodEpjXckNS65NfpB5oyqOkDDEG/8uxlfLZJu2IoBLQFjukUkn9rBbGkVYNzrDh6qy4NUd3g==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/coverage/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "license": "ISC", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/coverage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/coverage/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/coverage/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/coverage/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "license": "MIT" + }, + "node_modules/coverage/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/coverage/node_modules/foreground-child": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha512-3TOY+4TKV0Ml83PXJQY+JFQaHNV38lzQDIzzXYg1kWdBLenGgoZhAs0CKgzI31vi2pWEpQMq/Yi4bpKwCPkw7g==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "node_modules/coverage/node_modules/foreground-child/node_modules/cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", + "license": "MIT", + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/coverage/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/coverage/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/coverage/node_modules/istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/coverage/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/coverage/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "license": "MIT", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/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/coverage/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/coverage/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/coverage/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/coverage/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/coverage/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/v8-to-istanbul": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-3.2.6.tgz", + "integrity": "sha512-M6zzkVjsr+6sFdWPCuq7fjg9oCOXlssin05Yhobt9jMqHlEhw8AQ4/ClDiLCVWzXjpS2ezik53mhgSivw0XwmQ==", + "license": "ISC", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/coverage/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coverage/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "license": "ISC" + }, + "node_modules/coverage/node_modules/yargs": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "node_modules/coverage/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/coverage/node_modules/yargs/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/coverage/node_modules/yargs/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/coverage/node_modules/yargs/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/coverage/node_modules/yargs/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/coverage/node_modules/yargs/node_modules/yargs-parser": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.3.tgz", + "integrity": "sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/cz-conventional-changelog": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", + "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==", + "license": "MIT", + "dependencies": { + "chalk": "^2.4.1", + "commitizen": "^4.0.3", + "conventional-commit-types": "^3.0.0", + "lodash.map": "^4.5.1", + "longest": "^2.0.1", + "word-wrap": "^1.0.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@commitlint/load": ">6.1.1" + } + }, + "node_modules/cz-conventional-changelog/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/cz-conventional-changelog/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/cz-conventional-changelog/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "license": "MIT", + "dependencies": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "license": "MIT", + "dependencies": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "license": "MIT", + "dependencies": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "license": "MIT", + "dependencies": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", + "license": "MIT", + "dependencies": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip/node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", + "license": "MIT", + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress/node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "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", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/download": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", + "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==", + "license": "MIT", + "dependencies": { + "archive-type": "^4.0.0", + "caw": "^2.0.1", + "content-disposition": "^0.5.2", + "decompress": "^4.2.0", + "ext-name": "^5.0.0", + "file-type": "^8.1.0", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^8.3.1", + "make-dir": "^1.2.0", + "p-event": "^2.1.0", + "pify": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/download-git-repo": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/download-git-repo/-/download-git-repo-3.0.2.tgz", + "integrity": "sha512-N8hWXD4hXqmEcNoR8TBYFntaOcYvEQ7Bz90mgm3bZRTuteGQqwT32VDMnTyD0KTEvb8BWrMc1tVmzuV9u/WrAg==", + "license": "MIT", + "dependencies": { + "download": "^7.1.0", + "git-clone": "^0.1.0", + "rimraf": "^3.0.0" + } + }, + "node_modules/download/node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", + "license": "BSD-3-Clause" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-ci": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.2.0.tgz", + "integrity": "sha512-D5kWfzkmaOQDioPmiviWAVtKmpPT4/iJmMVQxWxMPJTFyTkdc5JQUfc5iXEeWxcOdsYTKSAiA/Age4NUOqKsRA==", + "license": "MIT", + "dependencies": { + "execa": "^8.0.0", + "java-properties": "^1.0.2" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + } + }, + "node_modules/env-ci/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/env-ci/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/env-ci/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/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/env-ci/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT", + "peer": true + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", + "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.11", + "@esbuild/android-arm": "0.25.11", + "@esbuild/android-arm64": "0.25.11", + "@esbuild/android-x64": "0.25.11", + "@esbuild/darwin-arm64": "0.25.11", + "@esbuild/darwin-x64": "0.25.11", + "@esbuild/freebsd-arm64": "0.25.11", + "@esbuild/freebsd-x64": "0.25.11", + "@esbuild/linux-arm": "0.25.11", + "@esbuild/linux-arm64": "0.25.11", + "@esbuild/linux-ia32": "0.25.11", + "@esbuild/linux-loong64": "0.25.11", + "@esbuild/linux-mips64el": "0.25.11", + "@esbuild/linux-ppc64": "0.25.11", + "@esbuild/linux-riscv64": "0.25.11", + "@esbuild/linux-s390x": "0.25.11", + "@esbuild/linux-x64": "0.25.11", + "@esbuild/netbsd-arm64": "0.25.11", + "@esbuild/netbsd-x64": "0.25.11", + "@esbuild/openbsd-arm64": "0.25.11", + "@esbuild/openbsd-x64": "0.25.11", + "@esbuild/openharmony-arm64": "0.25.11", + "@esbuild/sunos-x64": "0.25.11", + "@esbuild/win32-arm64": "0.25.11", + "@esbuild/win32-ia32": "0.25.11", + "@esbuild/win32-x64": "0.25.11" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "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/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", + "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", + "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/execa/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/execa/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/execa/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/execa/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/execa/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/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "license": "MIT", + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-content-type-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", + "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT", + "optional": true + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", + "license": "MIT" + }, + "node_modules/file-type": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz", + "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", + "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-node-modules": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz", + "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==", + "license": "MIT", + "dependencies": { + "findup-sync": "^4.0.0", + "merge": "^2.1.1" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-versions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-6.0.0.tgz", + "integrity": "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==", + "license": "MIT", + "dependencies": { + "semver-regex": "^4.0.5", + "super-regex": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "license": "MIT", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "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==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-timeout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-1.0.2.tgz", + "integrity": "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/furi": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/furi/-/furi-1.3.0.tgz", + "integrity": "sha512-TYoXEeRLKHXNWcCBP0VH1psPktQ9G8Y0GfZwMXCvwVbhbfNx7JItKWhB5mMBYufNjqxEHq+Ivd1nLtr5vQyVoQ==", + "license": "MIT", + "dependencies": { + "@types/is-windows": "^0.2.0", + "is-windows": "^1.0.2" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-proxy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", + "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", + "license": "MIT", + "dependencies": { + "npm-conf": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/git-clone": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/git-clone/-/git-clone-0.1.0.tgz", + "integrity": "sha512-zs9rlfa7HyaJAKG9o+V7C6qfMzyc+tb1IIXdUFcOBcR1U7siKy/uPdauLlrH1mc0vOgUwIv4BF+QxPiiTYz3Rw==", + "license": "ISC" + }, + "node_modules/git-log-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.1.tgz", + "integrity": "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==", + "license": "MIT", + "dependencies": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "0.6.8" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "license": "MIT", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "license": "ISC" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "license": "MIT", + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hook-std": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-4.0.0.tgz", + "integrity": "sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "license": "ISC" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "license": "MIT" + }, + "node_modules/http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "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.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from-esm": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-2.0.0.tgz", + "integrity": "sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=18.20" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/index-to-position": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", + "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "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/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/inquirer": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==", + "license": "MIT", + "dependencies": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inversify": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.2.2.tgz", + "integrity": "sha512-KB836KHbZ9WrUnB8ax5MtadOwnqQYa+ZJO3KWbPFgcr4RIEnHM621VaqFZzOZd9+U7ln6upt9n0wJei7x2BNqw==", + "license": "MIT", + "dependencies": { + "@inversifyjs/common": "1.4.0", + "@inversifyjs/core": "1.3.5" + }, + "peerDependencies": { + "reflect-metadata": "~0.2.2" + } + }, + "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-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "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-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "license": "MIT" + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/issue-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.1.tgz", + "integrity": "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==", + "license": "MIT", + "dependencies": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "license": "MIT", + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "license": "MIT", + "optional": true, + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "license": "MIT" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "license": "MIT" + }, + "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": "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", + "optional": true + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/langium": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", + "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", + "license": "MIT", + "dependencies": { + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/leds-spark-lib": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/leds-spark-lib/-/leds-spark-lib-1.12.0.tgz", + "integrity": "sha512-MZ4m9F1U8nt8548BtU4WsuymUds8aI4u9ft3rDHK6n91CVPAyTTeyPb4dL1YVFxBtzSPSwicUzWbUeIf03NblA==", + "license": "ISC", + "dependencies": { + "seon-lib-implementation": "^0.0.6", + "vue": "^3.5.16" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "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/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/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==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", + "license": "MIT" + }, + "node_modules/lodash.clonedeepwith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz", + "integrity": "sha512-QRBRSxhbtsX1nc0baxSkkK5WlVTTm/s48DSukcGcWZwIyI8Zz+lB+kFiELJXtzfH4Aj6kMWQ1VWW4U5uUDgZMA==", + "license": "MIT" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/longest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz", + "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "license": "MIT", + "peer": true + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/made-cli": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/made-cli/-/made-cli-1.0.3.tgz", + "integrity": "sha512-caTdYFVE9sHe1mSezRgU/WEq5vCsjy8K34lz3oJ8rAoUEbMuPZ5xJEASrwl82hNPyssyGC6trAkin9Yx0qz1AQ==", + "license": "ISC", + "dependencies": { + "axios": "^0.19.2", + "commander": "^5.1.0", + "consolidate": "^0.15.1", + "download-git-repo": "^3.0.2", + "ejs": "^3.1.3", + "inquirer": "^7.3.0", + "metalsmith": "^2.3.0", + "ncp": "^2.0.0", + "ora": "^4.0.4" + }, + "bin": { + "made-cli": "bin/index.js" + } + }, + "node_modules/made-cli/node_modules/axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", + "license": "MIT", + "dependencies": { + "follow-redirects": "1.5.10" + } + }, + "node_modules/made-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/made-cli/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/made-cli/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/made-cli/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/made-cli/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/made-cli/node_modules/follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "license": "MIT", + "dependencies": { + "debug": "=3.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/made-cli/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/made-cli/node_modules/inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/made-cli/node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/made-cli/node_modules/log-symbols/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/made-cli/node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/made-cli/node_modules/log-symbols/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/made-cli/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/made-cli/node_modules/ora": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz", + "integrity": "sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==", + "license": "MIT", + "dependencies": { + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/made-cli/node_modules/ora/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/made-cli/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/made-cli/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marked": { + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-terminal": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz", + "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "ansi-regex": "^6.1.0", + "chalk": "^5.4.1", + "cli-highlight": "^2.1.11", + "cli-table3": "^0.6.5", + "node-emoji": "^2.2.0", + "supports-hyperlinks": "^3.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <16" + } + }, + "node_modules/marked-terminal/node_modules/ansi-escapes": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.1.1.tgz", + "integrity": "sha512-Zhl0ErHcSRUaVfGUeUdDuLgpkEo8KIFjB4Y9uAc46ScOpdDiU1Dbyplh7qWJeJ/ZHpbyMSM26+X3BySgnIz40Q==", + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marked-terminal/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/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz", + "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", + "license": "MIT" + }, + "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/metalsmith": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/metalsmith/-/metalsmith-2.6.3.tgz", + "integrity": "sha512-nql0eDbeDdYY3cz0uDVmwQ/E9XDBAHBf5p3lz+IwZAlUvz72DAd5+F+vl7Fot7I+yQDVK59uB0CL9S+Ts7ELsw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.6.0", + "commander": "^10.0.1", + "debug": "^4.3.4", + "gray-matter": "^4.0.3", + "is-utf8": "~0.2.0", + "lodash.clonedeepwith": "^4.5.0", + "micromatch": "^4.0.5", + "stat-mode": "^1.0.0", + "ware": "^1.3.0" + }, + "bin": { + "metalsmith": "bin/metalsmith" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/metalsmith/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.1.0.tgz", + "integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==", + "funding": [ + "https://github.com/sponsors/broofa" + ], + "license": "MIT", + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "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": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mlly": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" + } + }, + "node_modules/monaco-editor": { + "name": "@codingame/monaco-editor-treemended", + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-editor-treemended/-/monaco-editor-treemended-1.83.16.tgz", + "integrity": "sha512-KS89o9zxphQqjQgZgpTDiHZNKCFxRpQdiDVkEfJGfNc83r5GbtTlIXA7RqtUSy55F+K5Bb3ua2WvrbwUGcZqBg==", + "license": "MIT" + }, + "node_modules/monaco-editor-workers": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor-workers/-/monaco-editor-workers-0.44.0.tgz", + "integrity": "sha512-rvdO292CMnxs9Y3Hl6nAjVx8d0SjcDgmXmZNVoaOCNJrdnTEEzcWcHJzEQsajTAAq4H2oeBmDZRpDE0US5DhXA==", + "license": "MIT", + "dependencies": { + "monaco-editor": "~0.44.0" + }, + "peerDependencies": { + "monaco-editor": "~0.44.0" + } + }, + "node_modules/monaco-editor-workers/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/monaco-editor-wrapper": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/monaco-editor-wrapper/-/monaco-editor-wrapper-3.6.0.tgz", + "integrity": "sha512-knW7bep54vUECL+4C9l4mKOM8hEB/TIMVmMWeVmhR6oJXUW1GYJwJM45q741ursS+qHcbZw1HIrUPv+tL79iOw==", + "deprecated": "The development of monaco-wrapper-editor will not be continued. Please use https://www.npmjs.com/package/monaco-languageclient v10+ from now on.", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-configuration-service-override": "~1.85.0", + "@codingame/monaco-vscode-editor-service-override": "~1.85.0", + "@codingame/monaco-vscode-textmate-service-override": "~1.85.0", + "@codingame/monaco-vscode-theme-defaults-default-extension": "~1.85.0", + "@codingame/monaco-vscode-theme-service-override": "~1.85.0", + "monaco-editor": "npm:@codingame/monaco-editor-treemended@>=1.85.0 <1.86.0", + "monaco-languageclient": "~7.3.0", + "vscode": "npm:@codingame/monaco-vscode-api@>=1.85.0 <1.86.0", + "vscode-languageclient": "~9.0.1", + "vscode-languageserver-protocol": "~3.17.5", + "vscode-ws-jsonrpc": "~3.1.0" + }, + "peerDependencies": { + "monaco-languageclient": "~7.3.0", + "vscode-ws-jsonrpc": "~3.1.0" + } + }, + "node_modules/monaco-editor-wrapper/node_modules/@codingame/monaco-vscode-editor-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-editor-service-override/-/monaco-vscode-editor-service-override-1.85.6.tgz", + "integrity": "sha512-oVlZrob7zvSGyk5YdBtFdSQ0o8vDrbwNs/DXunfaKVai6l5NKvi5aGUzMdyPWOs+GUIQERbWuMfFtaNE73LrtQ==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/monaco-editor-wrapper/node_modules/@codingame/monaco-vscode-editor-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/monaco-editor-wrapper/node_modules/@codingame/monaco-vscode-files-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.85.6.tgz", + "integrity": "sha512-ptNqoLBJr/+8Z5gzgeuAZt4yaPK5Lm0i5okQTcgrzHLezKCs5XZXUk6ZVeCMoQqQiK9Mo4C5mWimPQ83Wf18ig==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/monaco-editor-wrapper/node_modules/@codingame/monaco-vscode-files-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/monaco-editor-wrapper/node_modules/@codingame/monaco-vscode-languages-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-languages-service-override/-/monaco-vscode-languages-service-override-1.85.6.tgz", + "integrity": "sha512-gkV0CvL9NB03Ve9P0OOB9KplbWiedBeZvgc6NstICMiqT+opNAqcSbkceyWm+LhZoLq6ZsKNuTl4NrtJ4VnECg==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/monaco-editor-wrapper/node_modules/@codingame/monaco-vscode-languages-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/monaco-editor-wrapper/node_modules/@codingame/monaco-vscode-model-service-override": { + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-model-service-override/-/monaco-vscode-model-service-override-1.85.6.tgz", + "integrity": "sha512-DTIjWmP2Offsi5T8ZQxABnYK0lTNXdd+Vc9IpsXatFCmM6434JX48rz7QNnAP3eNUOaQemXUlTFYcj30R0arBA==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.85.6" + } + }, + "node_modules/monaco-editor-wrapper/node_modules/@codingame/monaco-vscode-model-service-override/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/monaco-editor-wrapper/node_modules/monaco-editor": { + "name": "@codingame/monaco-editor-treemended", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-editor-treemended/-/monaco-editor-treemended-1.85.6.tgz", + "integrity": "sha512-gA48LPVzbKDHyrKbQ6qLgV0hE6BH+px5ZCfjLPzZnl9WQZ4iLhpHB8oqPdMLRr/0y73qzSkQdQ0T/iGxiDC+hw==", + "license": "MIT" + }, + "node_modules/monaco-editor-wrapper/node_modules/monaco-languageclient": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/monaco-languageclient/-/monaco-languageclient-7.3.0.tgz", + "integrity": "sha512-8mAl+qa1JhTv5Iwm8P4a08XAJoN2XrG7tyckOYLn0jipLLdXNCRuUA6HaaFkc/naTzjy/bgqpiMoFy9k5J6gKA==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-editor-service-override": "~1.85.0", + "@codingame/monaco-vscode-languages-service-override": "~1.85.0", + "@codingame/monaco-vscode-model-service-override": "~1.85.0", + "monaco-editor": "npm:@codingame/monaco-editor-treemended@>=1.85.0 <1.86.0", + "vscode": "npm:@codingame/monaco-vscode-api@>=1.85.0 <1.86.0", + "vscode-languageclient": "~9.0.1" + }, + "engines": { + "node": ">=16.11.0", + "npm": ">=9.0.0" + }, + "peerDependencies": { + "monaco-editor": "0.45.0", + "vscode": "npm:@codingame/monaco-vscode-api@>=1.85.0 <1.86.0" + }, + "peerDependenciesMeta": { + "monaco-editor": { + "optional": false + }, + "vscode": { + "optional": false + } + } + }, + "node_modules/monaco-editor-wrapper/node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.85.6", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.85.6.tgz", + "integrity": "sha512-4udds/yfMRwrzRF6Yq5lI/vn4TEDT4r4nxSJXJ4KNpLoSWNV2p63NMItBGKmFBKCJQpIMtvO2O0IeX9gso2v2A==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-base-service-override": "1.85.6", + "@codingame/monaco-vscode-environment-service-override": "1.85.6", + "@codingame/monaco-vscode-extensions-service-override": "1.85.6", + "@codingame/monaco-vscode-files-service-override": "1.85.6", + "@codingame/monaco-vscode-host-service-override": "1.85.6", + "@codingame/monaco-vscode-layout-service-override": "1.85.6", + "@codingame/monaco-vscode-quickaccess-service-override": "1.85.6", + "monaco-editor": "0.45.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/monaco-editor-wrapper/node_modules/vscode/node_modules/monaco-editor": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz", + "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==", + "license": "MIT" + }, + "node_modules/monaco-languageclient": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/monaco-languageclient/-/monaco-languageclient-7.2.0.tgz", + "integrity": "sha512-Aequ3Lrq/rc5lGDiJ/0eD9CX+hi5fBaIae+vlzxqVVzrQXxyOrCEg2HpHjKHVSIfVtbUzH/hOAVCWqBeQv/AaA==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-editor-service-override": "~1.83.16", + "@codingame/monaco-vscode-languages-service-override": "~1.83.16", + "@codingame/monaco-vscode-model-service-override": "~1.83.16", + "monaco-editor": "npm:@codingame/monaco-editor-treemended@>=1.83.16 <1.84.0", + "vscode": "npm:@codingame/monaco-vscode-api@>=1.83.16 <1.84.0", + "vscode-languageclient": "~9.0.1" + }, + "engines": { + "node": ">=16.11.0", + "npm": ">=9.0.0" + }, + "peerDependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@>=1.83.16 <1.84.0" + }, + "peerDependenciesMeta": { + "monaco-editor": { + "optional": false + }, + "vscode": { + "optional": false + } + } + }, + "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==", + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "license": "MIT", + "bin": { + "ncp": "bin/ncp" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", + "license": "MIT" + }, + "node_modules/node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-emoji/node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "license": "MIT", + "dependencies": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.4.tgz", + "integrity": "sha512-OnUG836FwboQIbqtefDNlyR0gTHzIfwRfE3DuiNewBvnMnWEpB0VEXwBlFVgqpNzIgYo/MHh3d2Hel/pszapAA==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/redact", + "@npmcli/run-script", + "@sigstore/tuf", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "cli-columns", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "normalize-package-data", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "spdx-expression-parse", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], + "license": "Artistic-2.0", + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^8.0.1", + "@npmcli/config": "^9.0.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/map-workspaces": "^4.0.2", + "@npmcli/package-json": "^6.2.0", + "@npmcli/promise-spawn": "^8.0.2", + "@npmcli/redact": "^3.2.2", + "@npmcli/run-script": "^9.1.0", + "@sigstore/tuf": "^3.1.1", + "abbrev": "^3.0.1", + "archy": "~1.0.0", + "cacache": "^19.0.1", + "chalk": "^5.4.1", + "ci-info": "^4.2.0", + "cli-columns": "^4.0.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^10.4.5", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^8.1.0", + "ini": "^5.0.0", + "init-package-json": "^7.0.2", + "is-cidr": "^5.1.1", + "json-parse-even-better-errors": "^4.0.0", + "libnpmaccess": "^9.0.0", + "libnpmdiff": "^7.0.1", + "libnpmexec": "^9.0.1", + "libnpmfund": "^6.0.1", + "libnpmhook": "^11.0.0", + "libnpmorg": "^7.0.0", + "libnpmpack": "^8.0.1", + "libnpmpublish": "^10.0.1", + "libnpmsearch": "^8.0.0", + "libnpmteam": "^7.0.0", + "libnpmversion": "^7.0.0", + "make-fetch-happen": "^14.0.3", + "minimatch": "^9.0.5", + "minipass": "^7.1.1", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^11.2.0", + "nopt": "^8.1.0", + "normalize-package-data": "^7.0.0", + "npm-audit-report": "^6.0.0", + "npm-install-checks": "^7.1.1", + "npm-package-arg": "^12.0.2", + "npm-pick-manifest": "^10.0.0", + "npm-profile": "^11.0.1", + "npm-registry-fetch": "^18.0.2", + "npm-user-validate": "^3.0.0", + "p-map": "^7.0.3", + "pacote": "^19.0.1", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "qrcode-terminal": "^0.12.0", + "read": "^4.1.0", + "semver": "^7.7.2", + "spdx-expression-parse": "^4.0.0", + "ssri": "^12.0.0", + "supports-color": "^9.4.0", + "tar": "^6.2.1", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^6.0.1", + "which": "^5.0.0", + "write-file-atomic": "^6.0.0" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-conf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", + "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", + "license": "MIT", + "dependencies": { + "config-chain": "^1.1.11", + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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/npm/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "8.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^8.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "ssri": "^12.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/config": { + "version": "9.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "ci-info": "^4.0.0", + "ini": "^5.0.0", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/git": { + "version": "6.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "4.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "8.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^20.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { + "version": "20.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "6.2.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "8.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/query": { + "version": "4.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/redact": { + "version": "3.2.2", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "9.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.4.3", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "3.1.1", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.1", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.3", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-styles": { + "version": "6.2.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bin-links": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.3.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "19.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/chalk": { + "version": "5.4.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ci-info": { + "version": "4.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "4.1.3", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^5.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/npm/node_modules/color-name": { + "version": "1.1.4", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "7.0.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.4.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/diff": { + "version": "5.2.0", + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/eastasianwidth": { + "version": "0.2.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.2", + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/npm/node_modules/foreground-child": { + "version": "3.3.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "10.4.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "8.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.2.0", + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "7.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "7.0.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/ini": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "7.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^6.0.0", + "npm-package-arg": "^12.0.0", + "promzard": "^2.0.0", + "read": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/ip-address": { + "version": "9.0.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "5.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "5.1.1", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^4.1.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/jackspeak": { + "version": "3.4.3", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/npm/node_modules/jsbn": { + "version": "1.1.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "9.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "7.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.1", + "@npmcli/installed-package-contents": "^3.0.0", + "binary-extensions": "^2.3.0", + "diff": "^5.1.0", + "minimatch": "^9.0.4", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "tar": "^6.2.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "9.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.1", + "@npmcli/run-script": "^9.0.1", + "ci-info": "^4.0.0", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "6.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmhook": { + "version": "11.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "8.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.1", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "10.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "ci-info": "^4.0.0", + "normalize-package-data": "^7.0.0", + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1", + "proc-log": "^5.0.0", + "semver": "^7.3.7", + "sigstore": "^3.0.0", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "8.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmversion": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.1", + "@npmcli/run-script": "^9.0.1", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "10.4.3", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "14.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "9.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "7.1.2", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "2.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-fetch": { + "version": "4.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minizlib": { + "version": "3.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "11.2.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "tinyglobby": "^0.2.12", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "8.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/normalize-package-data": { + "version": "7.0.0", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "7.1.1", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "12.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "9.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "10.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "11.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "18.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "3.0.0", + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "7.0.3", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/package-json-from-dist": { + "version": "1.0.1", + "inBundle": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/npm/node_modules/pacote": { + "version": "19.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/path-key": { + "version": "3.1.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/path-scurry": { + "version": "1.11.1", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/proc-log": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/proggy": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.2", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "4.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "^2.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.7.2", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/shebang-command": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/shebang-regex": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "4.1.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/sigstore": { + "version": "3.1.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { + "version": "3.1.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": { + "version": "2.0.0", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { + "version": "3.1.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { + "version": "2.1.1", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.8.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "8.0.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.2.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.5.0", + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.21", + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/sprintf-js": { + "version": "1.1.3", + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/npm/node_modules/ssri": { + "version": "12.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/string-width": { + "version": "4.2.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "9.4.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "6.2.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.14", + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "inBundle": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/unique-filename": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/unique-slug": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "6.0.1", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/which": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/which/node_modules/isexe": { + "version": "3.1.1", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/npm/node_modules/wrap-ansi": { + "version": "8.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/yallist": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-each-series": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", + "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", + "license": "MIT", + "dependencies": { + "p-timeout": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-filter": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz", + "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==", + "license": "MIT", + "dependencies": { + "p-map": "^7.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", + "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "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==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "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/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "license": "MIT" + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "license": "MIT", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "license": "MIT" + }, + "node_modules/path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", + "license": "MIT", + "dependencies": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/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/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "license": "ISC" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "license": "ISC" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "license": "MIT", + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "license": "MIT", + "dependencies": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-package-up/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-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/read-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/read-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/read-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/read-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/read-pkg-up/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0", + "peer": true + }, + "node_modules/registry-auth-token": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", + "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==", + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "license": "ISC" + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/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/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "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/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "license": "MIT", + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } + }, + "node_modules/seek-bzip/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/semantic-release": { + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.9.tgz", + "integrity": "sha512-phCkJ6pjDi9ANdhuF5ElS10GGdAKY6R1Pvt9lT3SFhOwM4T7QZE7MLpBDbNruUx/Q3gFD92/UOFringGipRqZA==", + "license": "MIT", + "dependencies": { + "@semantic-release/commit-analyzer": "^13.0.0-beta.1", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^11.0.0", + "@semantic-release/npm": "^12.0.2", + "@semantic-release/release-notes-generator": "^14.0.0-beta.1", + "aggregate-error": "^5.0.0", + "cosmiconfig": "^9.0.0", + "debug": "^4.0.0", + "env-ci": "^11.0.0", + "execa": "^9.0.0", + "figures": "^6.0.0", + "find-versions": "^6.0.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^4.0.0", + "hosted-git-info": "^8.0.0", + "import-from-esm": "^2.0.0", + "lodash-es": "^4.17.21", + "marked": "^15.0.0", + "marked-terminal": "^7.3.0", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-package-up": "^11.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^5.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" + }, + "bin": { + "semantic-release": "bin/semantic-release.js" + }, + "engines": { + "node": ">=20.8.1" + } + }, + "node_modules/semantic-release/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/semantic-release/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/semantic-release/node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/semantic-release/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/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-5.0.0.tgz", + "integrity": "sha512-0HbGtOm+S7T6NGQ/pxJSJipJvc4DK3FcRVMRkhsIwJDJ4Jcz5DQC1cPPzB5GhzyHjwttW878HaWQq46CkL3cqg==", + "deprecated": "Deprecated as the semver package now supports this built-in.", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver-regex": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/seon-lib-implementation": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/seon-lib-implementation/-/seon-lib-implementation-0.0.6.tgz", + "integrity": "sha512-EBw/5zvIP3DhbFl56aILoo58D1w+gO8YrwvuGGbLCW+7IQiiMqxqH385738x+jAPN5B0pUTwLGSXOuirdHLJVA==", + "license": "MIT", + "dependencies": { + "semantic-release": "^24.2.5" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "license": "ISC", + "peer": true + }, + "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/signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "license": "MIT", + "dependencies": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/signale/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/signale/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/signale/node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/snabbdom": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.1.tgz", + "integrity": "sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", + "license": "MIT", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "license": "MIT", + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length/node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "license": "MIT", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spark-generators-lib": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/spark-generators-lib/-/spark-generators-lib-1.27.0.tgz", + "integrity": "sha512-EjRZVQWxbM3RmoC50GzlB5NjDjLWENgzdONavfrHOexVfqYAqiLmyp2Mi6Q1wtAAgYlhEqKCgBbmSoAPWjcKoA==", + "license": "ISC" + }, + "node_modules/spark-leds-beta": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/spark-leds-beta/-/spark-leds-beta-0.2.8.tgz", + "integrity": "sha512-Y2UsSno6lP7mou+aVuHH/Le2XkcfzBTqfV9ZQzP02MJO1yvAURFcvxYg2w6UAHI2wt6ibRhDPA6SZjifRZ2jQA==", + "license": "Apache-2.0", + "dependencies": { + "@codingame/monaco-vscode-editor-service-override": "1.83.16", + "@codingame/monaco-vscode-keybindings-service-override": "1.83.16", + "chalk": "~5.3.0", + "commander": "~11.0.0", + "langium": "~3.0.0", + "leds-spark-lib": "^1.10.0", + "monaco-editor": "npm:@codingame/monaco-editor-treemended@1.83.16", + "monaco-editor-workers": "~0.44.0", + "monaco-editor-wrapper": "~3.5.0", + "monaco-languageclient": "~7.2.0", + "spark-generators-lib": "^1.0.13", + "sprotty": "^1.3.0", + "sprotty-vscode": "^1.0.0", + "sprotty-vscode-webview": "^1.0.0", + "tsup": "^8.4.0", + "vscode-languageclient": "~9.0.1", + "vscode-languageserver": "~9.0.1" + }, + "bin": { + "spark-cli": "bin/cli.js" + }, + "engines": { + "node": ">=18.0.0", + "vscode": "^1.67.0" + } + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-configuration-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-configuration-service-override/-/monaco-vscode-configuration-service-override-1.83.16.tgz", + "integrity": "sha512-zvfVrb1PP9XxsF4A6+VODbea4diMzvTyeDxQsvHHocJOZOrWhvHREl7TuVKu8e8ydUSfIpouZQZDP5Hyh10U6Q==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-environment-service-override": "1.83.16", + "@codingame/monaco-vscode-extensions-service-override": "1.83.16", + "@codingame/monaco-vscode-files-service-override": "1.83.16", + "@codingame/monaco-vscode-layout-service-override": "1.83.16", + "@codingame/monaco-vscode-quickaccess-service-override": "1.83.16", + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-configuration-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-environment-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-environment-service-override/-/monaco-vscode-environment-service-override-1.83.16.tgz", + "integrity": "sha512-W/60KsaHwWNEI6Dl9lld5CCYyQvoQjXpqPU3XT7CT2VKaeilL20M7sj0MLA8tJWAbFoNt0DrcvTyNC1CCD85/Q==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-environment-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-extensions-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-extensions-service-override/-/monaco-vscode-extensions-service-override-1.83.16.tgz", + "integrity": "sha512-zltPGafTUt/V1PRyGGuLlOMthF5vthBb8dPuu4+E/qlB31jc3ygj+DIFMbpqhtzXywBZeUyAn/aiXO4/b/sHFQ==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.83.16", + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16", + "vscode-semver": "npm:semver@=5.5.0" + } + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-extensions-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-layout-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-layout-service-override/-/monaco-vscode-layout-service-override-1.83.16.tgz", + "integrity": "sha512-DOHpZVqLP8RVDwQYPP3hDd+LPjxSyBbgPL3Ixd1X9LZSmY37bi95ILOPESqG306h2wQZhPzwNC+E7UNY3P/Ing==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-layout-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-quickaccess-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-quickaccess-service-override/-/monaco-vscode-quickaccess-service-override-1.83.16.tgz", + "integrity": "sha512-uO1xJKkoI7wvyOT+WvopA3Sehy9yLk5bUi+QAESZbXLhvVMutbl2mO1T0stgC7O3cPOJnNh9xIi/kexW2TswOQ==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-quickaccess-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-textmate-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-textmate-service-override/-/monaco-vscode-textmate-service-override-1.83.16.tgz", + "integrity": "sha512-DJ5jk+TsmTsFbvX2VaglwGimTPFdUGxNCxrpe8wsMHkNpB9oS90ZGREEnhK7zOaw/t8njBIzVg4AEsy1vPErEA==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.83.16", + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16", + "vscode-oniguruma": "1.7.0", + "vscode-textmate": "9.0.0" + } + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-textmate-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-theme-defaults-default-extension": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-theme-defaults-default-extension/-/monaco-vscode-theme-defaults-default-extension-1.83.16.tgz", + "integrity": "sha512-vCf1yIBjubLfhm6Hv8uQ0Dv5T6CvSvGwvS9BtuUQg9oesbFglAozlDGZtZKDTheywYKaqvRCLsi5ajkuik9tBg==", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-theme-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-theme-service-override/-/monaco-vscode-theme-service-override-1.83.16.tgz", + "integrity": "sha512-re8r5MaMvPeB9eS4eNUxPeus6pZYBafq991Eu0/X0XQb3xMOu7T5Fq4QzBtLr3/xdyJ9zSiQZHUoOv4QAh7xjQ==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.83.16", + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/spark-leds-beta/node_modules/@codingame/monaco-vscode-theme-service-override/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/spark-leds-beta/node_modules/monaco-editor-wrapper": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/monaco-editor-wrapper/-/monaco-editor-wrapper-3.5.0.tgz", + "integrity": "sha512-rURrYi9rmCrIFwFOMn0bSq2lMyQgMryhIf40GDNcuOBcKrZRG9h6jAt/kaPC0S4/8arRgr9OA+8N4Rg4hDMZgA==", + "deprecated": "The development of monaco-wrapper-editor will not be continued. Please use https://www.npmjs.com/package/monaco-languageclient v10+ from now on.", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-configuration-service-override": "~1.83.16", + "@codingame/monaco-vscode-editor-service-override": "~1.83.16", + "@codingame/monaco-vscode-textmate-service-override": "~1.83.16", + "@codingame/monaco-vscode-theme-defaults-default-extension": "~1.83.16", + "@codingame/monaco-vscode-theme-service-override": "~1.83.16", + "monaco-editor": "npm:@codingame/monaco-editor-treemended@>=1.83.16 <1.84.0", + "monaco-languageclient": "~7.2.0", + "vscode": "npm:@codingame/monaco-vscode-api@>=1.83.16 <1.84.0", + "vscode-languageclient": "~9.0.1", + "vscode-languageserver-protocol": "~3.17.5", + "vscode-ws-jsonrpc": "~3.1.0" + }, + "peerDependencies": { + "monaco-languageclient": "~7.2.0", + "vscode-ws-jsonrpc": "~3.1.0" + } + }, + "node_modules/spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", + "license": "MIT" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "license": "CC0-1.0" + }, + "node_modules/split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", + "license": "ISC", + "dependencies": { + "through2": "~2.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/sprotty": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sprotty/-/sprotty-1.4.0.tgz", + "integrity": "sha512-QGZZQAM2pOa1QxJUG05Ox76RJOKuvKloT1nCkvs6SD5w/HfkcL0mjq1Om1+fb5NAalDzurrJL6agKUReST3TFw==", + "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)", + "dependencies": { + "autocompleter": "^9.1.2", + "file-saver": "^2.0.5", + "inversify": "^6.1.3", + "snabbdom": "~3.5.1", + "sprotty-protocol": "^1.4.0", + "tinyqueue": "^2.0.3" + } + }, + "node_modules/sprotty-protocol": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sprotty-protocol/-/sprotty-protocol-1.4.0.tgz", + "integrity": "sha512-+AAskW3Mzcq5UhMnummp4wwJ1dYdgT7/utmWoHtjfrK7JTJq9G/VWWlHnTnQGzHHyma03Loy2AozToXoArQuAQ==", + "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)" + }, + "node_modules/sprotty-vscode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/sprotty-vscode/-/sprotty-vscode-1.1.0.tgz", + "integrity": "sha512-Fk0VRw8s4M/nLqkV/Ot74KF5wF0BSjC+v+YJQ4256n7/eWTcOZ0imHmKR0tDQAsARM2FCQMOiyfuZQc/iSzdtA==", + "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)", + "dependencies": { + "path": "^0.12.7", + "sprotty-vscode-protocol": "^1.1.0", + "vscode-languageclient": "^9.0.1", + "vscode-messenger": "^0.5.1" + }, + "engines": { + "vscode": "^1.46.0" + } + }, + "node_modules/sprotty-vscode-protocol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/sprotty-vscode-protocol/-/sprotty-vscode-protocol-1.1.0.tgz", + "integrity": "sha512-8/BQ5FixfgEiwnWiH8Or0nXHVm5oDT3QsUHFHqJJnk9kO7ucRUyPS1IbOz5yYNa6GykjjoOdCs5fTPSGnjlaiw==", + "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)", + "dependencies": { + "sprotty-protocol": "^1.0.0", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-messenger-common": "^0.5.1" + } + }, + "node_modules/sprotty-vscode-webview": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/sprotty-vscode-webview/-/sprotty-vscode-webview-1.1.0.tgz", + "integrity": "sha512-gSoZwhgfs3Vhme0K6uJobqWZ4W4lwBd6Mq8d5IoSeunE6G8CxtrqrBGa3a7QFXXMus3bfuhZNMgYo14APzfbqQ==", + "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)", + "dependencies": { + "sprotty": "^1.0.0", + "sprotty-vscode-protocol": "^1.1.0", + "vscode-messenger-webview": "^0.5.1", + "vscode-uri": "^3.1.0" + } + }, + "node_modules/sprotty-vscode-webview/node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "license": "MIT" + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "license": "MIT", + "peer": true + }, + "node_modules/stat-mode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "license": "MIT" + }, + "node_modules/stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "license": "MIT", + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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-ansi-cjs": { + "name": "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-ansi-cjs/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/strip-ansi/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/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "license": "MIT", + "dependencies": { + "is-natural-number": "^4.0.1" + } + }, + "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", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "license": "MIT", + "peer": true, + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/super-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.0.0.tgz", + "integrity": "sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg==", + "license": "MIT", + "dependencies": { + "function-timeout": "^1.0.1", + "time-span": "^5.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "license": "MIT", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tar-stream/node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/tempy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", + "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", + "license": "MIT", + "dependencies": { + "is-stream": "^3.0.0", + "temp-dir": "^3.0.0", + "type-fest": "^2.12.2", + "unique-string": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/time-span": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", + "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", + "license": "MIT", + "dependencies": { + "convert-hrtime": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "license": "MIT", + "peer": true + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "license": "MIT", + "peer": true, + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyqueue": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", + "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==", + "license": "ISC" + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-buffer/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/traverse": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", + "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsup": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.0.tgz", + "integrity": "sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==", + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.25.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "0.8.0-beta.0", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tsup/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/tsup/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/tsup/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "deprecated": "The work that was done in this beta branch won't be included in future versions", + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "license": "MIT" + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "license": "MIT", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT", + "optional": true + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "license": "ISC" + }, + "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/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "license": "MIT", + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "license": "MIT", + "dependencies": { + "inherits": "2.0.3" + } + }, + "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/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vite": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", + "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "license": "MIT", + "peer": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.83.16.tgz", + "integrity": "sha512-8+jBcXKkvqfx5mVfaUQ+TeORIw2zGRASoKCavZCO/BSpnTCrPVTFyT2HN35+Hwun8eGqoWaNaKYunupLiBZRWg==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-environment-service-override": "1.83.16", + "@codingame/monaco-vscode-extensions-service-override": "1.83.16", + "@codingame/monaco-vscode-files-service-override": "1.83.16", + "@codingame/monaco-vscode-layout-service-override": "1.83.16", + "@codingame/monaco-vscode-quickaccess-service-override": "1.83.16", + "monaco-editor": "0.44.0", + "vscode-semver": "npm:semver@=5.5.0" + }, + "bin": { + "monaco-treemending": "monaco-treemending.js" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageclient": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz", + "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==", + "license": "MIT", + "dependencies": { + "minimatch": "^5.1.0", + "semver": "^7.3.7", + "vscode-languageserver-protocol": "3.17.5" + }, + "engines": { + "vscode": "^1.82.0" + } + }, + "node_modules/vscode-languageclient/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/vscode-languageclient/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/vscode-messenger": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/vscode-messenger/-/vscode-messenger-0.5.1.tgz", + "integrity": "sha512-pHexyKLr6FgVkdXi9NcCgygikVkFsbpk9PoObT4JXSQfnosNLTWS2NTdGJ+nv/xhUw5OodmVId/oJwNU7HxoQw==", + "license": "MIT", + "dependencies": { + "vscode-messenger-common": "^0.5" + } + }, + "node_modules/vscode-messenger-common": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/vscode-messenger-common/-/vscode-messenger-common-0.5.1.tgz", + "integrity": "sha512-YJRUdK278/K7vNyhVoePINOHmz3xjQFQbSiuNXCm3+GfQ6NSmjjWTpumAYAzNs05HKAeF9glU532livdwc3W0A==", + "license": "MIT" + }, + "node_modules/vscode-messenger-webview": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/vscode-messenger-webview/-/vscode-messenger-webview-0.5.1.tgz", + "integrity": "sha512-3IXFORcjD3c9khECdqRUeBh05mt0AZA/86FhY/MlCRB2YHGzqpJeD/5rRX92fO2M42rUjXLi5bnzmXSvVGXadw==", + "license": "MIT", + "dependencies": { + "vscode-messenger-common": "^0.5" + } + }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "license": "MIT" + }, + "node_modules/vscode-semver": { + "name": "semver", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/vscode-textmate": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz", + "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg==", + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "license": "MIT" + }, + "node_modules/vscode-ws-jsonrpc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-ws-jsonrpc/-/vscode-ws-jsonrpc-3.1.0.tgz", + "integrity": "sha512-Z3as2O9rml9rYMYjZQABeCtYEqmRa0TJRUOe6MElXDswNvXiJnu7+vqyy4c6GX+/8SfI0C+sDBJ7naM5wHz0gA==", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "~8.2.0" + }, + "engines": { + "node": ">=16.11.0", + "npm": ">=8.0.0" + } + }, + "node_modules/vscode/node_modules/@codingame/monaco-vscode-environment-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-environment-service-override/-/monaco-vscode-environment-service-override-1.83.16.tgz", + "integrity": "sha512-W/60KsaHwWNEI6Dl9lld5CCYyQvoQjXpqPU3XT7CT2VKaeilL20M7sj0MLA8tJWAbFoNt0DrcvTyNC1CCD85/Q==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/vscode/node_modules/@codingame/monaco-vscode-extensions-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-extensions-service-override/-/monaco-vscode-extensions-service-override-1.83.16.tgz", + "integrity": "sha512-zltPGafTUt/V1PRyGGuLlOMthF5vthBb8dPuu4+E/qlB31jc3ygj+DIFMbpqhtzXywBZeUyAn/aiXO4/b/sHFQ==", + "license": "MIT", + "dependencies": { + "@codingame/monaco-vscode-files-service-override": "1.83.16", + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16", + "vscode-semver": "npm:semver@=5.5.0" + } + }, + "node_modules/vscode/node_modules/@codingame/monaco-vscode-layout-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-layout-service-override/-/monaco-vscode-layout-service-override-1.83.16.tgz", + "integrity": "sha512-DOHpZVqLP8RVDwQYPP3hDd+LPjxSyBbgPL3Ixd1X9LZSmY37bi95ILOPESqG306h2wQZhPzwNC+E7UNY3P/Ing==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/vscode/node_modules/@codingame/monaco-vscode-quickaccess-service-override": { + "version": "1.83.16", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-quickaccess-service-override/-/monaco-vscode-quickaccess-service-override-1.83.16.tgz", + "integrity": "sha512-uO1xJKkoI7wvyOT+WvopA3Sehy9yLk5bUi+QAESZbXLhvVMutbl2mO1T0stgC7O3cPOJnNh9xIi/kexW2TswOQ==", + "license": "MIT", + "dependencies": { + "monaco-editor": "0.44.0", + "vscode": "npm:@codingame/monaco-vscode-api@1.83.16" + } + }, + "node_modules/vscode/node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz", + "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-sfc": "3.5.22", + "@vue/runtime-dom": "3.5.22", + "@vue/server-renderer": "3.5.22", + "@vue/shared": "3.5.22" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/ware": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ware/-/ware-1.3.0.tgz", + "integrity": "sha512-Y2HUDMktriUm+SR2gZWxlrszcgtXExlhQYZ8QJNYbl22jum00KIUcHJ/h/sdAXhWTJcbSkiMYN9Z2tWbWYSrrw==", + "license": "MIT", + "dependencies": { + "wrap-fn": "^0.1.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "license": "ISC" + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "license": "MIT", + "peer": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-fn": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz", + "integrity": "sha512-xDLdGx0M8JQw9QDAC9s5NUxtg9MI09F6Vbxa2LYoSoCvzJnx2n81YMIfykmXEGsUvuLaxnblJTzhSOjUOX37ag==", + "license": "MIT", + "dependencies": { + "co": "3.1.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/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/docs/andes/package.json b/docs/andes/package.json new file mode 100644 index 0000000..a7fcbce --- /dev/null +++ b/docs/andes/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "andes-leds-tools": "^0.4.9" + } +} diff --git a/docs/made/.gitignore b/docs/made/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/docs/made/.gitignore @@ -0,0 +1 @@ +.env diff --git a/docs/made/01_overview.md b/docs/made/01_overview.md new file mode 100644 index 0000000..fbbfa83 --- /dev/null +++ b/docs/made/01_overview.md @@ -0,0 +1,80 @@ +# 📊 Visão Geral do Projeto + +Conversão automática do backlog.md para um arquivo .made contendo Project, Backlog, TimeBoxes (sprints), Roadmap e Milestones. +* Data de Início: 2025-10-02 +* Data de Planejado: 2025-11-30 +* Data de Finalização: + +Conversão automática do backlog.md para um arquivo .made contendo Project, Backlog, TimeBoxes (sprints), Roadmap e Milestones. +## Métricas Consolidadas + +| Sprint | Período | Duração | Total Tasks | Concluídas | Em Progresso | Pendentes | Velocidade | Eficiência | +|--------|---------|----------|-------------|------------|--------------|-----------|------------|------------| +| Sprint 1: Memória Inicial com LangChain | 01/10 - 07/10 | 6 dias | 3 | 3 (100.0%) | 0 | 0 | 0.5/dia | 100.0% | +| Sprint 2: Visualização e Gráficos | 08/10 - 14/10 | 6 dias | 4 | 4 (100.0%) | 0 | 0 | 0.67/dia | 100.0% | +| Sprint 3: Padronização da IA - Parte 1 | 15/10 - 21/10 | 6 dias | 1 | 1 (100.0%) | 0 | 0 | 0.17/dia | 100.0% | +| Sprint 4: Interface e UX | 22/10 - 28/10 | 6 dias | 1 | 1 (100.0%) | 0 | 0 | 0.17/dia | 100.0% | +| Sprint 5: Autenticação Segura | 29/10 - 04/11 | 6 dias | 2 | 2 (100.0%) | 0 | 0 | 0.33/dia | 100.0% | +| Sprint 6: Gerenciamento de Token - Parte 1 | 05/11 - 11/11 | 6 dias | 2 | 2 (100.0%) | 0 | 0 | 0.33/dia | 100.0% | +| Sprint 7: Gerenciamento de Token - Parte 2 | 12/11 - 18/11 | 6 dias | 2 | 2 (100.0%) | 0 | 0 | 0.33/dia | 100.0% | +| Sprint 8: Estabilização e Revisão Final | 19/11 - 29/11 | 10 dias | 2 | 2 (100.0%) | 0 | 0 | 0.2/dia | 100.0% | + +## Análise Geral + +- **Total de Sprints:** 8 +- **Total de Tasks:** 17 +- **Taxa de Conclusão:** 100.0% + +### Notas +- Período Total: 01/10 - 29/11 +- Média de Duração das Sprints: 7 dias + +*Última atualização: novembro de 2025* + +## Cumulative Flow +![ Cumulative Flow](./project-cfd.svg) + + + + ## Previsão do Projeto + +## 🎯 Conclusão Principal + +### ✅ PROJETO PROVAVELMENTE SERÁ CONCLUÍDO NO PRAZO + +- **Probabilidade de conclusão no prazo**: 100.0% +- **Data mais provável de conclusão**: dom., 09/11/2025 +- **Dias em relação ao planejado**: -20 dias +- **Status**: ✅ Antes do Prazo + +### 📊 Métricas do Projeto + +| Métrica | Valor | Status | +|---------|--------|--------| +| Velocidade Atual | 2.1 tarefas/dia | ✅ | +| Velocidade Necessária | 0.0 tarefas/dia | - | +| Dias Restantes | 20 dias | - | +| Tarefas Restantes | 0 tarefas | - | + +### 📅 Previsões de Data de Conclusão + +| Data | Probabilidade | Status | Observação | +|------|---------------|---------|------------| +| dom., 09/11/2025 | 100.0% | ✅ Antes do Prazo | 📍 Data mais provável | + +## 💡 Recomendações + +1. ✅ Manter o ritmo atual de 2.1 tarefas/dia +2. ✅ Continuar monitorando impedimentos +3. ✅ Planejar próximas sprints com antecedência + +## ℹ️ Informações do Projeto + +- **Total de Sprints**: 8 +- **Início**: qua., 01/10/2025 +- **Término Planejado**: sáb., 29/11/2025 +- **Total de Tarefas**: 17 +- **Simulações Realizadas**: 10.000 + +--- +*Relatório gerado em 10/11/2025, 10:17:42* \ No newline at end of file diff --git a/docs/made/02_backlogs.md b/docs/made/02_backlogs.md new file mode 100644 index 0000000..3acf4c2 --- /dev/null +++ b/docs/made/02_backlogs.md @@ -0,0 +1,2 @@ +# 📋 Backlogs + diff --git a/docs/made/03_roadmap.md b/docs/made/03_roadmap.md new file mode 100644 index 0000000..a980cc0 --- /dev/null +++ b/docs/made/03_roadmap.md @@ -0,0 +1,2 @@ +# 🎯 Roadmaps + diff --git a/docs/made/_category_.json b/docs/made/_category_.json new file mode 100644 index 0000000..ded9b59 --- /dev/null +++ b/docs/made/_category_.json @@ -0,0 +1,10 @@ + + { + "label": "Gestão", + "position": 1, + "link": { + "type": "generated-index", + "description": "Documentos relativos ao planejamento." + } + } + \ No newline at end of file diff --git a/docs/made/db/backlog.json b/docs/made/db/backlog.json new file mode 100644 index 0000000..3a4b0de --- /dev/null +++ b/docs/made/db/backlog.json @@ -0,0 +1,3 @@ +{ + "data": [] +} \ No newline at end of file diff --git a/docs/made/db/issue.json b/docs/made/db/issue.json new file mode 100644 index 0000000..eb05646 --- /dev/null +++ b/docs/made/db/issue.json @@ -0,0 +1,249 @@ +{ + "data": [ + { + "id": "productbacklog.feature1_autenticacao", + "title": "Autenticação de Usuário e Controle de Acesso", + "description": "Desenvolvimento completo do subsistema de autenticação com Registro, Login seguro e Controle de Acesso (ACL)", + "type": "epic", + "issues": [ + { + "id": "productbacklog.feature1_autenticacao.implementregistration", + "title": "Implementar Sistema de Registro", + "description": "Formulário de registro, validações e persistência segura", + "type": "atomicuserstory", + "issues": [ + { + "id": "productbacklog.feature1_autenticacao.implementregistration.createregistrationform", + "title": "Criar formulário de registro", + "description": "Frontend e validações", + "type": "taskbacklog", + "depends": [] + }, + { + "id": "productbacklog.feature1_autenticacao.implementregistration.setupauthbackend", + "title": "Criar endpoints de autenticação", + "description": "Endpoints de registro e login", + "type": "taskbacklog", + "depends": [] + } + ], + "depends": [] + }, + { + "id": "productbacklog.feature1_autenticacao.implementacl", + "title": "Implementar ACL", + "description": "Permissões para visualizar/editar somente dados próprios", + "type": "atomicuserstory", + "issues": [ + { + "id": "productbacklog.feature1_autenticacao.implementacl.defineroles", + "title": "Definir papéis e permissões", + "description": "Modelagem de roles e permissões", + "type": "taskbacklog", + "depends": [] + }, + { + "id": "productbacklog.feature1_autenticacao.implementacl.applyacl", + "title": "Aplicar ACL aos recursos", + "description": "Filtrar dados por proprietário", + "type": "taskbacklog", + "depends": [] + } + ], + "depends": [] + } + ], + "depends": [] + }, + { + "id": "productbacklog.feature2_token", + "title": "Gerenciamento Dinâmico de Token", + "description": "Funcionalidade na UI para inserir, visualizar e atualizar token de acesso ao repositório", + "type": "epic", + "issues": [ + { + "id": "productbacklog.feature2_token.tokenui", + "title": "Interface de gerenciamento de token", + "description": "Entrada segura para tokens, visualização parcial e atualização", + "type": "atomicuserstory", + "issues": [ + { + "id": "productbacklog.feature2_token.tokenui.createtokenform", + "title": "Criar formulário de token", + "description": "Interface para entrada de tokens", + "type": "taskbacklog", + "depends": [] + }, + { + "id": "productbacklog.feature2_token.tokenui.tokenvalidation", + "title": "Validar token", + "description": "Verificar formato e validade do token", + "type": "taskbacklog", + "depends": [] + } + ], + "depends": [] + }, + { + "id": "productbacklog.feature2_token.securestorage", + "title": "Armazenamento Seguro", + "description": "Criptografar e armazenar tokens de forma segura", + "type": "atomicuserstory", + "issues": [ + { + "id": "productbacklog.feature2_token.securestorage.implementencryption", + "title": "Implementar criptografia", + "description": "Criptografar tokens antes de salvar", + "type": "taskbacklog", + "depends": [] + }, + { + "id": "productbacklog.feature2_token.securestorage.storagelayer", + "title": "Camada de armazenamento", + "description": "Persistir tokens criptografados", + "type": "taskbacklog", + "depends": [] + } + ], + "depends": [] + } + ], + "depends": [] + }, + { + "id": "productbacklog.feature3_memoria", + "title": "Memória Contextual com LangChain", + "description": "Camada de memória para interações com IA usando LangChain para contexto contínuo", + "type": "epic", + "issues": [ + { + "id": "productbacklog.feature3_memoria.initialmemory", + "title": "Memória inicial LangChain", + "description": "Integração básica para armazenar e recuperar contexto", + "type": "atomicuserstory", + "issues": [ + { + "id": "productbacklog.feature3_memoria.initialmemory.setuplangchain", + "title": "Configurar LangChain", + "description": "Instalar e configurar biblioteca", + "type": "taskbacklog", + "depends": [] + }, + { + "id": "productbacklog.feature3_memoria.initialmemory.memorystore", + "title": "Armazenamento de memória", + "description": "Criar store para histórico", + "type": "taskbacklog", + "depends": [] + }, + { + "id": "productbacklog.feature3_memoria.initialmemory.integratechat", + "title": "Integrar com chat", + "description": "Usar contexto nas respostas", + "type": "taskbacklog", + "depends": [] + } + ], + "depends": [] + } + ], + "depends": [] + }, + { + "id": "productbacklog.feature4_graficos", + "title": "Geração de Gráficos e Visualização de Dados", + "description": "Capacidade de gerar gráficos usando Matplotlib/Pandas e exibir na interface do chat", + "type": "epic", + "issues": [ + { + "id": "productbacklog.feature4_graficos.charts", + "title": "Implementar geração de gráficos", + "description": "API/backend para gerar imagens e exibir no chat", + "type": "atomicuserstory", + "issues": [ + { + "id": "productbacklog.feature4_graficos.charts.setuplibraries", + "title": "Configurar bibliotecas", + "description": "Instalar Matplotlib, Pandas, Plotly", + "type": "taskbacklog", + "depends": [] + }, + { + "id": "productbacklog.feature4_graficos.charts.datapipeline", + "title": "Pipeline de dados", + "description": "Processar dados para visualização", + "type": "taskbacklog", + "depends": [] + }, + { + "id": "productbacklog.feature4_graficos.charts.chartgeneration", + "title": "Geração de gráficos", + "description": "Criar diferentes tipos de gráficos", + "type": "taskbacklog", + "depends": [] + }, + { + "id": "productbacklog.feature4_graficos.charts.chatintegration", + "title": "Integração com chat", + "description": "Exibir gráficos nas respostas", + "type": "taskbacklog", + "depends": [] + } + ], + "depends": [] + } + ], + "depends": [] + }, + { + "id": "productbacklog.feature5_ui", + "title": "Design de Frontend e Usabilidade (UX)", + "description": "Interface de Usuário responsiva e moderna para Login, Cadastro e Gerenciamento de Token", + "type": "epic", + "issues": [ + { + "id": "productbacklog.feature5_ui.createauthui", + "title": "Criar UI de Autenticação e Token", + "description": "Design responsivo e fluxos simplificados para login, cadastro e gerenciamento de token", + "type": "atomicuserstory", + "issues": [ + { + "id": "productbacklog.feature5_ui.createauthui.authandtokenui", + "title": "UI de Autenticação e Token", + "description": "Criar telas de login, cadastro e gerenciamento de token com design responsivo", + "type": "taskbacklog", + "depends": [] + } + ], + "depends": [] + } + ], + "depends": [] + }, + { + "id": "productbacklog.feature6_padraorespostas", + "title": "Padronização de Respostas da IA", + "description": "Sistema de controle de parâmetros (temperature, top_p, estilo) para respostas consistentes da IA", + "type": "epic", + "issues": [ + { + "id": "productbacklog.feature6_padraorespostas.responseparams", + "title": "Sistema de parâmetros da IA", + "description": "Permitir pelo código controlar parâmetros de resposta para padronização", + "type": "atomicuserstory", + "issues": [ + { + "id": "productbacklog.feature6_padraorespostas.responseparams.aiintegration", + "title": "Integração com IA", + "description": "Aplicar parâmetros nas chamadas", + "type": "taskbacklog", + "depends": [] + } + ], + "depends": [] + } + ], + "depends": [] + } + ] +} \ No newline at end of file diff --git a/docs/made/db/project.json b/docs/made/db/project.json new file mode 100644 index 0000000..d59e0a2 --- /dev/null +++ b/docs/made/db/project.json @@ -0,0 +1,12 @@ +{ + "data": [ + { + "id": "backlogproject", + "name": "Backlog de Features - MADE", + "description": "Conversão automática do backlog.md para um arquivo .made contendo Project, Backlog, TimeBoxes (sprints), Roadmap e Milestones.", + "startDate": "2025-10-02", + "dueDate": "2025-11-30", + "completedDate": "" + } + ] +} \ No newline at end of file diff --git a/docs/made/db/roadmap.json b/docs/made/db/roadmap.json new file mode 100644 index 0000000..3a4b0de --- /dev/null +++ b/docs/made/db/roadmap.json @@ -0,0 +1,3 @@ +{ + "data": [] +} \ No newline at end of file diff --git a/docs/made/db/team.json b/docs/made/db/team.json new file mode 100644 index 0000000..e1af883 --- /dev/null +++ b/docs/made/db/team.json @@ -0,0 +1,53 @@ +{ + "data": [ + { + "id": "ProjectTeam", + "name": "Equipe do Projeto", + "description": "Equipe responsável pela gestão do projeto", + "teamMembers": [ + { + "id": "livia", + "name": "liviahombre", + "email": "liviahombre@gmail.com" + }, + { + "id": "thiago", + "name": "ThiagoFabiano", + "email": "thiagoffabiano@gmail.com" + }, + { + "id": "pedro", + "name": "bedrohenr", + "email": "ferfonhp@gmail.com" + }, + { + "id": "felipe", + "name": "FeLiXp90", + "email": "ferfonhp@gmail.com" + } + ] + }, + { + "id": "DevelelopmentTeam", + "name": "Equipe de Gestão", + "description": "Equipe responsável pelas features descritas no backlog", + "teamMembers": [ + { + "id": "sofia", + "name": "sofianasilva", + "email": "sofianascimento307@gmail.com" + }, + { + "id": "alicia", + "name": "aliciacapo", + "email": "alicia.caporrali@gmail.com" + }, + { + "id": "vitor", + "name": "nascimentoVitor10", + "email": "vitorramosnascimento10@gmail.com" + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/made/db/timebox.json b/docs/made/db/timebox.json new file mode 100644 index 0000000..8ce3f57 --- /dev/null +++ b/docs/made/db/timebox.json @@ -0,0 +1,407 @@ +{ + "data": [ + { + "id": "Sprint1", + "name": "Sprint 1: Memória Inicial com LangChain", + "description": "02/10/2025 -- 08/10/2025", + "startDate": "2025-10-02", + "endDate": "2025-10-08", + "status": "IN_PROGRESS", + "sprintItems": [ + { + "id": "feature3_memoria.initialmemory.setuplangchain", + "assignee": { + "id": "alicia", + "name": "aliciacapo", + "email": "alicia.caporrali@gmail.com" + }, + "issue": { + "id": "feature3_memoria.initialmemory.setuplangchain", + "title": "Configurar LangChain", + "description": "Instalar e configurar biblioteca", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-02", + "dueDate": "2025-10-08", + "status": "DOING" + }, + { + "id": "feature3_memoria.initialmemory.memorystore", + "assignee": { + "id": "alicia", + "name": "aliciacapo", + "email": "alicia.caporrali@gmail.com" + }, + "issue": { + "id": "feature3_memoria.initialmemory.memorystore", + "title": "Armazenamento de memória", + "description": "Criar store para histórico", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-02", + "dueDate": "2025-10-08", + "status": "DOING" + }, + { + "id": "feature3_memoria.initialmemory.integratechat", + "assignee": { + "id": "alicia", + "name": "aliciacapo", + "email": "alicia.caporrali@gmail.com" + }, + "issue": { + "id": "feature3_memoria.initialmemory.integratechat", + "title": "Integrar com chat", + "description": "Usar contexto nas respostas", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-02", + "dueDate": "2025-10-08", + "status": "DOING" + } + ] + }, + { + "id": "Sprint2", + "name": "Sprint 2: Visualização e Gráficos", + "description": "09/10/2025 -- 15/10/2025", + "startDate": "2025-10-09", + "endDate": "2025-10-15", + "status": "PLANNED", + "sprintItems": [ + { + "id": "feature4_graficos.charts.setuplibraries", + "assignee": { + "id": "sofia", + "name": "sofianasilva", + "email": "sofianascimento307@gmail.com" + }, + "issue": { + "id": "feature4_graficos.charts.setuplibraries", + "title": "Configurar bibliotecas", + "description": "Instalar Matplotlib, Pandas, Plotly", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-09", + "dueDate": "2025-10-15", + "status": "TODO" + }, + { + "id": "feature4_graficos.charts.datapipeline", + "assignee": { + "id": "sofia", + "name": "sofianasilva", + "email": "sofianascimento307@gmail.com" + }, + "issue": { + "id": "feature4_graficos.charts.datapipeline", + "title": "Pipeline de dados", + "description": "Processar dados para visualização", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-09", + "dueDate": "2025-10-15", + "status": "TODO" + }, + { + "id": "feature4_graficos.charts.chartgeneration", + "assignee": { + "id": "sofia", + "name": "sofianasilva", + "email": "sofianascimento307@gmail.com" + }, + "issue": { + "id": "feature4_graficos.charts.chartgeneration", + "title": "Geração de gráficos", + "description": "Criar diferentes tipos de gráficos", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-09", + "dueDate": "2025-10-15", + "status": "TODO" + }, + { + "id": "feature4_graficos.charts.chatintegration", + "assignee": { + "id": "sofia", + "name": "sofianasilva", + "email": "sofianascimento307@gmail.com" + }, + "issue": { + "id": "feature4_graficos.charts.chatintegration", + "title": "Integração com chat", + "description": "Exibir gráficos nas respostas", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-09", + "dueDate": "2025-10-15", + "status": "TODO" + } + ] + }, + { + "id": "Sprint3", + "name": "Sprint 3: Padronização da IA - Parte 1", + "description": "16/10/2025 -- 22/10/2025", + "startDate": "2025-10-16", + "endDate": "2025-10-22", + "status": "PLANNED", + "sprintItems": [ + { + "id": "feature6_padraorespostas.responseparams.aiintegration", + "assignee": { + "id": "vitor", + "name": "nascimentoVitor10", + "email": "vitorramosnascimento10@gmail.com" + }, + "issue": { + "id": "feature6_padraorespostas.responseparams.aiintegration", + "title": "Integração com IA", + "description": "Aplicar parâmetros nas chamadas", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-16", + "dueDate": "2025-10-22", + "status": "TODO" + } + ] + }, + { + "id": "Sprint4", + "name": "Sprint 4: Interface e UX", + "description": "23/10/2025 -- 29/10/2025", + "startDate": "2025-10-23", + "endDate": "2025-10-29", + "status": "PLANNED", + "sprintItems": [ + { + "id": "feature5_ui.createauthui.authandtokenui", + "assignee": { + "id": "alicia", + "name": "aliciacapo", + "email": "alicia.caporrali@gmail.com" + }, + "issue": { + "id": "feature5_ui.createauthui.authandtokenui", + "title": "UI de Autenticação e Token", + "description": "Criar telas de login, cadastro e gerenciamento de token com design responsivo", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-23", + "dueDate": "2025-10-29", + "status": "TODO" + } + ] + }, + { + "id": "Sprint5", + "name": "Sprint 5: Autenticação Segura", + "description": "30/10/2025 -- 05/11/2025", + "startDate": "2025-10-30", + "endDate": "2025-11-05", + "status": "PLANNED", + "sprintItems": [ + { + "id": "feature1_autenticacao.implementregistration.createregistrationform", + "assignee": { + "id": "sofia", + "name": "sofianasilva", + "email": "sofianascimento307@gmail.com" + }, + "issue": { + "id": "feature1_autenticacao.implementregistration.createregistrationform", + "title": "Criar formulário de registro", + "description": "Frontend e validações", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-30", + "dueDate": "2025-11-05", + "status": "TODO" + }, + { + "id": "feature1_autenticacao.implementregistration.setupauthbackend", + "assignee": { + "id": "sofia", + "name": "sofianasilva", + "email": "sofianascimento307@gmail.com" + }, + "issue": { + "id": "feature1_autenticacao.implementregistration.setupauthbackend", + "title": "Criar endpoints de autenticação", + "description": "Endpoints de registro e login", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-10-30", + "dueDate": "2025-11-05", + "status": "TODO" + } + ] + }, + { + "id": "Sprint6", + "name": "Sprint 6: Gerenciamento de Token - Parte 1", + "description": "06/11/2025 -- 12/11/2025", + "startDate": "2025-11-06", + "endDate": "2025-11-12", + "status": "PLANNED", + "sprintItems": [ + { + "id": "feature2_token.tokenui.createtokenform", + "assignee": { + "id": "vitor", + "name": "nascimentoVitor10", + "email": "vitorramosnascimento10@gmail.com" + }, + "issue": { + "id": "feature2_token.tokenui.createtokenform", + "title": "Criar formulário de token", + "description": "Interface para entrada de tokens", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-11-06", + "dueDate": "2025-11-12", + "status": "TODO" + }, + { + "id": "feature2_token.tokenui.tokenvalidation", + "assignee": { + "id": "vitor", + "name": "nascimentoVitor10", + "email": "vitorramosnascimento10@gmail.com" + }, + "issue": { + "id": "feature2_token.tokenui.tokenvalidation", + "title": "Validar token", + "description": "Verificar formato e validade do token", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-11-06", + "dueDate": "2025-11-12", + "status": "TODO" + } + ] + }, + { + "id": "Sprint7", + "name": "Sprint 7: Gerenciamento de Token - Parte 2", + "description": "13/11/2025 -- 19/11/2025", + "startDate": "2025-11-13", + "endDate": "2025-11-19", + "status": "PLANNED", + "sprintItems": [ + { + "id": "feature2_token.securestorage.implementencryption", + "assignee": { + "id": "alicia", + "name": "aliciacapo", + "email": "alicia.caporrali@gmail.com" + }, + "issue": { + "id": "feature2_token.securestorage.implementencryption", + "title": "Implementar criptografia", + "description": "Criptografar tokens antes de salvar", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-11-13", + "dueDate": "2025-11-19", + "status": "TODO" + }, + { + "id": "feature2_token.securestorage.storagelayer", + "assignee": { + "id": "alicia", + "name": "aliciacapo", + "email": "alicia.caporrali@gmail.com" + }, + "issue": { + "id": "feature2_token.securestorage.storagelayer", + "title": "Camada de armazenamento", + "description": "Persistir tokens criptografados", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-11-13", + "dueDate": "2025-11-19", + "status": "TODO" + } + ] + }, + { + "id": "Sprint8", + "name": "Sprint 8: Estabilização e Revisão Final", + "description": "20/11/2025 -- 30/11/2025", + "startDate": "2025-11-20", + "endDate": "2025-11-30", + "status": "PLANNED", + "sprintItems": [ + { + "id": "feature1_autenticacao.implementacl.defineroles", + "assignee": { + "id": "sofia", + "name": "sofianasilva", + "email": "sofianascimento307@gmail.com" + }, + "issue": { + "id": "feature1_autenticacao.implementacl.defineroles", + "title": "Definir papéis e permissões", + "description": "Modelagem de roles e permissões", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-11-20", + "dueDate": "2025-11-30", + "status": "TODO" + }, + { + "id": "feature1_autenticacao.implementacl.applyacl", + "assignee": { + "id": "sofia", + "name": "sofianasilva", + "email": "sofianascimento307@gmail.com" + }, + "issue": { + "id": "feature1_autenticacao.implementacl.applyacl", + "title": "Aplicar ACL aos recursos", + "description": "Filtrar dados por proprietário", + "type": "taskbacklog", + "subtype": "", + "depends": [] + }, + "startDate": "2025-11-20", + "dueDate": "2025-11-30", + "status": "TODO" + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/made/oraculo.made b/docs/made/oraculo.made new file mode 100644 index 0000000..b2e695e --- /dev/null +++ b/docs/made/oraculo.made @@ -0,0 +1,376 @@ +project BacklogProject { + name: "Backlog de Features - MADE" + description: "Conversão automática do backlog.md para um arquivo .made contendo Project, Backlog, TimeBoxes (sprints), Roadmap e Milestones." + startDate: 2025-10-02 + dueDate: 2025-11-30 +} + +team ProjectTeam { + name: "Equipe do Projeto" + description: "Equipe responsável pela gestão do projeto" + + teammember livia { + name: "liviahombre" + email: "liviahombre@gmail.com" + } + teammember thiago { + name: "ThiagoFabiano" + email: "thiagoffabiano@gmail.com" + } + teammember pedro { + name: "bedrohenr" + email: "ferfonhp@gmail.com" + } + teammember felipe { + name: "FeLiXp90" + email: "ferfonhp@gmail.com" + } +} +team DevelelopmentTeam { + name: "Equipe de Gestão" + description: "Equipe responsável pelas features descritas no backlog" + + teammember sofia { + name: "sofianasilva" + email: "sofianascimento307@gmail.com" + } + teammember alicia { + name: "aliciacapo" + email: "alicia.caporrali@gmail.com" + } + teammember vitor { + name: "nascimentoVitor10" + email: "vitorramosnascimento10@gmail.com" + } +} + +backlog ProductBacklog { + name: "Product Backlog" + description: "Lista de features convertidas do backlog.md" + + epic Feature1_Autenticacao { + name: "Autenticação de Usuário e Controle de Acesso" + description: "Desenvolvimento completo do subsistema de autenticação com Registro, Login seguro e Controle de Acesso (ACL)" + Criterions: "Registro", "Login seguro", "ACL por usuário" + observation: "Prioridade: Alta. Complexidade: Alta." + + story ImplementRegistration { + name: "Implementar Sistema de Registro" + description: "Formulário de registro, validações e persistência segura" + Requirements: "Validação de email", "Senha forte", "Persistência segura" + task CreateRegistrationForm { + name: "Criar formulário de registro" + description: "Frontend e validações" + Deliverables: "Formulário", "Validações JS" + } + task SetupAuthBackend { + name: "Criar endpoints de autenticação" + description: "Endpoints de registro e login" + Deliverables: "API de auth", "Documentação" + } + } + + story ImplementACL { + name: "Implementar ACL" + description: "Permissões para visualizar/editar somente dados próprios" + task DefineRoles { + name: "Definir papéis e permissões" + description: "Modelagem de roles e permissões" + } + task ApplyACL { + name: "Aplicar ACL aos recursos" + description: "Filtrar dados por proprietário" + } + } + } + + epic Feature2_Token { + name: "Gerenciamento Dinâmico de Token" + description: "Funcionalidade na UI para inserir, visualizar e atualizar token de acesso ao repositório" + observation: "Prioridade: Média. Complexidade: Alta." + + story TokenUI { + name: "Interface de gerenciamento de token" + description: "Entrada segura para tokens, visualização parcial e atualização" + task CreateTokenForm { + name: "Criar formulário de token" + description: "Interface para entrada de tokens" + } + task TokenValidation { + name: "Validar token" + description: "Verificar formato e validade do token" + } + } + + story SecureStorage { + name: "Armazenamento Seguro" + description: "Criptografar e armazenar tokens de forma segura" + task ImplementEncryption { + name: "Implementar criptografia" + description: "Criptografar tokens antes de salvar" + } + task StorageLayer { + name: "Camada de armazenamento" + description: "Persistir tokens criptografados" + } + } + } + + epic Feature3_Memoria { + name: "Memória Contextual com LangChain" + description: "Camada de memória para interações com IA usando LangChain para contexto contínuo" + observation: "Prioridade: Alta. Complexidade: Média." + + story InitialMemory { + name: "Memória inicial LangChain" + description: "Integração básica para armazenar e recuperar contexto" + task SetupLangChain { + name: "Configurar LangChain" + description: "Instalar e configurar biblioteca" + } + task MemoryStore { + name: "Armazenamento de memória" + description: "Criar store para histórico" + } + task IntegrateChat { + name: "Integrar com chat" + description: "Usar contexto nas respostas" + } + } + } + + epic Feature4_Graficos { + name: "Geração de Gráficos e Visualização de Dados" + description: "Capacidade de gerar gráficos usando Matplotlib/Pandas e exibir na interface do chat" + observation: "Prioridade: Média. Complexidade: Média." + + story Charts { + name: "Implementar geração de gráficos" + description: "API/backend para gerar imagens e exibir no chat" + task SetupLibraries { + name: "Configurar bibliotecas" + description: "Instalar Matplotlib, Pandas, Plotly" + } + task DataPipeline { + name: "Pipeline de dados" + description: "Processar dados para visualização" + } + task ChartGeneration { + name: "Geração de gráficos" + description: "Criar diferentes tipos de gráficos" + } + task ChatIntegration { + name: "Integração com chat" + description: "Exibir gráficos nas respostas" + } + } + } + + epic Feature5_UI { + name: "Design de Frontend e Usabilidade (UX)" + description: "Interface de Usuário responsiva e moderna para Login, Cadastro e Gerenciamento de Token" + observation: "Prioridade: Média. Complexidade: Baixa." + + story CreateAuthUI { + name: "Criar UI de Autenticação e Token" + description: "Design responsivo e fluxos simplificados para login, cadastro e gerenciamento de token" + task AuthAndTokenUI { + name: "UI de Autenticação e Token" + description: "Criar telas de login, cadastro e gerenciamento de token com design responsivo" + Deliverables: "Tela login", "Tela cadastro", "Tela gerenciamento token", "Layout responsivo", "Design system básico" + } + } + } + + epic Feature6_PadraoRespostas { + name: "Padronização de Respostas da IA" + description: "Sistema de controle de parâmetros (temperature, top_p, estilo) para respostas consistentes da IA" + observation: "Prioridade: Baixa. Complexidade: Baixa." + + story ResponseParams { + name: "Sistema de parâmetros da IA" + description: "Permitir pelo código controlar parâmetros de resposta para padronização" + task AIIntegration { + name: "Integração com IA" + description: "Aplicar parâmetros nas chamadas" + } + } + } +} + +sprint Sprint1 { + name: "Sprint 1: Memória Inicial com LangChain" + description: "02/10/2025 -- 08/10/2025" + startDate: 2025-10-02 + endDate: 2025-10-08 + status: IN_PROGRESS + sprintbacklog Sprint1Backlog { + item ProductBacklog.Feature3_Memoria.InitialMemory { + assignee: DevelelopmentTeam.alicia + startDate: 2025-10-02 + dueDate: 2025-10-08 + status: DOING + complexity: MEDIUM|HARD|SPIKE + } + } +} + +sprint Sprint2 { + name: "Sprint 2: Visualização e Gráficos" + description: "09/10/2025 -- 15/10/2025" + startDate: 2025-10-09 + endDate: 2025-10-15 + status: PLANNED + sprintbacklog Sprint2Backlog { + item ProductBacklog.Feature4_Graficos.Charts { + assignee: DevelelopmentTeam.sofia + startDate: 2025-10-09 + dueDate: 2025-10-15 + status: TODO + complexity: MEDIUM|HARD|SPIKE + } + } +} + +sprint Sprint3 { + name: "Sprint 3: Padronização da IA - Parte 1" + description: "16/10/2025 -- 22/10/2025" + startDate: 2025-10-16 + endDate: 2025-10-22 + status: PLANNED + sprintbacklog Sprint3Backlog { + item ProductBacklog.Feature6_PadraoRespostas.ResponseParams { + assignee: DevelelopmentTeam.vitor + startDate: 2025-10-16 + dueDate: 2025-10-22 + status: TODO + complexity: EASY + } + } +} + +sprint Sprint4 { + name: "Sprint 4: Interface e UX" + description: "23/10/2025 -- 29/10/2025" + startDate: 2025-10-23 + endDate: 2025-10-29 + status: PLANNED + sprintbacklog Sprint4Backlog { + item ProductBacklog.Feature5_UI.CreateAuthUI { + assignee: DevelelopmentTeam.alicia + startDate: 2025-10-23 + dueDate: 2025-10-29 + status: TODO + complexity: EASY + } + } +} + +sprint Sprint5 { + name: "Sprint 5: Autenticação Segura" + description: "30/10/2025 -- 05/11/2025" + startDate: 2025-10-30 + endDate: 2025-11-05 + status: PLANNED + sprintbacklog Sprint5Backlog { + item ProductBacklog.Feature1_Autenticacao.ImplementRegistration { + assignee: DevelelopmentTeam.sofia + startDate: 2025-10-30 + dueDate: 2025-11-05 + status: TODO + complexity: MEDIUM|HARD|SPIKE + } + } +} + +sprint Sprint6 { + name: "Sprint 6: Gerenciamento de Token - Parte 1" + description: "06/11/2025 -- 12/11/2025" + startDate: 2025-11-06 + endDate: 2025-11-12 + status: PLANNED + sprintbacklog Sprint6Backlog { + item ProductBacklog.Feature2_Token.TokenUI { + assignee: DevelelopmentTeam.vitor + startDate: 2025-11-06 + dueDate: 2025-11-12 + status: TODO + complexity: MEDIUM|HARD|SPIKE + } + } +} + +sprint Sprint7 { + name: "Sprint 7: Gerenciamento de Token - Parte 2" + description: "13/11/2025 -- 19/11/2025" + startDate: 2025-11-13 + endDate: 2025-11-19 + status: PLANNED + sprintbacklog Sprint7Backlog { + item ProductBacklog.Feature2_Token.SecureStorage { + assignee: DevelelopmentTeam.alicia + startDate: 2025-11-13 + dueDate: 2025-11-19 + status: TODO + complexity: MEDIUM|HARD|SPIKE + } + } +} + +sprint Sprint8 { + name: "Sprint 8: Estabilização e Revisão Final" + description: "20/11/2025 -- 30/11/2025" + startDate: 2025-11-20 + endDate: 2025-11-30 + status: PLANNED + sprintbacklog Sprint8Backlog { + item ProductBacklog.Feature1_Autenticacao.ImplementACL { + assignee: DevelelopmentTeam.sofia + startDate: 2025-11-20 + dueDate: 2025-11-30 + status: TODO + complexity: MEDIUM|HARD|SPIKE + } + } +} + +roadmap ProductRoadmap { + name: "Roadmap de Entregas" + description: "Marcos principais e entregas conforme o backlog.md" + + milestone Delivery1 { + name: "Entrega Inicial" + description: "Sprint 1 + Sprint 2 + Sprint 3" + startDate: 2025-10-02 + dueDate: 2025-11-02 + status: IN_PROGRESS + release V0_1 { + name: "Versão Inicial" + description: "Memória Contextual, Gráficos e Padronização - Parte 1" + version: "0.1.0" + dueDate: 2025-11-02 + status: IN_DEVELOPMENT + item: ProductBacklog.Feature3_Memoria + item: ProductBacklog.Feature4_Graficos + item: ProductBacklog.Feature6_PadraoRespostas + } + } + + milestone FinalDelivery { + name: "Entrega Final" + description: "Sprints 4 a 8 - finalização das features" + startDate: 2025-10-23 + dueDate: 2025-11-30 + status: PLANNED + release V1_0 { + name: "Versão Completa" + description: "UI, Autenticação, Gerenciamento de Token e Estabilização" + version: "1.0.0" + dueDate: 2025-11-30 + status: PLANNED + item: ProductBacklog.Feature5_UI + item: ProductBacklog.Feature1_Autenticacao + item: ProductBacklog.Feature2_Token + } + } +} \ No newline at end of file diff --git a/docs/made/project-cfd.svg b/docs/made/project-cfd.svg new file mode 100644 index 0000000..fe82601 --- /dev/null +++ b/docs/made/project-cfd.svg @@ -0,0 +1,513 @@ + + + + + + + + + + + 17 + + + 15 + + + 14 + + + 12 + + + 10 + + + 9 + + + 7 + + + 5 + + + 3 + + + 2 + + + 0 + + + + + + + + + + + qua. 01/10 + + sex. 03/10 + + dom. 05/10 + + ter. 07/10 + + qui. 09/10 + + sáb. 11/10 + + seg. 13/10 + + qua. 15/10 + + sex. 17/10 + + dom. 19/10 + + ter. 21/10 + + qui. 23/10 + + sáb. 25/10 + + seg. 27/10 + + qua. 29/10 + + sex. 31/10 + + dom. 02/11 + + ter. 04/11 + + qui. 06/11 + + sáb. 08/11 + + seg. 10/11 + + qua. 12/11 + + sex. 14/11 + + dom. 16/11 + + ter. 18/11 + + qui. 20/11 + + sáb. 22/11 + + seg. 24/11 + + qua. 26/11 + + sex. 28/11 + + + Número de Tarefas + + Período do Projeto + + Cumulative Flow Diagram - Projeto Completo + + + + TODO + + + DOING + + + DONE + + + Período: 2025-10-02 - + 2025-11-30 + + + Total de Tasks: 17 + + + Total de Sprints: 8 + + + + \ No newline at end of file diff --git a/docs/made/project-throughput.svg b/docs/made/project-throughput.svg new file mode 100644 index 0000000..020636c --- /dev/null +++ b/docs/made/project-throughput.svg @@ -0,0 +1,675 @@ + + + + + + + + + + + 4 + + + 4 + + + 3 + + + 3 + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 0 + + + 0 + + + + + + + + + + qua. 01/10 + + + + + + sex. 03/10 + + + + + + dom. 05/10 + + + + + + 3 + + + ter. 07/10 + + + + + + qui. 09/10 + + + + + + sáb. 11/10 + + + + + + seg. 13/10 + + + + + + qua. 15/10 + + + + + + sex. 17/10 + + + + + + dom. 19/10 + + + + + + 1 + + + ter. 21/10 + + + + + + qui. 23/10 + + + + + + sáb. 25/10 + + + + + + seg. 27/10 + + + + + + qua. 29/10 + + + + + + sex. 31/10 + + + + + + dom. 02/11 + + + + + + 2 + + + ter. 04/11 + + + + + + qui. 06/11 + + + + + + sáb. 08/11 + + + + + + seg. 10/11 + + + + + + qua. 12/11 + + + + + + sex. 14/11 + + + + + + dom. 16/11 + + + + + + 2 + + + ter. 18/11 + + + + + + qui. 20/11 + + + + + + sáb. 22/11 + + + + + + seg. 24/11 + + + + + + qua. 26/11 + + + + + + sex. 28/11 + + + + Tarefas Concluídas + + Período do Projeto + + Throughput Diário (Tarefas Concluídas) + + + + Concluídas + + + Período: 2025-10-02 - + 2025-11-30 + + + Total de Tasks: 17 + + + Total de Sprints: 8 + + + + \ No newline at end of file diff --git a/docs/made/sprints/Sprint1.md b/docs/made/sprints/Sprint1.md new file mode 100644 index 0000000..ef0f1ee --- /dev/null +++ b/docs/made/sprints/Sprint1.md @@ -0,0 +1,123 @@ +# SPRINT 1: MEMÓRIA INICIAL COM LANGCHAIN + +02/10/2025 -- 08/10/2025 + +## Dados do Sprint +* **Goal**: 02/10/2025 -- 08/10/2025 +* **Data Início**: 2025-10-02 +* **Data Fim**: 2025-10-08 +* **Status**: IN_PROGRESS +## Sprint Backlog + +|Nome |Descrição|Resposável |Data de Inicio Planejada| Data de Entrega Planejada| Data de Inicío | Data Entrega | Status| +|:----|:---------|:-------- |:----------------------:| :-----------------------:| :------------: |:------------:|:-----:| +|Configurar LangChain|Instalar e configurar biblioteca|aliciacapo|2025-10-02|2025-10-02|2025-10-02|2025-10-08|DOING| +|Armazenamento de memória|Criar store para histórico|aliciacapo|2025-10-02|2025-10-02|2025-10-02|2025-10-08|DOING| +|Integrar com chat|Usar contexto nas respostas|aliciacapo|2025-10-02|2025-10-02|2025-10-02|2025-10-08|DOING| + +## Gantt + +```mermaid +gantt + dateFormat YYYY-MM-DD + axisFormat %d/%m + + + section Sprint - Sprint 1: Memória Inicial com LangChain + Configurar LangChain (Real) :done, Configurar LangChain_actual, 2025-10-01, 2025-10-07 + Armazenamento de memória (Real) :done, Armazenamento de memória_actual, 2025-10-01, 2025-10-07 + Integrar com chat (Real) :done, Integrar com chat_actual, 2025-10-01, 2025-10-07 +``` + +# Análise de Dependências do Sprint + +Análise gerada em: 10/11/2025, 10:17:42 + +## 🔍 Grafo de Dependências + +```mermaid +graph BT + classDef sprint fill:#a8e6cf,stroke:#333,stroke-width:2px; + classDef done fill:#98fb98,stroke:#333,stroke-width:2px; + classDef external fill:#ffd3b6,stroke:#333,stroke-width:1px; + feature3_memoria.initialmemory.setuplangchain["📝 Tarefa: Configurar LangChain
📊 Estado: DOING
👤 Responsável: aliciacapo"]:::sprint + feature3_memoria.initialmemory.memorystore["📝 Tarefa: Armazenamento de memória
📊 Estado: DOING
👤 Responsável: aliciacapo"]:::sprint + feature3_memoria.initialmemory.integratechat["📝 Tarefa: Integrar com chat
📊 Estado: DOING
👤 Responsável: aliciacapo"]:::sprint +``` + +**Legenda:** +- 🟢 Verde Claro: Issues no sprint +- 🟢 Verde Escuro: Issues concluídas +- 🟡 Laranja: Dependências externas ao sprint +- ➡️ Linha sólida: Dependência no sprint +- ➡️ Linha pontilhada: Dependência externa + +## 📋 Sugestão de Execução das Issues + +| # | Título | Status | Responsável | Dependências | +|---|--------|--------|-------------|---------------| +| 1 | Configurar LangChain | DOING | aliciacapo | 🆓 | +| 2 | Armazenamento de memória | DOING | aliciacapo | 🆓 | +| 3 | Integrar com chat | DOING | aliciacapo | 🆓 | + +**Legenda das Dependências:** +- 🆓 Sem dependências +- ✅ Issue concluída +- ⚠️ Dependência externa ao sprint + + +## Cumulative Flow +![ Cumulative Flow](./charts/cfd-Sprint1.svg) + +## Throughput +![ Throughput](./charts/throuput-Sprint1.svg) + +# Previsão da Sprint + +## ✅ SPRINT PROVAVELMENTE SERÁ CONCLUÍDA NO PRAZO + +- **Probabilidade de conclusão no prazo**: 100.0% +- **Data mais provável de conclusão**: qua., 12/11/2025 +- **Dias em relação ao planejado**: 36 dias +- **Status**: ❌ Atraso Crítico + +### 📊 Métricas Críticas + +| Métrica | Valor | Status | +|---------|--------|--------| +| Velocidade Atual | 1.0 tarefas/dia | ❌ | +| Velocidade Necessária | 3.0 tarefas/dia | - | +| Dias Restantes | 1 dias | - | +| Tarefas Restantes | 3 tarefas | - | + +### 📅 Previsões de Data de Conclusão + +| Data | Probabilidade | Status | Observação | +|------|---------------|---------|------------| +| qua., 12/11/2025 | 100.0% | ❌ Atraso Crítico | 📍 Data mais provável | + +### 📋 Status das Tarefas + +| Status | Quantidade | Porcentagem | +|--------|------------|-------------| +| Concluído | 0 | 0.0% | +| Em Andamento | 3 | 100.0% | +| A Fazer | 0 | 0.0% | + +## 💡 Recomendações + +1. ✅ Mantenha o ritmo atual de 1.0 tarefas/dia +2. ✅ Continue monitorando impedimentos +3. ✅ Prepare-se para a próxima sprint + +## ℹ️ Informações da Sprint + +- **Sprint**: Sprint 1: Memória Inicial com LangChain +- **Início**: qua., 01/10/2025 +- **Término Planejado**: ter., 07/10/2025 +- **Total de Tarefas**: 3 +- **Simulações Realizadas**: 10.000 + +--- +*Relatório gerado em 10/11/2025, 10:17:42* + \ No newline at end of file diff --git a/docs/made/sprints/Sprint2.md b/docs/made/sprints/Sprint2.md new file mode 100644 index 0000000..eb32084 --- /dev/null +++ b/docs/made/sprints/Sprint2.md @@ -0,0 +1,80 @@ +# SPRINT 2: VISUALIZAÇÃO E GRÁFICOS + +09/10/2025 -- 15/10/2025 + +## Dados do Sprint +* **Goal**: 09/10/2025 -- 15/10/2025 +* **Data Início**: 2025-10-09 +* **Data Fim**: 2025-10-15 +* **Status**: PLANNED +## Sprint Backlog + +|Nome |Descrição|Resposável |Data de Inicio Planejada| Data de Entrega Planejada| Data de Inicío | Data Entrega | Status| +|:----|:---------|:-------- |:----------------------:| :-----------------------:| :------------: |:------------:|:-----:| +|Configurar bibliotecas|Instalar Matplotlib, Pandas, Plotly|sofianasilva|2025-10-09|2025-10-09|2025-10-09|2025-10-15|TODO| +|Pipeline de dados|Processar dados para visualização|sofianasilva|2025-10-09|2025-10-09|2025-10-09|2025-10-15|TODO| +|Geração de gráficos|Criar diferentes tipos de gráficos|sofianasilva|2025-10-09|2025-10-09|2025-10-09|2025-10-15|TODO| +|Integração com chat|Exibir gráficos nas respostas|sofianasilva|2025-10-09|2025-10-09|2025-10-09|2025-10-15|TODO| + +## Gantt + +```mermaid +gantt + dateFormat YYYY-MM-DD + axisFormat %d/%m + + + section Sprint - Sprint 2: Visualização e Gráficos + Configurar bibliotecas (Real) :done, Configurar bibliotecas_actual, 2025-10-08, 2025-10-14 + Pipeline de dados (Real) :done, Pipeline de dados_actual, 2025-10-08, 2025-10-14 + Geração de gráficos (Real) :done, Geração de gráficos_actual, 2025-10-08, 2025-10-14 + Integração com chat (Real) :done, Integração com chat_actual, 2025-10-08, 2025-10-14 +``` + +# Análise de Dependências do Sprint + +Análise gerada em: 10/11/2025, 10:17:42 + +## 🔍 Grafo de Dependências + +```mermaid +graph BT + classDef sprint fill:#a8e6cf,stroke:#333,stroke-width:2px; + classDef done fill:#98fb98,stroke:#333,stroke-width:2px; + classDef external fill:#ffd3b6,stroke:#333,stroke-width:1px; + feature4_graficos.charts.setuplibraries["📝 Tarefa: Configurar bibliotecas
📊 Estado: TODO
👤 Responsável: sofianasilva"]:::sprint + feature4_graficos.charts.datapipeline["📝 Tarefa: Pipeline de dados
📊 Estado: TODO
👤 Responsável: sofianasilva"]:::sprint + feature4_graficos.charts.chartgeneration["📝 Tarefa: Geração de gráficos
📊 Estado: TODO
👤 Responsável: sofianasilva"]:::sprint + feature4_graficos.charts.chatintegration["📝 Tarefa: Integração com chat
📊 Estado: TODO
👤 Responsável: sofianasilva"]:::sprint +``` + +**Legenda:** +- 🟢 Verde Claro: Issues no sprint +- 🟢 Verde Escuro: Issues concluídas +- 🟡 Laranja: Dependências externas ao sprint +- ➡️ Linha sólida: Dependência no sprint +- ➡️ Linha pontilhada: Dependência externa + +## 📋 Sugestão de Execução das Issues + +| # | Título | Status | Responsável | Dependências | +|---|--------|--------|-------------|---------------| +| 1 | Configurar bibliotecas | TODO | sofianasilva | 🆓 | +| 2 | Pipeline de dados | TODO | sofianasilva | 🆓 | +| 3 | Geração de gráficos | TODO | sofianasilva | 🆓 | +| 4 | Integração com chat | TODO | sofianasilva | 🆓 | + +**Legenda das Dependências:** +- 🆓 Sem dependências +- ✅ Issue concluída +- ⚠️ Dependência externa ao sprint + + +## Cumulative Flow +![ Cumulative Flow](./charts/cfd-Sprint2.svg) + +## Throughput +![ Throughput](./charts/throuput-Sprint2.svg) + + + \ No newline at end of file diff --git a/docs/made/sprints/Sprint3.md b/docs/made/sprints/Sprint3.md new file mode 100644 index 0000000..e4b2fa0 --- /dev/null +++ b/docs/made/sprints/Sprint3.md @@ -0,0 +1,68 @@ +# SPRINT 3: PADRONIZAÇÃO DA IA - PARTE 1 + +16/10/2025 -- 22/10/2025 + +## Dados do Sprint +* **Goal**: 16/10/2025 -- 22/10/2025 +* **Data Início**: 2025-10-16 +* **Data Fim**: 2025-10-22 +* **Status**: PLANNED +## Sprint Backlog + +|Nome |Descrição|Resposável |Data de Inicio Planejada| Data de Entrega Planejada| Data de Inicío | Data Entrega | Status| +|:----|:---------|:-------- |:----------------------:| :-----------------------:| :------------: |:------------:|:-----:| +|Integração com IA|Aplicar parâmetros nas chamadas|nascimentoVitor10|2025-10-16|2025-10-16|2025-10-16|2025-10-22|TODO| + +## Gantt + +```mermaid +gantt + dateFormat YYYY-MM-DD + axisFormat %d/%m + + + section Sprint - Sprint 3: Padronização da IA - Parte 1 + Integração com IA (Real) :done, Integração com IA_actual, 2025-10-15, 2025-10-21 +``` + +# Análise de Dependências do Sprint + +Análise gerada em: 10/11/2025, 10:17:42 + +## 🔍 Grafo de Dependências + +```mermaid +graph BT + classDef sprint fill:#a8e6cf,stroke:#333,stroke-width:2px; + classDef done fill:#98fb98,stroke:#333,stroke-width:2px; + classDef external fill:#ffd3b6,stroke:#333,stroke-width:1px; + feature6_padraorespostas.responseparams.aiintegration["📝 Tarefa: Integração com IA
📊 Estado: TODO
👤 Responsável: nascimentoVitor10"]:::sprint +``` + +**Legenda:** +- 🟢 Verde Claro: Issues no sprint +- 🟢 Verde Escuro: Issues concluídas +- 🟡 Laranja: Dependências externas ao sprint +- ➡️ Linha sólida: Dependência no sprint +- ➡️ Linha pontilhada: Dependência externa + +## 📋 Sugestão de Execução das Issues + +| # | Título | Status | Responsável | Dependências | +|---|--------|--------|-------------|---------------| +| 1 | Integração com IA | TODO | nascimentoVitor10 | 🆓 | + +**Legenda das Dependências:** +- 🆓 Sem dependências +- ✅ Issue concluída +- ⚠️ Dependência externa ao sprint + + +## Cumulative Flow +![ Cumulative Flow](./charts/cfd-Sprint3.svg) + +## Throughput +![ Throughput](./charts/throuput-Sprint3.svg) + + + \ No newline at end of file diff --git a/docs/made/sprints/Sprint4.md b/docs/made/sprints/Sprint4.md new file mode 100644 index 0000000..7b00110 --- /dev/null +++ b/docs/made/sprints/Sprint4.md @@ -0,0 +1,68 @@ +# SPRINT 4: INTERFACE E UX + +23/10/2025 -- 29/10/2025 + +## Dados do Sprint +* **Goal**: 23/10/2025 -- 29/10/2025 +* **Data Início**: 2025-10-23 +* **Data Fim**: 2025-10-29 +* **Status**: PLANNED +## Sprint Backlog + +|Nome |Descrição|Resposável |Data de Inicio Planejada| Data de Entrega Planejada| Data de Inicío | Data Entrega | Status| +|:----|:---------|:-------- |:----------------------:| :-----------------------:| :------------: |:------------:|:-----:| +|UI de Autenticação e Token|Criar telas de login, cadastro e gerenciamento de token com design responsivo|aliciacapo|2025-10-23|2025-10-23|2025-10-23|2025-10-29|TODO| + +## Gantt + +```mermaid +gantt + dateFormat YYYY-MM-DD + axisFormat %d/%m + + + section Sprint - Sprint 4: Interface e UX + UI de Autenticação e Token (Real) :done, UI de Autenticação e Token_actual, 2025-10-22, 2025-10-28 +``` + +# Análise de Dependências do Sprint + +Análise gerada em: 10/11/2025, 10:17:42 + +## 🔍 Grafo de Dependências + +```mermaid +graph BT + classDef sprint fill:#a8e6cf,stroke:#333,stroke-width:2px; + classDef done fill:#98fb98,stroke:#333,stroke-width:2px; + classDef external fill:#ffd3b6,stroke:#333,stroke-width:1px; + feature5_ui.createauthui.authandtokenui["📝 Tarefa: UI de Autenticação e Token
📊 Estado: TODO
👤 Responsável: aliciacapo"]:::sprint +``` + +**Legenda:** +- 🟢 Verde Claro: Issues no sprint +- 🟢 Verde Escuro: Issues concluídas +- 🟡 Laranja: Dependências externas ao sprint +- ➡️ Linha sólida: Dependência no sprint +- ➡️ Linha pontilhada: Dependência externa + +## 📋 Sugestão de Execução das Issues + +| # | Título | Status | Responsável | Dependências | +|---|--------|--------|-------------|---------------| +| 1 | UI de Autenticação e Token | TODO | aliciacapo | 🆓 | + +**Legenda das Dependências:** +- 🆓 Sem dependências +- ✅ Issue concluída +- ⚠️ Dependência externa ao sprint + + +## Cumulative Flow +![ Cumulative Flow](./charts/cfd-Sprint4.svg) + +## Throughput +![ Throughput](./charts/throuput-Sprint4.svg) + + + \ No newline at end of file diff --git a/docs/made/sprints/Sprint5.md b/docs/made/sprints/Sprint5.md new file mode 100644 index 0000000..8851d98 --- /dev/null +++ b/docs/made/sprints/Sprint5.md @@ -0,0 +1,72 @@ +# SPRINT 5: AUTENTICAÇÃO SEGURA + +30/10/2025 -- 05/11/2025 + +## Dados do Sprint +* **Goal**: 30/10/2025 -- 05/11/2025 +* **Data Início**: 2025-10-30 +* **Data Fim**: 2025-11-05 +* **Status**: PLANNED +## Sprint Backlog + +|Nome |Descrição|Resposável |Data de Inicio Planejada| Data de Entrega Planejada| Data de Inicío | Data Entrega | Status| +|:----|:---------|:-------- |:----------------------:| :-----------------------:| :------------: |:------------:|:-----:| +|Criar formulário de registro|Frontend e validações|sofianasilva|2025-10-30|2025-10-30|2025-10-30|2025-11-05|TODO| +|Criar endpoints de autenticação|Endpoints de registro e login|sofianasilva|2025-10-30|2025-10-30|2025-10-30|2025-11-05|TODO| + +## Gantt + +```mermaid +gantt + dateFormat YYYY-MM-DD + axisFormat %d/%m + + + section Sprint - Sprint 5: Autenticação Segura + Criar formulário de registro (Real) :done, Criar formulário de registro_actual, 2025-10-29, 2025-11-04 + Criar endpoints de autenticação (Real) :done, Criar endpoints de autenticação_actual, 2025-10-29, 2025-11-04 +``` + +# Análise de Dependências do Sprint + +Análise gerada em: 10/11/2025, 10:17:42 + +## 🔍 Grafo de Dependências + +```mermaid +graph BT + classDef sprint fill:#a8e6cf,stroke:#333,stroke-width:2px; + classDef done fill:#98fb98,stroke:#333,stroke-width:2px; + classDef external fill:#ffd3b6,stroke:#333,stroke-width:1px; + feature1_autenticacao.implementregistration.createregistrationform["📝 Tarefa: Criar formulário de registro
📊 Estado: TODO
👤 Responsável: sofianasilva"]:::sprint + feature1_autenticacao.implementregistration.setupauthbackend["📝 Tarefa: Criar endpoints de autenticação
📊 Estado: TODO
👤 Responsável: sofianasilva"]:::sprint +``` + +**Legenda:** +- 🟢 Verde Claro: Issues no sprint +- 🟢 Verde Escuro: Issues concluídas +- 🟡 Laranja: Dependências externas ao sprint +- ➡️ Linha sólida: Dependência no sprint +- ➡️ Linha pontilhada: Dependência externa + +## 📋 Sugestão de Execução das Issues + +| # | Título | Status | Responsável | Dependências | +|---|--------|--------|-------------|---------------| +| 1 | Criar formulário de registro | TODO | sofianasilva | 🆓 | +| 2 | Criar endpoints de autenticação | TODO | sofianasilva | 🆓 | + +**Legenda das Dependências:** +- 🆓 Sem dependências +- ✅ Issue concluída +- ⚠️ Dependência externa ao sprint + + +## Cumulative Flow +![ Cumulative Flow](./charts/cfd-Sprint5.svg) + +## Throughput +![ Throughput](./charts/throuput-Sprint5.svg) + + + \ No newline at end of file diff --git a/docs/made/sprints/Sprint6.md b/docs/made/sprints/Sprint6.md new file mode 100644 index 0000000..bedd4b8 --- /dev/null +++ b/docs/made/sprints/Sprint6.md @@ -0,0 +1,72 @@ +# SPRINT 6: GERENCIAMENTO DE TOKEN - PARTE 1 + +06/11/2025 -- 12/11/2025 + +## Dados do Sprint +* **Goal**: 06/11/2025 -- 12/11/2025 +* **Data Início**: 2025-11-06 +* **Data Fim**: 2025-11-12 +* **Status**: PLANNED +## Sprint Backlog + +|Nome |Descrição|Resposável |Data de Inicio Planejada| Data de Entrega Planejada| Data de Inicío | Data Entrega | Status| +|:----|:---------|:-------- |:----------------------:| :-----------------------:| :------------: |:------------:|:-----:| +|Criar formulário de token|Interface para entrada de tokens|nascimentoVitor10|2025-11-06|2025-11-06|2025-11-06|2025-11-12|TODO| +|Validar token|Verificar formato e validade do token|nascimentoVitor10|2025-11-06|2025-11-06|2025-11-06|2025-11-12|TODO| + +## Gantt + +```mermaid +gantt + dateFormat YYYY-MM-DD + axisFormat %d/%m + + + section Sprint - Sprint 6: Gerenciamento de Token - Parte 1 + Criar formulário de token (Real) :done, Criar formulário de token_actual, 2025-11-05, 2025-11-11 + Validar token (Real) :done, Validar token_actual, 2025-11-05, 2025-11-11 +``` + +# Análise de Dependências do Sprint + +Análise gerada em: 10/11/2025, 10:17:42 + +## 🔍 Grafo de Dependências + +```mermaid +graph BT + classDef sprint fill:#a8e6cf,stroke:#333,stroke-width:2px; + classDef done fill:#98fb98,stroke:#333,stroke-width:2px; + classDef external fill:#ffd3b6,stroke:#333,stroke-width:1px; + feature2_token.tokenui.createtokenform["📝 Tarefa: Criar formulário de token
📊 Estado: TODO
👤 Responsável: nascimentoVitor10"]:::sprint + feature2_token.tokenui.tokenvalidation["📝 Tarefa: Validar token
📊 Estado: TODO
👤 Responsável: nascimentoVitor10"]:::sprint +``` + +**Legenda:** +- 🟢 Verde Claro: Issues no sprint +- 🟢 Verde Escuro: Issues concluídas +- 🟡 Laranja: Dependências externas ao sprint +- ➡️ Linha sólida: Dependência no sprint +- ➡️ Linha pontilhada: Dependência externa + +## 📋 Sugestão de Execução das Issues + +| # | Título | Status | Responsável | Dependências | +|---|--------|--------|-------------|---------------| +| 1 | Criar formulário de token | TODO | nascimentoVitor10 | 🆓 | +| 2 | Validar token | TODO | nascimentoVitor10 | 🆓 | + +**Legenda das Dependências:** +- 🆓 Sem dependências +- ✅ Issue concluída +- ⚠️ Dependência externa ao sprint + + +## Cumulative Flow +![ Cumulative Flow](./charts/cfd-Sprint6.svg) + +## Throughput +![ Throughput](./charts/throuput-Sprint6.svg) + + + \ No newline at end of file diff --git a/docs/made/sprints/Sprint7.md b/docs/made/sprints/Sprint7.md new file mode 100644 index 0000000..f8ecce3 --- /dev/null +++ b/docs/made/sprints/Sprint7.md @@ -0,0 +1,72 @@ +# SPRINT 7: GERENCIAMENTO DE TOKEN - PARTE 2 + +13/11/2025 -- 19/11/2025 + +## Dados do Sprint +* **Goal**: 13/11/2025 -- 19/11/2025 +* **Data Início**: 2025-11-13 +* **Data Fim**: 2025-11-19 +* **Status**: PLANNED +## Sprint Backlog + +|Nome |Descrição|Resposável |Data de Inicio Planejada| Data de Entrega Planejada| Data de Inicío | Data Entrega | Status| +|:----|:---------|:-------- |:----------------------:| :-----------------------:| :------------: |:------------:|:-----:| +|Implementar criptografia|Criptografar tokens antes de salvar|aliciacapo|2025-11-13|2025-11-13|2025-11-13|2025-11-19|TODO| +|Camada de armazenamento|Persistir tokens criptografados|aliciacapo|2025-11-13|2025-11-13|2025-11-13|2025-11-19|TODO| + +## Gantt + +```mermaid +gantt + dateFormat YYYY-MM-DD + axisFormat %d/%m + + + section Sprint - Sprint 7: Gerenciamento de Token - Parte 2 + Implementar criptografia (Real) :done, Implementar criptografia_actual, 2025-11-12, 2025-11-18 + Camada de armazenamento (Real) :done, Camada de armazenamento_actual, 2025-11-12, 2025-11-18 +``` + +# Análise de Dependências do Sprint + +Análise gerada em: 10/11/2025, 10:17:42 + +## 🔍 Grafo de Dependências + +```mermaid +graph BT + classDef sprint fill:#a8e6cf,stroke:#333,stroke-width:2px; + classDef done fill:#98fb98,stroke:#333,stroke-width:2px; + classDef external fill:#ffd3b6,stroke:#333,stroke-width:1px; + feature2_token.securestorage.implementencryption["📝 Tarefa: Implementar criptografia
📊 Estado: TODO
👤 Responsável: aliciacapo"]:::sprint + feature2_token.securestorage.storagelayer["📝 Tarefa: Camada de armazenamento
📊 Estado: TODO
👤 Responsável: aliciacapo"]:::sprint +``` + +**Legenda:** +- 🟢 Verde Claro: Issues no sprint +- 🟢 Verde Escuro: Issues concluídas +- 🟡 Laranja: Dependências externas ao sprint +- ➡️ Linha sólida: Dependência no sprint +- ➡️ Linha pontilhada: Dependência externa + +## 📋 Sugestão de Execução das Issues + +| # | Título | Status | Responsável | Dependências | +|---|--------|--------|-------------|---------------| +| 1 | Implementar criptografia | TODO | aliciacapo | 🆓 | +| 2 | Camada de armazenamento | TODO | aliciacapo | 🆓 | + +**Legenda das Dependências:** +- 🆓 Sem dependências +- ✅ Issue concluída +- ⚠️ Dependência externa ao sprint + + +## Cumulative Flow +![ Cumulative Flow](./charts/cfd-Sprint7.svg) + +## Throughput +![ Throughput](./charts/throuput-Sprint7.svg) + + + \ No newline at end of file diff --git a/docs/made/sprints/Sprint8.md b/docs/made/sprints/Sprint8.md new file mode 100644 index 0000000..475eb2b --- /dev/null +++ b/docs/made/sprints/Sprint8.md @@ -0,0 +1,72 @@ +# SPRINT 8: ESTABILIZAÇÃO E REVISÃO FINAL + +20/11/2025 -- 30/11/2025 + +## Dados do Sprint +* **Goal**: 20/11/2025 -- 30/11/2025 +* **Data Início**: 2025-11-20 +* **Data Fim**: 2025-11-30 +* **Status**: PLANNED +## Sprint Backlog + +|Nome |Descrição|Resposável |Data de Inicio Planejada| Data de Entrega Planejada| Data de Inicío | Data Entrega | Status| +|:----|:---------|:-------- |:----------------------:| :-----------------------:| :------------: |:------------:|:-----:| +|Definir papéis e permissões|Modelagem de roles e permissões|sofianasilva|2025-11-20|2025-11-20|2025-11-20|2025-11-30|TODO| +|Aplicar ACL aos recursos|Filtrar dados por proprietário|sofianasilva|2025-11-20|2025-11-20|2025-11-20|2025-11-30|TODO| + +## Gantt + +```mermaid +gantt + dateFormat YYYY-MM-DD + axisFormat %d/%m + + + section Sprint - Sprint 8: Estabilização e Revisão Final + Definir papéis e permissões (Real) :done, Definir papéis e permissões_actual, 2025-11-19, 2025-11-29 + Aplicar ACL aos recursos (Real) :done, Aplicar ACL aos recursos_actual, 2025-11-19, 2025-11-29 +``` + +# Análise de Dependências do Sprint + +Análise gerada em: 10/11/2025, 10:17:42 + +## 🔍 Grafo de Dependências + +```mermaid +graph BT + classDef sprint fill:#a8e6cf,stroke:#333,stroke-width:2px; + classDef done fill:#98fb98,stroke:#333,stroke-width:2px; + classDef external fill:#ffd3b6,stroke:#333,stroke-width:1px; + feature1_autenticacao.implementacl.defineroles["📝 Tarefa: Definir papéis e permissões
📊 Estado: TODO
👤 Responsável: sofianasilva"]:::sprint + feature1_autenticacao.implementacl.applyacl["📝 Tarefa: Aplicar ACL aos recursos
📊 Estado: TODO
👤 Responsável: sofianasilva"]:::sprint +``` + +**Legenda:** +- 🟢 Verde Claro: Issues no sprint +- 🟢 Verde Escuro: Issues concluídas +- 🟡 Laranja: Dependências externas ao sprint +- ➡️ Linha sólida: Dependência no sprint +- ➡️ Linha pontilhada: Dependência externa + +## 📋 Sugestão de Execução das Issues + +| # | Título | Status | Responsável | Dependências | +|---|--------|--------|-------------|---------------| +| 1 | Definir papéis e permissões | TODO | sofianasilva | 🆓 | +| 2 | Aplicar ACL aos recursos | TODO | sofianasilva | 🆓 | + +**Legenda das Dependências:** +- 🆓 Sem dependências +- ✅ Issue concluída +- ⚠️ Dependência externa ao sprint + + +## Cumulative Flow +![ Cumulative Flow](./charts/cfd-Sprint8.svg) + +## Throughput +![ Throughput](./charts/throuput-Sprint8.svg) + + + \ No newline at end of file diff --git a/docs/made/sprints/_category_.json b/docs/made/sprints/_category_.json new file mode 100644 index 0000000..7ab8b7b --- /dev/null +++ b/docs/made/sprints/_category_.json @@ -0,0 +1,10 @@ + + { + "label": " 🚀 Sprints", + "position": 4, + "link": { + "type": "generated-index", + "description": "Documentos sobre os sprints." + } + } + \ No newline at end of file diff --git a/docs/made/sprints/charts/cfd-Sprint1.svg b/docs/made/sprints/charts/cfd-Sprint1.svg new file mode 100644 index 0000000..d85686a --- /dev/null +++ b/docs/made/sprints/charts/cfd-Sprint1.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + 3 + + + 3 + + + 2 + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + + + + + + + + + qua. 01/10 + + qui. 02/10 + + sex. 03/10 + + sáb. 04/10 + + dom. 05/10 + + seg. 06/10 + + ter. 07/10 + + + Número de Tarefas + + Dias da Sprint + + Sprint 1: Memória Inicial com LangChain - Cumulative Flow Diagram + + + + A Fazer + + + Em Andamento + + + Concluído + + + Período: 2025-10-02 - 2025-10-08 + + + Total de Issues: 3 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/cfd-Sprint2.svg b/docs/made/sprints/charts/cfd-Sprint2.svg new file mode 100644 index 0000000..92ccbe3 --- /dev/null +++ b/docs/made/sprints/charts/cfd-Sprint2.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + 4 + + + 4 + + + 3 + + + 3 + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 0 + + + 0 + + + + + + + + + + + qua. 08/10 + + qui. 09/10 + + sex. 10/10 + + sáb. 11/10 + + dom. 12/10 + + seg. 13/10 + + ter. 14/10 + + + Número de Tarefas + + Dias da Sprint + + Sprint 2: Visualização e Gráficos - Cumulative Flow Diagram + + + + A Fazer + + + Em Andamento + + + Concluído + + + Período: 2025-10-09 - 2025-10-15 + + + Total de Issues: 4 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/cfd-Sprint3.svg b/docs/made/sprints/charts/cfd-Sprint3.svg new file mode 100644 index 0000000..e040248 --- /dev/null +++ b/docs/made/sprints/charts/cfd-Sprint3.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + qua. 15/10 + + qui. 16/10 + + sex. 17/10 + + sáb. 18/10 + + dom. 19/10 + + seg. 20/10 + + ter. 21/10 + + + Número de Tarefas + + Dias da Sprint + + Sprint 3: Padronização da IA - Parte 1 - Cumulative Flow Diagram + + + + A Fazer + + + Em Andamento + + + Concluído + + + Período: 2025-10-16 - 2025-10-22 + + + Total de Issues: 1 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/cfd-Sprint4.svg b/docs/made/sprints/charts/cfd-Sprint4.svg new file mode 100644 index 0000000..2907999 --- /dev/null +++ b/docs/made/sprints/charts/cfd-Sprint4.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + qua. 22/10 + + qui. 23/10 + + sex. 24/10 + + sáb. 25/10 + + dom. 26/10 + + seg. 27/10 + + ter. 28/10 + + + Número de Tarefas + + Dias da Sprint + + Sprint 4: Interface e UX - Cumulative Flow Diagram + + + + A Fazer + + + Em Andamento + + + Concluído + + + Período: 2025-10-23 - 2025-10-29 + + + Total de Issues: 1 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/cfd-Sprint5.svg b/docs/made/sprints/charts/cfd-Sprint5.svg new file mode 100644 index 0000000..9891254 --- /dev/null +++ b/docs/made/sprints/charts/cfd-Sprint5.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + qua. 29/10 + + qui. 30/10 + + sex. 31/10 + + sáb. 01/11 + + dom. 02/11 + + seg. 03/11 + + ter. 04/11 + + + Número de Tarefas + + Dias da Sprint + + Sprint 5: Autenticação Segura - Cumulative Flow Diagram + + + + A Fazer + + + Em Andamento + + + Concluído + + + Período: 2025-10-30 - 2025-11-05 + + + Total de Issues: 2 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/cfd-Sprint6.svg b/docs/made/sprints/charts/cfd-Sprint6.svg new file mode 100644 index 0000000..c7739e7 --- /dev/null +++ b/docs/made/sprints/charts/cfd-Sprint6.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + qua. 05/11 + + qui. 06/11 + + sex. 07/11 + + sáb. 08/11 + + dom. 09/11 + + seg. 10/11 + + ter. 11/11 + + + Número de Tarefas + + Dias da Sprint + + Sprint 6: Gerenciamento de Token - Parte 1 - Cumulative Flow Diagram + + + + A Fazer + + + Em Andamento + + + Concluído + + + Período: 2025-11-06 - 2025-11-12 + + + Total de Issues: 2 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/cfd-Sprint7.svg b/docs/made/sprints/charts/cfd-Sprint7.svg new file mode 100644 index 0000000..6ad2f64 --- /dev/null +++ b/docs/made/sprints/charts/cfd-Sprint7.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + qua. 12/11 + + qui. 13/11 + + sex. 14/11 + + sáb. 15/11 + + dom. 16/11 + + seg. 17/11 + + ter. 18/11 + + + Número de Tarefas + + Dias da Sprint + + Sprint 7: Gerenciamento de Token - Parte 2 - Cumulative Flow Diagram + + + + A Fazer + + + Em Andamento + + + Concluído + + + Período: 2025-11-13 - 2025-11-19 + + + Total de Issues: 2 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/cfd-Sprint8.svg b/docs/made/sprints/charts/cfd-Sprint8.svg new file mode 100644 index 0000000..3cf2dcb --- /dev/null +++ b/docs/made/sprints/charts/cfd-Sprint8.svg @@ -0,0 +1,357 @@ + + + + + + + + + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + qua. 19/11 + + qui. 20/11 + + sex. 21/11 + + sáb. 22/11 + + dom. 23/11 + + seg. 24/11 + + ter. 25/11 + + qua. 26/11 + + qui. 27/11 + + sex. 28/11 + + sáb. 29/11 + + + Número de Tarefas + + Dias da Sprint + + Sprint 8: Estabilização e Revisão Final - Cumulative Flow Diagram + + + + A Fazer + + + Em Andamento + + + Concluído + + + Período: 2025-11-20 - 2025-11-30 + + + Total de Issues: 2 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/throuput-Sprint1.svg b/docs/made/sprints/charts/throuput-Sprint1.svg new file mode 100644 index 0000000..6659619 --- /dev/null +++ b/docs/made/sprints/charts/throuput-Sprint1.svg @@ -0,0 +1,561 @@ + + + + + + + + + + + 3 + + + 3 + + + 2 + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + + + + + + + + + + + + qua. 01/10 + + + + + + + + + + + + + + + + qui. 02/10 + + + + + + + + + + + + + + + + sex. 03/10 + + + + + + + + + + + + + + + + sáb. 04/10 + + + + + + + + + + + + + + + + dom. 05/10 + + + + + + + + + + + + + + + + seg. 06/10 + + + + + + + + + + + + + + + + ter. 07/10 + + + + + + + 3 + + + + + Número de Tarefas + + Dias da Sprint + + Sprint 1: Memória Inicial com LangChain - Throughput + + + + TODO + + + DOING + + + DONE + + + Período: 2025-10-02 - 2025-10-08 + + + Total de Issues: 3 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/throuput-Sprint2.svg b/docs/made/sprints/charts/throuput-Sprint2.svg new file mode 100644 index 0000000..3f596d2 --- /dev/null +++ b/docs/made/sprints/charts/throuput-Sprint2.svg @@ -0,0 +1,561 @@ + + + + + + + + + + + 4 + + + 4 + + + 3 + + + 3 + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 0 + + + 0 + + + + + + + + + + + + + + qua. 08/10 + + + + + + + + + + + + + + + + qui. 09/10 + + + + + + + + + + + + + + + + sex. 10/10 + + + + + + + + + + + + + + + + sáb. 11/10 + + + + + + + + + + + + + + + + dom. 12/10 + + + + + + + + + + + + + + + + seg. 13/10 + + + + + + + + + + + + + + + + ter. 14/10 + + + + + + + 4 + + + + + Número de Tarefas + + Dias da Sprint + + Sprint 2: Visualização e Gráficos - Throughput + + + + TODO + + + DOING + + + DONE + + + Período: 2025-10-09 - 2025-10-15 + + + Total de Issues: 4 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/throuput-Sprint3.svg b/docs/made/sprints/charts/throuput-Sprint3.svg new file mode 100644 index 0000000..50e303d --- /dev/null +++ b/docs/made/sprints/charts/throuput-Sprint3.svg @@ -0,0 +1,561 @@ + + + + + + + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + qua. 15/10 + + + + + + + + + + + + + + + + qui. 16/10 + + + + + + + + + + + + + + + + sex. 17/10 + + + + + + + + + + + + + + + + sáb. 18/10 + + + + + + + + + + + + + + + + dom. 19/10 + + + + + + + + + + + + + + + + seg. 20/10 + + + + + + + + + + + + + + + + ter. 21/10 + + + + + + + 1 + + + + + Número de Tarefas + + Dias da Sprint + + Sprint 3: Padronização da IA - Parte 1 - Throughput + + + + TODO + + + DOING + + + DONE + + + Período: 2025-10-16 - 2025-10-22 + + + Total de Issues: 1 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/throuput-Sprint4.svg b/docs/made/sprints/charts/throuput-Sprint4.svg new file mode 100644 index 0000000..333143a --- /dev/null +++ b/docs/made/sprints/charts/throuput-Sprint4.svg @@ -0,0 +1,561 @@ + + + + + + + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + qua. 22/10 + + + + + + + + + + + + + + + + qui. 23/10 + + + + + + + + + + + + + + + + sex. 24/10 + + + + + + + + + + + + + + + + sáb. 25/10 + + + + + + + + + + + + + + + + dom. 26/10 + + + + + + + + + + + + + + + + seg. 27/10 + + + + + + + + + + + + + + + + ter. 28/10 + + + + + + + 1 + + + + + Número de Tarefas + + Dias da Sprint + + Sprint 4: Interface e UX - Throughput + + + + TODO + + + DOING + + + DONE + + + Período: 2025-10-23 - 2025-10-29 + + + Total de Issues: 1 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/throuput-Sprint5.svg b/docs/made/sprints/charts/throuput-Sprint5.svg new file mode 100644 index 0000000..58149fe --- /dev/null +++ b/docs/made/sprints/charts/throuput-Sprint5.svg @@ -0,0 +1,561 @@ + + + + + + + + + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + qua. 29/10 + + + + + + + + + + + + + + + + qui. 30/10 + + + + + + + + + + + + + + + + sex. 31/10 + + + + + + + + + + + + + + + + sáb. 01/11 + + + + + + + + + + + + + + + + dom. 02/11 + + + + + + + + + + + + + + + + seg. 03/11 + + + + + + + + + + + + + + + + ter. 04/11 + + + + + + + 2 + + + + + Número de Tarefas + + Dias da Sprint + + Sprint 5: Autenticação Segura - Throughput + + + + TODO + + + DOING + + + DONE + + + Período: 2025-10-30 - 2025-11-05 + + + Total de Issues: 2 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/throuput-Sprint6.svg b/docs/made/sprints/charts/throuput-Sprint6.svg new file mode 100644 index 0000000..6bb7664 --- /dev/null +++ b/docs/made/sprints/charts/throuput-Sprint6.svg @@ -0,0 +1,561 @@ + + + + + + + + + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + qua. 05/11 + + + + + + + + + + + + + + + + qui. 06/11 + + + + + + + + + + + + + + + + sex. 07/11 + + + + + + + + + + + + + + + + sáb. 08/11 + + + + + + + + + + + + + + + + dom. 09/11 + + + + + + + + + + + + + + + + seg. 10/11 + + + + + + + + + + + + + + + + ter. 11/11 + + + + + + + 2 + + + + + Número de Tarefas + + Dias da Sprint + + Sprint 6: Gerenciamento de Token - Parte 1 - Throughput + + + + TODO + + + DOING + + + DONE + + + Período: 2025-11-06 - 2025-11-12 + + + Total de Issues: 2 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/throuput-Sprint7.svg b/docs/made/sprints/charts/throuput-Sprint7.svg new file mode 100644 index 0000000..dc248d9 --- /dev/null +++ b/docs/made/sprints/charts/throuput-Sprint7.svg @@ -0,0 +1,561 @@ + + + + + + + + + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + qua. 12/11 + + + + + + + + + + + + + + + + qui. 13/11 + + + + + + + + + + + + + + + + sex. 14/11 + + + + + + + + + + + + + + + + sáb. 15/11 + + + + + + + + + + + + + + + + dom. 16/11 + + + + + + + + + + + + + + + + seg. 17/11 + + + + + + + + + + + + + + + + ter. 18/11 + + + + + + + 2 + + + + + Número de Tarefas + + Dias da Sprint + + Sprint 7: Gerenciamento de Token - Parte 2 - Throughput + + + + TODO + + + DOING + + + DONE + + + Período: 2025-11-13 - 2025-11-19 + + + Total de Issues: 2 + + + + \ No newline at end of file diff --git a/docs/made/sprints/charts/throuput-Sprint8.svg b/docs/made/sprints/charts/throuput-Sprint8.svg new file mode 100644 index 0000000..bb98383 --- /dev/null +++ b/docs/made/sprints/charts/throuput-Sprint8.svg @@ -0,0 +1,733 @@ + + + + + + + + + + + 2 + + + 2 + + + 2 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + qua. 19/11 + + + + + + + + + + + + + + + + qui. 20/11 + + + + + + + + + + + + + + + + sex. 21/11 + + + + + + + + + + + + + + + + sáb. 22/11 + + + + + + + + + + + + + + + + dom. 23/11 + + + + + + + + + + + + + + + + seg. 24/11 + + + + + + + + + + + + + + + + ter. 25/11 + + + + + + + + + + + + + + + + qua. 26/11 + + + + + + + + + + + + + + + + qui. 27/11 + + + + + + + + + + + + + + + + sex. 28/11 + + + + + + + + + + + + + + + + sáb. 29/11 + + + + + + + 2 + + + + + Número de Tarefas + + Dias da Sprint + + Sprint 8: Estabilização e Revisão Final - Throughput + + + + TODO + + + DOING + + + DONE + + + Período: 2025-11-20 - 2025-11-30 + + + Total de Issues: 2 + + + + \ No newline at end of file From 771c2b0f2497f751a17e9bba74b4c65dd23975c9 Mon Sep 17 00:00:00 2001 From: Vitor do Nascimento Ramos Date: Tue, 25 Nov 2025 12:14:17 -0300 Subject: [PATCH 12/20] =?UTF-8?q?inser=C3=A7=C3=A3o=20de=20mem=C3=B3ria=20?= =?UTF-8?q?contextual=20com=20langchain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 14 -- src/api/controller/AskController.py | 106 ++++++++++-- src/api/database/MyVanna.py | 244 ++++------------------------ src/api/database/sql_examples.sql | 35 ++++ 4 files changed, 163 insertions(+), 236 deletions(-) create mode 100644 src/api/database/sql_examples.sql diff --git a/requirements.txt b/requirements.txt index 00101b6..e69de29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,14 +0,0 @@ -annotated-types==0.7.0 -anyio==4.11.0 -certifi==2025.10.5 -exceptiongroup==1.3.0 -h11==0.16.0 -httpcore==1.0.9 -httpx==0.28.1 -idna==3.11 -ollama==0.6.0 -pydantic==2.12.3 -pydantic_core==2.41.4 -sniffio==1.3.1 -typing-inspection==0.4.2 -typing_extensions==4.15.0 diff --git a/src/api/controller/AskController.py b/src/api/controller/AskController.py index cd320a4..ff2722c 100644 --- a/src/api/controller/AskController.py +++ b/src/api/controller/AskController.py @@ -8,7 +8,12 @@ from src.api.database.MyVanna import MyVanna import json from typing import Dict, Optional +import pandas as pd +import matplotlib.pyplot as plt +import uuid +import os import hashlib +import re from src.assets.aux.env import env @@ -18,6 +23,44 @@ class AskController(metaclass=SingletonMeta): + + # Diretório estático para salvar gráficos + STATIC_DIR = os.path.join(os.getcwd(), "static", "graficos") + + def _generate_chart_if_requested(self, resultado, wants_chart: bool): + """ + Gera um gráfico a partir do resultado se wants_chart for True. + Salva o gráfico em arquivo e retorna o link, ou mensagem de erro se não houver dados. + """ + if not wants_chart: + return None + # Garante que o diretório existe + os.makedirs(self.STATIC_DIR, exist_ok=True) + df = pd.DataFrame(resultado) + if df.empty: + return {"output": "Não há dados suficientes para gerar um gráfico."} + + plt.figure(figsize=(8, 5)) + if df.shape[1] >= 2: + x = df.columns[0] + y = df.columns[1] + plt.bar(df[x], df[y]) + plt.xlabel(x) + plt.ylabel(y) + plt.title("Gráfico gerado a partir dos dados") + else: + plt.plot(df[df.columns[0]]) + plt.title("Gráfico gerado a partir dos dados") + + filename = f"{uuid.uuid4()}.png" + filepath = os.path.join(self.STATIC_DIR, filename) + plt.tight_layout() + plt.savefig(filepath) + plt.close() + + link = f"http://localhost:8000/static/graficos/{filename}" + return {"output": f"Gráfico gerado: [Clique aqui para visualizar]({link})", "grafico_url": link} + def __init__(self): self.client = genai.Client(api_key=GEMINI_API_KEY) @@ -53,6 +96,18 @@ def __init__(self): # Cache simples para queries SQL (em memória) self.sql_cache: Dict[str, str] = {} self.result_cache: Dict[str, any] = {} + + def _detect_chart_request(self, question: str) -> bool: + """ + Detecta se a pergunta do usuário sugere a geração de um gráfico. + """ + chart_keywords = [ + "gráfico", "grafico", "plot", "visualização", "visualizacao", + "chart", "plotar", "desenhar gráfico", "desenhar grafico", "mostrar gráfico", + "mostrar grafico", "visualize", "visualizar", "figure", "figura" + ] + question_lower = question.lower() + return any(kw in question_lower for kw in chart_keywords) def _preprocess_question(self, question: str) -> str: """ @@ -89,12 +144,13 @@ def _preprocess_question(self, question: str) -> str: - "mudança" → "commit" - "alteração" → "commit" 5. Expandir a pergunta com contexto necessário do histórico +6. Desenvolver análises robustas dos dados extraídos para que insight valiosos sejam extraídos +7. REGRAS CRÍTICAS: - Se a pergunta fizer referência a algo anterior ("e aquele", "o outro", "também"), inclua o contexto explícito - Se não houver referência contextual, retorne a pergunta apenas normalizada -- NÃO explique, NÃO confirme, NÃO dê exemplos -- Retorne APENAS a pergunta processada e expandida em uma única linha""" +""" # Monta mensagens messages = [ @@ -139,14 +195,27 @@ def _validate_sql(self, sql: str) -> tuple[bool, Optional[str]]: if not sql_upper.startswith("SELECT"): return False, "Apenas queries SELECT são permitidas" - # Blacklist: operações perigosas - dangerous_keywords = [ - "DELETE", "DROP", "TRUNCATE", "INSERT", - "UPDATE", "ALTER", "CREATE", "GRANT", "REVOKE" + # Blacklist com word boundaries (evita falsos positivos) + dangerous_patterns = [ + r'\bDELETE\b', + r'\bDROP\b', + r'\bTRUNCATE\b', + r'\bINSERT\b', + r'\bUPDATE\b', + r'\bALTER\b', + r'\bCREATE\s+TABLE\b', # Só bloqueia "CREATE TABLE", não "created_by" + r'\bCREATE\s+INDEX\b', + r'\bCREATE\s+DATABASE\b', + r'\bGRANT\b', + r'\bREVOKE\b', + r'\bEXEC\b', + r'\bEXECUTE\b', + r';\s*\w+', # SQL injection ] - for keyword in dangerous_keywords: - if keyword in sql_upper: + for pattern in dangerous_patterns: + if re.search(pattern, sql_upper): + keyword = pattern.replace(r'\b', '').replace(r'\s+', ' ') return False, f"Operação '{keyword}' não é permitida" # Limite de complexidade (número de JOINs) @@ -225,6 +294,9 @@ def ask(self, question: Question, session_id: Optional[str] = None) -> dict: original_question = question.question print(f"[Original] {original_question}") + # Detectar intenção de gráfico + wants_chart = self._detect_chart_request(original_question) + # Etapa 1: Pré-processar com contexto processed_question = self._preprocess_question(original_question) print(f"[Preprocessed] {processed_question}") @@ -278,24 +350,31 @@ def ask(self, question: Question, session_id: Optional[str] = None) -> dict: self.result_cache[result_cache_key] = resultado print(f"[Cache Miss] Resultado obtido e armazenado") - # Etapa 4: Formatar resposta com contexto + # Etapa 4: Gerar gráfico se solicitado + chart_result = self._generate_chart_if_requested(resultado, wants_chart) + + # Etapa 5: Formatar resposta com contexto resposta_formatada = self._format_response_with_context( question=original_question, sql=sql_gerado, result=resultado ) - # Etapa 5: Salvar na memória + # Etapa 6: Salvar na memória self.memory.save_context( inputs={"question": original_question}, outputs={"answer": resposta_formatada} ) - return { + response = { "output": resposta_formatada, "sql": sql_gerado, - "cached": result_cache_key in self.result_cache + "cached": result_cache_key in self.result_cache, + "wants_chart": wants_chart } + if chart_result: + response.update(chart_result) + return response except Exception as e: import traceback @@ -314,7 +393,8 @@ def ask(self, question: Question, session_id: Optional[str] = None) -> dict: return { "output": error_msg, - "error": True + "error": True, + "wants_chart": False } def clear_memory(self): diff --git a/src/api/database/MyVanna.py b/src/api/database/MyVanna.py index a21ab42..18d01ef 100644 --- a/src/api/database/MyVanna.py +++ b/src/api/database/MyVanna.py @@ -164,224 +164,50 @@ def run_sql(self, sql): def prepare(self): + """ + Prepara o Vanna com treinamento inicial CORRIGIDO + + Args: + force_retrain: Se True, força o retreinamento mesmo se já existir cache + """ + + # Conectar ao banco self.connect_to_postgres( - host = DB_HOST, - port = DB_PORT, - dbname = DB_NAME, - user = DB_USER, - password = DB_PASSWORD + host=DB_HOST, + port=DB_PORT, + dbname=DB_NAME, + user=DB_USER, + password=DB_PASSWORD ) + + print("[Vanna] → Iniciando treinamento (isso consome API quota)...") + + # ========================================================================= + # ETAPA 1: Treinar com DDL (estrutura real do banco) + # ========================================================================= + print("[Vanna] 1/2 Treinando DDL...") self.train(ddl=self.get_schema()) - self.train(documentation=""" -Table: user_info - - id: Bigint primary key with default value from sequence - - login: Required username field (character varying) - - html_url: Required profile URL field (text) - -Table: milestone - - id: Bigint primary key with default value from sequence - - repository_id: Associated repository ID (integer, required) - - title: Milestone title (text, required) - - description: Milestone description (text, optional) - - number: Milestone number (integer, required) - - state: Milestone state (character varying, required) - - created_at: Creation timestamp with time zone - - updated_at: Update timestamp with time zone - - creator: Creator user ID (bigint, required) - -Table: repository - - id: Integer primary key with default value from sequence - - name: Repository name (character varying, required) - -Table: branch - - id: Bigint primary key with default value from sequence - - name: Branch name (character varying, required) - - repository_id: Associated repository ID (integer, required) - -Table: issue - - id: Bigint primary key with default value from sequence - - title: Issue title (text, required) - - body: Issue body/description (text, optional) - - number: Issue number (integer, required) - - html_url: Issue URL (text, optional) - - created_at: Creation timestamp with time zone - - updated_at: Update timestamp with time zone - - created_by: Creator user ID (bigint, required) - - repository_id: Associated repository ID (bigint, required) + print("[Vanna] 2/2 Treinando SQL Examples e documentação...") + self.train(sql=open("src/api/database/sql_examples.sql").read()) - milestone_id: Associated milestone ID (bigint, optional) - -Table: pull_requests - - id: Bigint primary key with default value from sequence - - created_by: Creator user ID (bigint, required) - - repository_id: Associated repository ID (integer, required) - - number: Pull request number (integer, required) - - state: Pull request state (character varying, required) - - title: Pull request title (text, required) - - body: Pull request body/description (text, optional) - - html_url: Pull request URL (text, required) - - created_at: Creation timestamp with time zone - - updated_at: Update timestamp with time zone - - milestone_id: Associated milestone ID (bigint, optional) - -Table: commits - - id: Bigint primary key with default value from sequence - - user_id: Author user ID (bigint, required) - - branch_id: Associated branch ID (integer, optional) - - pull_request_id: Associated pull request ID (bigint, optional) - - created_at: Creation timestamp with time zone - - message: Commit message (text, required) - - sha: Commit SHA hash (character varying, required) - - html_url: Commit URL (text, optional) - -Table: parents_commits - - id: Integer primary key with default value from sequence - - parent_sha: Parent commit SHA hash (character varying, required) - - commit_id: Child commit ID (integer, required) - -Table: issue_assignees - - issue_id: Issue ID (bigint, required, part of primary key) - - user_id: Assigned user ID (bigint, required, part of primary key) + self.train(documentation=""" + O banco contempla atividades de GitHub: -Table: pull_request_assignees + - user_info: usuários + - repository: repositórios + - branch: branches dos repositórios + - issue: issues criadas + - pull_requests: PRs + - commits: commits de usuários, podendo referenciar PRs + - issue_assignees / pull_request_assignees: responsáveis + - milestone: grupo de issues e PRs - pull_request_id: Pull request ID (bigint, required, part of primary key) + Consultas esperadas: ranking, agregações, contagem de atividades, obtenção de repositórios mais ativos e etc. - user_id: Assigned user ID (bigint, required, part of primary key) - """) + """) - self.train(sql=""" - -- 1. Repositórios com mais issues abertas - SELECT - r.name AS repositorio, - COUNT(*) AS total_issues_abertas, - MAX(i.created_at) AS data_ultima_issue - FROM - issue i - JOIN - repository r ON i.repository_id = r.id - WHERE - i.state = 'open' - GROUP BY - r.name - ORDER BY - total_issues_abertas DESC - LIMIT 10; - """) - - self.train(sql=""" - -- 2. Top 5 usuários com mais commits registrados - SELECT - u.login, - COUNT(*) AS total_commits - FROM - commits c - JOIN - user_info u ON c.user_id = u.id - GROUP BY - u.login - ORDER BY - total_commits DESC - LIMIT 5; - """) - - self.train(sql=""" - -- 3. Total de pull requests abertos por repositório - SELECT - r.name AS repositorio, - COUNT(*) AS total_pr_abertos - FROM - pull_requests pr - JOIN - repository r ON pr.repository_id = r.id - WHERE - pr.state = 'open' - GROUP BY - r.name - ORDER BY - total_pr_abertos DESC; - """) - - self.train(sql=""" - -- 4. Número de issues por milestone - SELECT - m.title AS milestone, - COUNT(*) AS total_issues - FROM - issue i - JOIN - milestone m ON i.milestone_id = m.id - GROUP BY - m.title - ORDER BY - total_issues DESC; - """) - - self.train(sql=""" - -- 5. Commits feitos por branch - SELECT - b.name AS branch, - COUNT(*) AS total_commits - FROM - commits c - JOIN - branch b ON c.branch_id = b.id - GROUP BY - b.name - ORDER BY - total_commits DESC; - """) + \ No newline at end of file diff --git a/src/api/database/sql_examples.sql b/src/api/database/sql_examples.sql new file mode 100644 index 0000000..4a320f7 --- /dev/null +++ b/src/api/database/sql_examples.sql @@ -0,0 +1,35 @@ +-- Exemplo 1: Contar issues por repositório +SELECT r.name, COUNT(*) AS total_issues +FROM issue i +JOIN repository r ON r.id = i.repository_id +GROUP BY r.name; + +-- Exemplo 2: Contar commits por usuário +SELECT u.login, COUNT(*) AS total_commits +FROM commits c +JOIN user_info u ON u.id = c.user_id +GROUP BY u.login; + +-- Exemplo 3: Repositório mais movimentado (issues + PRs + commits) +WITH activity AS ( + SELECT + r.id, + COUNT(DISTINCT i.id) + + COUNT(DISTINCT pr.id) + + COUNT(DISTINCT c.id) AS score + FROM repository r + LEFT JOIN issue i ON i.repository_id = r.id + LEFT JOIN pull_requests pr ON pr.repository_id = r.id + LEFT JOIN commits c ON c.pull_request_id = pr.id + GROUP BY r.id +) +SELECT id FROM activity ORDER BY score DESC LIMIT 1; + +-- Exemplo 4: Tasks (issues) por usuário em um repositório específico +SELECT + u.login, + COUNT(*) AS total_tasks +FROM issue i +JOIN user_info u ON u.id = i.created_by +WHERE i.repository_id = 1 +GROUP BY u.login; From 556968b580d1e514fb114285dfdc529c530d41a1 Mon Sep 17 00:00:00 2001 From: Vitor do Nascimento Ramos Date: Wed, 26 Nov 2025 13:31:47 -0300 Subject: [PATCH 13/20] =?UTF-8?q?corre=C3=A7=C3=A3o=20de=20=C3=BAltima=20P?= =?UTF-8?q?R?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example.env | 15 +++++++++ requirements.txt | 50 +++++++++++++++++++++++++++++ src/api/controller/AskController.py | 6 ++-- 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 example.env diff --git a/example.env b/example.env new file mode 100644 index 0000000..a2aa962 --- /dev/null +++ b/example.env @@ -0,0 +1,15 @@ +GITHUB_TOKEN= + +# Database credentials +DB_HOST=db +DB_AB_DESTINATION_HOST=host.docker.internal +DB_PORT=5432 +EXPOSED_DB_PORT=5432 +DB_NAME=databasex +DB_USER=postgres +DB_PASSWORD=postgres +DB_URL=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} + +# Google cloud gemini +GEMINI_API_KEY= +GEMINI_MODEL_NAME=gemini-2.0-flash \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index e69de29..e044d45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,50 @@ +airbyte==0.31.3 +FastAPI==0.115.9 +uvicorn==0.34.3 +psycopg2-binary==2.9.10 +python-dotenv==1.1.0 +vanna==0.7.9 +chromadb +google-genai +google-cloud-aiplatform==1.96.0 +onnxruntime==1.22.0 +langchain-google-genai<1.0.0 +langchain + +pytest==7.4.0 +pytest-asyncio==0.21.1 +pytest-mock==3.12.0 +pytest-cov==4.1.0 +httpx +requests-mock==1.11.0 + +torch>=2.2.0,<2.8.0 +transformers>=4.35.0,<5.0.0 +tokenizers>=0.15.0,<1.0.0 +scikit-learn>=1.5.2,<2.0.0 +numpy>=1.21.0,<1.27.0 + +annotated-types==0.7.0 +anyio==4.11.0 +certifi==2025.10.5 +contourpy==1.3.2 +cycler==0.12.1 +exceptiongroup==1.3.0 +fonttools==4.60.1 +h11==0.16.0 +httpcore==1.0.9 +httpx==0.28.1 +idna==3.11 +kiwisolver==1.4.9 +ollama==0.6.0 +packaging==25.0 +pillow==12.0.0 +pydantic==2.12.3 +pydantic_core==2.41.4 +pyparsing==3.2.5 +python-dateutil==2.9.0.post0 +six==1.17.0 +sniffio==1.3.1 +typing-inspection==0.4.2 +typing_extensions==4.15.0 +uuid==1.30 \ No newline at end of file diff --git a/src/api/controller/AskController.py b/src/api/controller/AskController.py index ff2722c..4d9d0dd 100644 --- a/src/api/controller/AskController.py +++ b/src/api/controller/AskController.py @@ -24,10 +24,10 @@ class AskController(metaclass=SingletonMeta): - # Diretório estático para salvar gráficos - STATIC_DIR = os.path.join(os.getcwd(), "static", "graficos") + # Diretório estático para salvar gráficos + STATIC_DIR = os.path.join(os.getcwd(), "static", "graficos") - def _generate_chart_if_requested(self, resultado, wants_chart: bool): + def _generate_chart_if_requested(self, resultado, wants_chart: bool): """ Gera um gráfico a partir do resultado se wants_chart for True. Salva o gráfico em arquivo e retorna o link, ou mensagem de erro se não houver dados. From 9536c95361d5addb0b572dabe025a6fab7620a1a Mon Sep 17 00:00:00 2001 From: Vitor do Nascimento Ramos Date: Thu, 27 Nov 2025 11:08:52 -0300 Subject: [PATCH 14/20] =?UTF-8?q?Corre=C3=A7=C3=A3o=20de=20requirements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example.env | 4 +- requirements.txt | 287 +++++++++++++++++++++++++--- src/api/controller/AskController.py | 140 +++++++------- 3 files changed, 332 insertions(+), 99 deletions(-) diff --git a/example.env b/example.env index a2aa962..918fade 100644 --- a/example.env +++ b/example.env @@ -1,4 +1,4 @@ -GITHUB_TOKEN= +GITHUB_TOKEN= # Database credentials DB_HOST=db @@ -11,5 +11,5 @@ DB_PASSWORD=postgres DB_URL=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} # Google cloud gemini -GEMINI_API_KEY= +GEMINI_API_KEY= GEMINI_MODEL_NAME=gemini-2.0-flash \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index e044d45..c355f8d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,50 +1,283 @@ +aiohappyeyeballs==2.6.1 +aiohttp==3.13.2 +aiosignal==1.4.0 airbyte==0.31.3 -FastAPI==0.115.9 -uvicorn==0.34.3 -psycopg2-binary==2.9.10 -python-dotenv==1.1.0 -vanna==0.7.9 -chromadb -google-genai -google-cloud-aiplatform==1.96.0 -onnxruntime==1.22.0 -langchain-google-genai<1.0.0 -langchain - -pytest==7.4.0 -pytest-asyncio==0.21.1 -pytest-mock==3.12.0 -pytest-cov==4.1.0 -httpx -requests-mock==1.11.0 - -torch>=2.2.0,<2.8.0 -transformers>=4.35.0,<5.0.0 -tokenizers>=0.15.0,<1.0.0 -scikit-learn>=1.5.2,<2.0.0 -numpy>=1.21.0,<1.27.0 - +airbyte-api==0.52.2 +airbyte-cdk==6.61.6 +airbyte_protocol_models_dataclasses==0.17.1 +airbyte_protocol_models_pdv2==0.13.1 annotated-types==0.7.0 +anyascii==0.3.3 anyio==4.11.0 +asn1crypto==1.5.1 +async-timeout==4.0.3 +attributes-doc==0.4.0 +attrs==25.4.0 +Authlib==1.6.5 +backoff==2.2.1 +backports.tarfile==1.2.0 +bcrypt==5.0.0 +beartype==0.22.6 +blinker==1.9.0 +boltons==25.0.0 +boto3==1.41.5 +botocore==1.41.5 +bracex==2.6 +build==1.3.0 +cachetools==6.2.2 +cattrs==25.3.0 certifi==2025.10.5 +cffi==1.17.1 +charset-normalizer==3.4.4 +choreographer==1.2.1 +chromadb==1.3.5 +click==8.3.1 +coloredlogs==15.0.1 contourpy==1.3.2 +coverage==7.12.0 +cryptography==44.0.3 cycler==0.12.1 +cyclopts==4.3.0 +dataclasses-json==0.6.7 +dateparser==1.2.2 +Deprecated==1.3.1 +diskcache==5.6.3 +distro==1.9.0 +dnspython==2.8.0 +docstring_parser==0.17.0 +docutils==0.22.3 +dpath==2.2.0 +duckdb==1.4.2 +duckdb_engine==0.13.6 +dunamai==1.25.0 +durationpy==0.10 +email-validator==2.3.0 exceptiongroup==1.3.0 +fastapi==0.115.9 +fastmcp==2.13.0.2 +filelock==3.20.0 +flasgger==0.9.7.1 +Flask==3.1.2 +flask-sock==0.7.0 +flatbuffers==25.9.23 fonttools==4.60.1 +frozenlist==1.8.0 +fsspec==2025.10.0 +genson==1.3.0 +google-ai-generativelanguage==0.4.0 +google-api-core==2.28.1 +google-auth==2.43.0 +google-cloud-aiplatform==1.96.0 +google-cloud-bigquery==3.30.0 +google-cloud-bigquery-storage==2.34.0 +google-cloud-core==2.5.0 +google-cloud-resource-manager==1.15.0 +google-cloud-secret-manager==2.25.0 +google-cloud-storage==2.19.0 +google-crc32c==1.7.1 +google-genai==1.52.0 +google-generativeai==0.4.1 +google-resumable-media==2.8.0 +googleapis-common-protos==1.72.0 +greenlet==3.2.4 +grpc-google-iam-v1==0.14.3 +grpcio==1.76.0 +grpcio-status==1.62.3 h11==0.16.0 +hf-xet==1.2.0 httpcore==1.0.9 +httptools==0.7.1 httpx==0.28.1 +httpx-sse==0.4.3 +huggingface-hub==0.36.0 +humanfriendly==10.0 idna==3.11 +importlib_metadata==8.4.0 +importlib_resources==6.5.2 +iniconfig==2.3.0 +isodate==0.6.1 +itsdangerous==2.2.0 +jaraco.classes==3.4.0 +jaraco.context==6.0.1 +jaraco.functools==4.3.0 +jeepney==0.9.0 +Jinja2==3.1.6 +jmespath==1.0.1 +joblib==1.5.2 +jsonpatch==1.33 +jsonpath-python==1.1.4 +jsonpointer==3.0.0 +jsonref==0.2 +jsonschema==4.25.1 +jsonschema-path==0.3.4 +jsonschema-specifications==2025.9.1 +kaleido==1.2.0 +keyring==25.7.0 kiwisolver==1.4.9 +kubernetes==34.1.0 +langchain==0.1.16 +langchain-community==0.0.32 +langchain-core==0.1.42 +langchain-google-genai==0.0.11 +langchain-text-splitters==0.0.2 +langsmith==0.1.147 +logistro==2.0.1 +markdown-it-py==4.0.0 +MarkupSafe==3.0.3 +marshmallow==3.26.1 +matplotlib==3.9.2 +mcp==1.22.0 +mdurl==0.1.2 +mistune==3.1.4 +mmh3==5.2.0 +more-itertools==10.8.0 +mpmath==1.3.0 +multidict==6.7.0 +mypy_extensions==1.1.0 +narwhals==2.12.0 +networkx==3.4.2 +nltk==3.9.1 +numpy==1.26.4 +nvidia-cublas-cu12==12.6.4.1 +nvidia-cuda-cupti-cu12==12.6.80 +nvidia-cuda-nvrtc-cu12==12.6.77 +nvidia-cuda-runtime-cu12==12.6.77 +nvidia-cudnn-cu12==9.5.1.17 +nvidia-cufft-cu12==11.3.0.4 +nvidia-cufile-cu12==1.11.1.6 +nvidia-curand-cu12==10.3.7.77 +nvidia-cusolver-cu12==11.7.1.2 +nvidia-cusparse-cu12==12.5.4.2 +nvidia-cusparselt-cu12==0.6.3 +nvidia-nccl-cu12==2.26.2 +nvidia-nvjitlink-cu12==12.6.85 +nvidia-nvtx-cu12==12.6.77 +oauthlib==3.3.1 ollama==0.6.0 -packaging==25.0 +onnxruntime==1.22.0 +openapi-pydantic==0.5.1 +opentelemetry-api==1.27.0 +opentelemetry-exporter-otlp-proto-common==1.27.0 +opentelemetry-exporter-otlp-proto-grpc==1.27.0 +opentelemetry-proto==1.27.0 +opentelemetry-sdk==1.27.0 +opentelemetry-semantic-conventions==0.48b0 +orjson==3.11.4 +overrides==7.7.0 +packaging==23.2 +pandas==2.2.3 +pathable==0.4.4 +pathvalidate==3.3.1 pillow==12.0.0 +platformdirs==4.5.0 +plotly==6.5.0 +pluggy==1.6.0 +posthog==5.4.0 +propcache==0.4.1 +proto-plus==1.26.1 +protobuf==4.25.8 +psutil==6.1.0 +psycopg==3.2.13 +psycopg-binary==3.2.13 +psycopg-pool==3.2.8 +psycopg2-binary==2.9.10 +py-key-value-aio==0.2.8 +py-key-value-shared==0.2.8 +pyarrow==21.0.0 +pyasn1==0.6.1 +pyasn1_modules==0.4.2 +pybase64==1.4.2 +pycparser==2.23 pydantic==2.12.3 +pydantic-settings==2.12.0 pydantic_core==2.41.4 +Pygments==2.19.2 +PyJWT==2.10.1 +pyOpenSSL==25.1.0 pyparsing==3.2.5 +pyperclip==1.11.0 +PyPika==0.48.9 +pyproject_hooks==1.2.0 +pyrate-limiter==3.1.1 +pytest==7.4.0 +pytest-asyncio==0.21.1 +pytest-cov==4.1.0 +pytest-mock==3.12.0 +pytest-timeout==2.4.0 python-dateutil==2.9.0.post0 +python-dotenv==1.1.0 +python-multipart==0.0.20 +python-ulid==3.1.0 +pytz==2024.2 +PyYAML==6.0.3 +RapidFuzz==3.14.3 +referencing==0.36.2 +regex==2025.11.3 +requests==2.32.5 +requests-cache==1.2.1 +requests-mock==1.11.0 +requests-oauthlib==2.0.0 +requests-toolbelt==1.0.0 +rich==13.9.4 +rich-click==1.9.4 +rich-rst==1.3.2 +rpds-py==0.29.0 +rsa==4.9.1 +s3transfer==0.15.0 +safetensors==0.7.0 +scikit-learn==1.7.2 +scipy==1.15.3 +SecretStorage==3.5.0 +serpyco-rs==1.17.1 +shapely==2.1.2 +shellingham==1.5.4 +simple-websocket==1.1.0 +simplejson==3.20.2 six==1.17.0 sniffio==1.3.1 +snowflake-connector-python==3.18.0 +snowflake-sqlalchemy==1.7.7 +sortedcontainers==2.4.0 +SQLAlchemy==2.0.44 +sqlalchemy-bigquery==1.12.0 +sqlparse==0.5.3 +sse-starlette==3.0.3 +starlette==0.45.3 +structlog==24.4.0 +sympy==1.14.0 +tabulate==0.9.0 +tenacity==8.5.0 +threadpoolctl==3.6.0 +tokenizers==0.22.1 +tomli==2.3.0 +tomlkit==0.13.3 +torch==2.7.1 +tqdm==4.67.1 +transformers==4.57.3 +triton==3.3.1 +typer==0.20.0 +typing-inspect==0.9.0 typing-inspection==0.4.2 typing_extensions==4.15.0 -uuid==1.30 \ No newline at end of file +tzdata==2025.2 +tzlocal==5.3.1 +Unidecode==1.4.0 +url-normalize==2.2.1 +urllib3==2.3.0 +uuid==1.30 +uuid7==0.1.0 +uv==0.8.24 +uvicorn==0.34.3 +uvloop==0.22.1 +vanna==0.7.9 +watchfiles==1.1.1 +wcmatch==10.0 +websocket-client==1.9.0 +websockets==15.0.1 +Werkzeug==3.1.3 +whenever==0.6.17 +wrapt==2.0.1 +wsproto==1.3.2 +xmltodict==0.14.2 +yarl==1.22.0 +zipp==3.23.0 diff --git a/src/api/controller/AskController.py b/src/api/controller/AskController.py index 4d9d0dd..853f577 100644 --- a/src/api/controller/AskController.py +++ b/src/api/controller/AskController.py @@ -26,40 +26,6 @@ class AskController(metaclass=SingletonMeta): # Diretório estático para salvar gráficos STATIC_DIR = os.path.join(os.getcwd(), "static", "graficos") - - def _generate_chart_if_requested(self, resultado, wants_chart: bool): - """ - Gera um gráfico a partir do resultado se wants_chart for True. - Salva o gráfico em arquivo e retorna o link, ou mensagem de erro se não houver dados. - """ - if not wants_chart: - return None - # Garante que o diretório existe - os.makedirs(self.STATIC_DIR, exist_ok=True) - df = pd.DataFrame(resultado) - if df.empty: - return {"output": "Não há dados suficientes para gerar um gráfico."} - - plt.figure(figsize=(8, 5)) - if df.shape[1] >= 2: - x = df.columns[0] - y = df.columns[1] - plt.bar(df[x], df[y]) - plt.xlabel(x) - plt.ylabel(y) - plt.title("Gráfico gerado a partir dos dados") - else: - plt.plot(df[df.columns[0]]) - plt.title("Gráfico gerado a partir dos dados") - - filename = f"{uuid.uuid4()}.png" - filepath = os.path.join(self.STATIC_DIR, filename) - plt.tight_layout() - plt.savefig(filepath) - plt.close() - - link = f"http://localhost:8000/static/graficos/{filename}" - return {"output": f"Gráfico gerado: [Clique aqui para visualizar]({link})", "grafico_url": link} def __init__(self): self.client = genai.Client(api_key=GEMINI_API_KEY) @@ -77,7 +43,7 @@ def __init__(self): # Memória conversacional (mantém últimas 5 interações) self.memory = ConversationBufferWindowMemory( - k=5, # Número de interações a manter + k=5, memory_key="chat_history", return_messages=True, input_key="question", @@ -97,6 +63,40 @@ def __init__(self): self.sql_cache: Dict[str, str] = {} self.result_cache: Dict[str, any] = {} + def _generate_chart_if_requested(self, resultado, wants_chart: bool): + """ + Gera um gráfico a partir do resultado se wants_chart for True. + Salva o gráfico em arquivo e retorna o link, ou mensagem de erro se não houver dados. + """ + if not wants_chart: + return None + # Garante que o diretório existe + os.makedirs(self.STATIC_DIR, exist_ok=True) + df = pd.DataFrame(resultado) + if df.empty: + return {"output": "Não há dados suficientes para gerar um gráfico."} + + plt.figure(figsize=(8, 5)) + if df.shape[1] >= 2: + x = df.columns[0] + y = df.columns[1] + plt.bar(df[x], df[y]) + plt.xlabel(x) + plt.ylabel(y) + plt.title("Gráfico gerado a partir dos dados") + else: + plt.plot(df[df.columns[0]]) + plt.title("Gráfico gerado a partir dos dados") + + filename = f"{uuid.uuid4()}.png" + filepath = os.path.join(self.STATIC_DIR, filename) + plt.tight_layout() + plt.savefig(filepath) + plt.close() + + link = f"http://localhost:8000/static/graficos/{filename}" + return {"output": f"Gráfico gerado: [Clique aqui para visualizar]({link})", "grafico_url": link} + def _detect_chart_request(self, question: str) -> bool: """ Detecta se a pergunta do usuário sugere a geração de um gráfico. @@ -133,24 +133,24 @@ def _preprocess_question(self, question: str) -> str: # Monta o prompt system_prompt = """Você é um assistente especializado em processar perguntas sobre dados do GitHub. -Sua função é: -1. Analisar o histórico da conversa para entender o contexto -2. Resolver referências contextuais (ex: "e no mês passado?", "mostre mais detalhes", "e o outro repositório?") -3. Normalizar expressões temporais: - - "3 meses" → "90 dias" - - "1 ano e 2 meses" → "425 dias" - - Meses separados = 30 dias cada -4. Normalizar terminologia: - - "mudança" → "commit" - - "alteração" → "commit" -5. Expandir a pergunta com contexto necessário do histórico -6. Desenvolver análises robustas dos dados extraídos para que insight valiosos sejam extraídos -7. - -REGRAS CRÍTICAS: -- Se a pergunta fizer referência a algo anterior ("e aquele", "o outro", "também"), inclua o contexto explícito -- Se não houver referência contextual, retorne a pergunta apenas normalizada -""" + Sua função é: + 1. Analisar o histórico da conversa para entender o contexto + 2. Resolver referências contextuais (ex: "e no mês passado?", "mostre mais detalhes", "e o outro repositório?") + 3. Normalizar expressões temporais: + - "3 meses" → "90 dias" + - "1 ano e 2 meses" → "425 dias" + - Meses separados = 30 dias cada + 4. Normalizar terminologia: + - "mudança" → "commit" + - "alteração" → "commit" + 5. Expandir a pergunta com contexto necessário do histórico + 6. Desenvolver análises robustas dos dados extraídos para que insight valiosos sejam extraídos + 7. + + REGRAS CRÍTICAS: + - Se a pergunta fizer referência a algo anterior ("e aquele", "o outro", "também"), inclua o contexto explícito + - Se não houver referência contextual, retorne a pergunta apenas normalizada + """ # Monta mensagens messages = [ @@ -203,7 +203,7 @@ def _validate_sql(self, sql: str) -> tuple[bool, Optional[str]]: r'\bINSERT\b', r'\bUPDATE\b', r'\bALTER\b', - r'\bCREATE\s+TABLE\b', # Só bloqueia "CREATE TABLE", não "created_by" + r'\bCREATE\s+TABLE\b', r'\bCREATE\s+INDEX\b', r'\bCREATE\s+DATABASE\b', r'\bGRANT\b', @@ -243,28 +243,28 @@ def _format_response_with_context(self, question: str, sql: str, result: any) -> history_context += f"Assistente: {msg.content}\n" prompt = f""" -Você é um assistente especializado em análise de dados do GitHub. + Você é um assistente especializado em análise de dados do GitHub. -{history_context} + {history_context} -Pergunta atual: "{question}" + Pergunta atual: "{question}" -SQL gerado e executado: -```sql -{sql} -``` + SQL gerado e executado: + ```sql + {sql} + ``` -Resultado da consulta: {result} + Resultado da consulta: {result} -Com base no contexto da conversa e nos resultados, gere uma resposta: -1. Clara e direta -2. Em linguagem natural -3. Destacando insights relevantes -4. Relacionando com perguntas anteriores se aplicável -5. Formato estruturado se houver múltiplos dados + Com base no contexto da conversa e nos resultados, gere uma resposta: + 1. Clara e direta + 2. Em linguagem natural + 3. Destacando insights relevantes + 4. Relacionando com perguntas anteriores se aplicável + 5. Formato estruturado se houver múltiplos dados -Responda de forma conversacional e útil. -""" + Responda de forma conversacional e útil. + """ try: response = self.client.models.generate_content( From 49642b34cab3baadf4b5dee36392663da59927c4 Mon Sep 17 00:00:00 2001 From: sofianasilva Date: Mon, 1 Dec 2025 17:36:49 -0300 Subject: [PATCH 15/20] loy --- .docker/back-end/Dockerfile | 3 + .docker/django-auth/Dockerfile | 30 + .dockerignore | 44 + docker-compose.yml | 48 + entrypoint.sh | 51 + example.env | 16 +- requirements.txt | 38 +- src/__init__.py | 0 src/api/__init__.py | 0 src/api/controller/__init__.py | 0 src/api/database/__init__.py | 0 src/api/endpoints/__init__.py | 0 src/api/endpoints/routes.py | 12 +- src/api/middleware/__init__.py | 0 src/api/middleware/auth.py | 91 + .../29f4c871-9113-4540-9202-b1c98ea11c7f.png | Bin 0 -> 12405 bytes .../dd549a0f-9ca8-47eb-91f6-58c57bbb7c7b.png | Bin 0 -> 12405 bytes src/assets/__init__.py | 0 src/assets/aux/__init__.py | 0 src/assets/aux/env.py | 15 +- src/assets/open_web_ui/pipeline_api.py | 147 +- src/assets/pattern/__init__.py | 0 src/django_auth/__init__.py | 0 src/django_auth/apps/__init__.py | 0 src/django_auth/apps/auth_app/__init__.py | 0 src/django_auth/apps/auth_app/admin.py | 26 + src/django_auth/apps/auth_app/apps.py | 6 + src/django_auth/apps/auth_app/forms.py | 55 + .../apps/auth_app/migrations/0001_initial.py | 89 + .../0002_remove_unique_constraint.py | 16 + .../apps/auth_app/migrations/__init__.py | 0 src/django_auth/apps/auth_app/models.py | 66 + src/django_auth/apps/auth_app/serializers.py | 102 + src/django_auth/apps/auth_app/tests.py | 293 + src/django_auth/apps/auth_app/ui_urls.py | 20 + src/django_auth/apps/auth_app/ui_views.py | 155 + src/django_auth/apps/auth_app/urls.py | 23 + .../apps/auth_app/urls_internal.py | 6 + src/django_auth/apps/auth_app/views.py | 126 + .../apps/auth_app/views_internal.py | 110 + src/django_auth/generate_keys.py | 28 + src/django_auth/manage.py | 22 + src/django_auth/settings.py | 160 + src/django_auth/templates/auth_app/login.html | 30 + .../templates/auth_app/register.html | 49 + .../templates/auth_app/token_created.html | 95 + .../templates/auth_app/token_form.html | 58 + .../templates/auth_app/token_list.html | 77 + src/django_auth/templates/base.html | 42 + src/django_auth/urls.py | 9 + src/django_auth/wsgi.py | 6 + src/etl/__init__.py | 0 staticfiles/admin/css/autocomplete.css | 275 + staticfiles/admin/css/base.css | 1145 ++ staticfiles/admin/css/changelists.css | 328 + staticfiles/admin/css/dark_mode.css | 137 + staticfiles/admin/css/dashboard.css | 29 + staticfiles/admin/css/forms.css | 534 + staticfiles/admin/css/login.css | 61 + staticfiles/admin/css/nav_sidebar.css | 144 + staticfiles/admin/css/responsive.css | 999 ++ staticfiles/admin/css/responsive_rtl.css | 84 + staticfiles/admin/css/rtl.css | 298 + .../css/vendor/select2/LICENSE-SELECT2.md | 21 + .../admin/css/vendor/select2/select2.css | 481 + .../admin/css/vendor/select2/select2.min.css | 1 + staticfiles/admin/css/widgets.css | 604 + staticfiles/admin/img/LICENSE | 20 + staticfiles/admin/img/README.txt | 7 + staticfiles/admin/img/calendar-icons.svg | 14 + staticfiles/admin/img/gis/move_vertex_off.svg | 1 + staticfiles/admin/img/gis/move_vertex_on.svg | 1 + staticfiles/admin/img/icon-addlink.svg | 3 + staticfiles/admin/img/icon-alert.svg | 3 + staticfiles/admin/img/icon-calendar.svg | 9 + staticfiles/admin/img/icon-changelink.svg | 3 + staticfiles/admin/img/icon-clock.svg | 9 + staticfiles/admin/img/icon-deletelink.svg | 3 + staticfiles/admin/img/icon-no.svg | 3 + staticfiles/admin/img/icon-unknown-alt.svg | 3 + staticfiles/admin/img/icon-unknown.svg | 3 + staticfiles/admin/img/icon-viewlink.svg | 3 + staticfiles/admin/img/icon-yes.svg | 3 + staticfiles/admin/img/inline-delete.svg | 3 + staticfiles/admin/img/search.svg | 3 + staticfiles/admin/img/selector-icons.svg | 34 + staticfiles/admin/img/sorting-icons.svg | 19 + staticfiles/admin/img/tooltag-add.svg | 3 + staticfiles/admin/img/tooltag-arrowright.svg | 3 + staticfiles/admin/js/SelectBox.js | 116 + staticfiles/admin/js/SelectFilter2.js | 283 + staticfiles/admin/js/actions.js | 201 + .../admin/js/admin/DateTimeShortcuts.js | 408 + .../admin/js/admin/RelatedObjectLookups.js | 238 + staticfiles/admin/js/autocomplete.js | 33 + staticfiles/admin/js/calendar.js | 221 + staticfiles/admin/js/cancel.js | 29 + staticfiles/admin/js/change_form.js | 16 + staticfiles/admin/js/collapse.js | 43 + staticfiles/admin/js/core.js | 170 + staticfiles/admin/js/filters.js | 30 + staticfiles/admin/js/inlines.js | 359 + staticfiles/admin/js/jquery.init.js | 8 + staticfiles/admin/js/nav_sidebar.js | 79 + staticfiles/admin/js/popup_response.js | 16 + staticfiles/admin/js/prepopulate.js | 43 + staticfiles/admin/js/prepopulate_init.js | 15 + staticfiles/admin/js/theme.js | 56 + staticfiles/admin/js/urlify.js | 169 + .../admin/js/vendor/jquery/LICENSE.txt | 20 + staticfiles/admin/js/vendor/jquery/jquery.js | 10965 ++++++++++++++++ .../admin/js/vendor/jquery/jquery.min.js | 2 + .../admin/js/vendor/select2/LICENSE.md | 21 + .../admin/js/vendor/select2/i18n/af.js | 3 + .../admin/js/vendor/select2/i18n/ar.js | 3 + .../admin/js/vendor/select2/i18n/az.js | 3 + .../admin/js/vendor/select2/i18n/bg.js | 3 + .../admin/js/vendor/select2/i18n/bn.js | 3 + .../admin/js/vendor/select2/i18n/bs.js | 3 + .../admin/js/vendor/select2/i18n/ca.js | 3 + .../admin/js/vendor/select2/i18n/cs.js | 3 + .../admin/js/vendor/select2/i18n/da.js | 3 + .../admin/js/vendor/select2/i18n/de.js | 3 + .../admin/js/vendor/select2/i18n/dsb.js | 3 + .../admin/js/vendor/select2/i18n/el.js | 3 + .../admin/js/vendor/select2/i18n/en.js | 3 + .../admin/js/vendor/select2/i18n/es.js | 3 + .../admin/js/vendor/select2/i18n/et.js | 3 + .../admin/js/vendor/select2/i18n/eu.js | 3 + .../admin/js/vendor/select2/i18n/fa.js | 3 + .../admin/js/vendor/select2/i18n/fi.js | 3 + .../admin/js/vendor/select2/i18n/fr.js | 3 + .../admin/js/vendor/select2/i18n/gl.js | 3 + .../admin/js/vendor/select2/i18n/he.js | 3 + .../admin/js/vendor/select2/i18n/hi.js | 3 + .../admin/js/vendor/select2/i18n/hr.js | 3 + .../admin/js/vendor/select2/i18n/hsb.js | 3 + .../admin/js/vendor/select2/i18n/hu.js | 3 + .../admin/js/vendor/select2/i18n/hy.js | 3 + .../admin/js/vendor/select2/i18n/id.js | 3 + .../admin/js/vendor/select2/i18n/is.js | 3 + .../admin/js/vendor/select2/i18n/it.js | 3 + .../admin/js/vendor/select2/i18n/ja.js | 3 + .../admin/js/vendor/select2/i18n/ka.js | 3 + .../admin/js/vendor/select2/i18n/km.js | 3 + .../admin/js/vendor/select2/i18n/ko.js | 3 + .../admin/js/vendor/select2/i18n/lt.js | 3 + .../admin/js/vendor/select2/i18n/lv.js | 3 + .../admin/js/vendor/select2/i18n/mk.js | 3 + .../admin/js/vendor/select2/i18n/ms.js | 3 + .../admin/js/vendor/select2/i18n/nb.js | 3 + .../admin/js/vendor/select2/i18n/ne.js | 3 + .../admin/js/vendor/select2/i18n/nl.js | 3 + .../admin/js/vendor/select2/i18n/pl.js | 3 + .../admin/js/vendor/select2/i18n/ps.js | 3 + .../admin/js/vendor/select2/i18n/pt-BR.js | 3 + .../admin/js/vendor/select2/i18n/pt.js | 3 + .../admin/js/vendor/select2/i18n/ro.js | 3 + .../admin/js/vendor/select2/i18n/ru.js | 3 + .../admin/js/vendor/select2/i18n/sk.js | 3 + .../admin/js/vendor/select2/i18n/sl.js | 3 + .../admin/js/vendor/select2/i18n/sq.js | 3 + .../admin/js/vendor/select2/i18n/sr-Cyrl.js | 3 + .../admin/js/vendor/select2/i18n/sr.js | 3 + .../admin/js/vendor/select2/i18n/sv.js | 3 + .../admin/js/vendor/select2/i18n/th.js | 3 + .../admin/js/vendor/select2/i18n/tk.js | 3 + .../admin/js/vendor/select2/i18n/tr.js | 3 + .../admin/js/vendor/select2/i18n/uk.js | 3 + .../admin/js/vendor/select2/i18n/vi.js | 3 + .../admin/js/vendor/select2/i18n/zh-CN.js | 3 + .../admin/js/vendor/select2/i18n/zh-TW.js | 3 + .../admin/js/vendor/select2/select2.full.js | 6820 ++++++++++ .../js/vendor/select2/select2.full.min.js | 2 + .../admin/js/vendor/xregexp/LICENSE.txt | 21 + .../admin/js/vendor/xregexp/xregexp.js | 4652 +++++++ .../admin/js/vendor/xregexp/xregexp.min.js | 160 + .../css/bootstrap-theme.min.css | 6 + .../css/bootstrap-theme.min.css.map | 1 + .../rest_framework/css/bootstrap-tweaks.css | 237 + .../rest_framework/css/bootstrap.min.css | 6 + .../rest_framework/css/bootstrap.min.css.map | 1 + staticfiles/rest_framework/css/default.css | 82 + .../rest_framework/css/font-awesome-4.0.3.css | 1338 ++ staticfiles/rest_framework/css/prettify.css | 30 + staticfiles/rest_framework/docs/css/base.css | 359 + .../rest_framework/docs/css/highlight.css | 125 + .../docs/css/jquery.json-view.min.css | 11 + .../rest_framework/docs/img/favicon.ico | Bin 0 -> 5430 bytes staticfiles/rest_framework/docs/img/grid.png | Bin 0 -> 1458 bytes staticfiles/rest_framework/docs/js/api.js | 315 + .../rest_framework/docs/js/highlight.pack.js | 2 + .../docs/js/jquery.json-view.min.js | 7 + .../fonts/fontawesome-webfont.eot | Bin 0 -> 38205 bytes .../fonts/fontawesome-webfont.svg | 414 + .../fonts/fontawesome-webfont.ttf | Bin 0 -> 80652 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 44432 bytes .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../img/glyphicons-halflings.png | Bin 0 -> 12762 bytes staticfiles/rest_framework/img/grid.png | Bin 0 -> 1458 bytes staticfiles/rest_framework/js/ajax-form.js | 133 + .../rest_framework/js/bootstrap.min.js | 6 + .../rest_framework/js/coreapi-0.1.1.js | 2043 +++ staticfiles/rest_framework/js/csrf.js | 53 + staticfiles/rest_framework/js/default.js | 47 + .../rest_framework/js/jquery-3.7.1.min.js | 2 + .../rest_framework/js/load-ajax-form.js | 3 + staticfiles/rest_framework/js/prettify-min.js | 28 + 213 files changed, 38345 insertions(+), 23 deletions(-) create mode 100644 .docker/django-auth/Dockerfile create mode 100644 .dockerignore create mode 100644 entrypoint.sh create mode 100644 src/__init__.py create mode 100644 src/api/__init__.py create mode 100644 src/api/controller/__init__.py create mode 100644 src/api/database/__init__.py create mode 100644 src/api/endpoints/__init__.py create mode 100644 src/api/middleware/__init__.py create mode 100644 src/api/middleware/auth.py create mode 100644 src/api/static/graficos/29f4c871-9113-4540-9202-b1c98ea11c7f.png create mode 100644 src/api/static/graficos/dd549a0f-9ca8-47eb-91f6-58c57bbb7c7b.png create mode 100644 src/assets/__init__.py create mode 100644 src/assets/aux/__init__.py create mode 100644 src/assets/pattern/__init__.py create mode 100644 src/django_auth/__init__.py create mode 100644 src/django_auth/apps/__init__.py create mode 100644 src/django_auth/apps/auth_app/__init__.py create mode 100644 src/django_auth/apps/auth_app/admin.py create mode 100644 src/django_auth/apps/auth_app/apps.py create mode 100644 src/django_auth/apps/auth_app/forms.py create mode 100644 src/django_auth/apps/auth_app/migrations/0001_initial.py create mode 100644 src/django_auth/apps/auth_app/migrations/0002_remove_unique_constraint.py create mode 100644 src/django_auth/apps/auth_app/migrations/__init__.py create mode 100644 src/django_auth/apps/auth_app/models.py create mode 100644 src/django_auth/apps/auth_app/serializers.py create mode 100644 src/django_auth/apps/auth_app/tests.py create mode 100644 src/django_auth/apps/auth_app/ui_urls.py create mode 100644 src/django_auth/apps/auth_app/ui_views.py create mode 100644 src/django_auth/apps/auth_app/urls.py create mode 100644 src/django_auth/apps/auth_app/urls_internal.py create mode 100644 src/django_auth/apps/auth_app/views.py create mode 100644 src/django_auth/apps/auth_app/views_internal.py create mode 100644 src/django_auth/generate_keys.py create mode 100644 src/django_auth/manage.py create mode 100644 src/django_auth/settings.py create mode 100644 src/django_auth/templates/auth_app/login.html create mode 100644 src/django_auth/templates/auth_app/register.html create mode 100644 src/django_auth/templates/auth_app/token_created.html create mode 100644 src/django_auth/templates/auth_app/token_form.html create mode 100644 src/django_auth/templates/auth_app/token_list.html create mode 100644 src/django_auth/templates/base.html create mode 100644 src/django_auth/urls.py create mode 100644 src/django_auth/wsgi.py create mode 100644 src/etl/__init__.py create mode 100644 staticfiles/admin/css/autocomplete.css create mode 100644 staticfiles/admin/css/base.css create mode 100644 staticfiles/admin/css/changelists.css create mode 100644 staticfiles/admin/css/dark_mode.css create mode 100644 staticfiles/admin/css/dashboard.css create mode 100644 staticfiles/admin/css/forms.css create mode 100644 staticfiles/admin/css/login.css create mode 100644 staticfiles/admin/css/nav_sidebar.css create mode 100644 staticfiles/admin/css/responsive.css create mode 100644 staticfiles/admin/css/responsive_rtl.css create mode 100644 staticfiles/admin/css/rtl.css create mode 100644 staticfiles/admin/css/vendor/select2/LICENSE-SELECT2.md create mode 100644 staticfiles/admin/css/vendor/select2/select2.css create mode 100644 staticfiles/admin/css/vendor/select2/select2.min.css create mode 100644 staticfiles/admin/css/widgets.css create mode 100644 staticfiles/admin/img/LICENSE create mode 100644 staticfiles/admin/img/README.txt create mode 100644 staticfiles/admin/img/calendar-icons.svg create mode 100644 staticfiles/admin/img/gis/move_vertex_off.svg create mode 100644 staticfiles/admin/img/gis/move_vertex_on.svg create mode 100644 staticfiles/admin/img/icon-addlink.svg create mode 100644 staticfiles/admin/img/icon-alert.svg create mode 100644 staticfiles/admin/img/icon-calendar.svg create mode 100644 staticfiles/admin/img/icon-changelink.svg create mode 100644 staticfiles/admin/img/icon-clock.svg create mode 100644 staticfiles/admin/img/icon-deletelink.svg create mode 100644 staticfiles/admin/img/icon-no.svg create mode 100644 staticfiles/admin/img/icon-unknown-alt.svg create mode 100644 staticfiles/admin/img/icon-unknown.svg create mode 100644 staticfiles/admin/img/icon-viewlink.svg create mode 100644 staticfiles/admin/img/icon-yes.svg create mode 100644 staticfiles/admin/img/inline-delete.svg create mode 100644 staticfiles/admin/img/search.svg create mode 100644 staticfiles/admin/img/selector-icons.svg create mode 100644 staticfiles/admin/img/sorting-icons.svg create mode 100644 staticfiles/admin/img/tooltag-add.svg create mode 100644 staticfiles/admin/img/tooltag-arrowright.svg create mode 100644 staticfiles/admin/js/SelectBox.js create mode 100644 staticfiles/admin/js/SelectFilter2.js create mode 100644 staticfiles/admin/js/actions.js create mode 100644 staticfiles/admin/js/admin/DateTimeShortcuts.js create mode 100644 staticfiles/admin/js/admin/RelatedObjectLookups.js create mode 100644 staticfiles/admin/js/autocomplete.js create mode 100644 staticfiles/admin/js/calendar.js create mode 100644 staticfiles/admin/js/cancel.js create mode 100644 staticfiles/admin/js/change_form.js create mode 100644 staticfiles/admin/js/collapse.js create mode 100644 staticfiles/admin/js/core.js create mode 100644 staticfiles/admin/js/filters.js create mode 100644 staticfiles/admin/js/inlines.js create mode 100644 staticfiles/admin/js/jquery.init.js create mode 100644 staticfiles/admin/js/nav_sidebar.js create mode 100644 staticfiles/admin/js/popup_response.js create mode 100644 staticfiles/admin/js/prepopulate.js create mode 100644 staticfiles/admin/js/prepopulate_init.js create mode 100644 staticfiles/admin/js/theme.js create mode 100644 staticfiles/admin/js/urlify.js create mode 100644 staticfiles/admin/js/vendor/jquery/LICENSE.txt create mode 100644 staticfiles/admin/js/vendor/jquery/jquery.js create mode 100644 staticfiles/admin/js/vendor/jquery/jquery.min.js create mode 100644 staticfiles/admin/js/vendor/select2/LICENSE.md create mode 100644 staticfiles/admin/js/vendor/select2/i18n/af.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ar.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/az.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/bg.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/bn.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/bs.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ca.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/cs.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/da.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/de.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/dsb.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/el.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/en.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/es.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/et.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/eu.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/fa.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/fi.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/fr.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/gl.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/he.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/hi.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/hr.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/hsb.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/hu.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/hy.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/id.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/is.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/it.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ja.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ka.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/km.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ko.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/lt.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/lv.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/mk.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ms.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/nb.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ne.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/nl.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/pl.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ps.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/pt-BR.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/pt.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ro.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/ru.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/sk.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/sl.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/sq.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/sr-Cyrl.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/sr.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/sv.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/th.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/tk.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/tr.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/uk.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/vi.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/zh-CN.js create mode 100644 staticfiles/admin/js/vendor/select2/i18n/zh-TW.js create mode 100644 staticfiles/admin/js/vendor/select2/select2.full.js create mode 100644 staticfiles/admin/js/vendor/select2/select2.full.min.js create mode 100644 staticfiles/admin/js/vendor/xregexp/LICENSE.txt create mode 100644 staticfiles/admin/js/vendor/xregexp/xregexp.js create mode 100644 staticfiles/admin/js/vendor/xregexp/xregexp.min.js create mode 100644 staticfiles/rest_framework/css/bootstrap-theme.min.css create mode 100644 staticfiles/rest_framework/css/bootstrap-theme.min.css.map create mode 100644 staticfiles/rest_framework/css/bootstrap-tweaks.css create mode 100644 staticfiles/rest_framework/css/bootstrap.min.css create mode 100644 staticfiles/rest_framework/css/bootstrap.min.css.map create mode 100644 staticfiles/rest_framework/css/default.css create mode 100644 staticfiles/rest_framework/css/font-awesome-4.0.3.css create mode 100644 staticfiles/rest_framework/css/prettify.css create mode 100644 staticfiles/rest_framework/docs/css/base.css create mode 100644 staticfiles/rest_framework/docs/css/highlight.css create mode 100644 staticfiles/rest_framework/docs/css/jquery.json-view.min.css create mode 100644 staticfiles/rest_framework/docs/img/favicon.ico create mode 100644 staticfiles/rest_framework/docs/img/grid.png create mode 100644 staticfiles/rest_framework/docs/js/api.js create mode 100644 staticfiles/rest_framework/docs/js/highlight.pack.js create mode 100644 staticfiles/rest_framework/docs/js/jquery.json-view.min.js create mode 100644 staticfiles/rest_framework/fonts/fontawesome-webfont.eot create mode 100644 staticfiles/rest_framework/fonts/fontawesome-webfont.svg create mode 100644 staticfiles/rest_framework/fonts/fontawesome-webfont.ttf create mode 100644 staticfiles/rest_framework/fonts/fontawesome-webfont.woff create mode 100644 staticfiles/rest_framework/fonts/glyphicons-halflings-regular.eot create mode 100644 staticfiles/rest_framework/fonts/glyphicons-halflings-regular.svg create mode 100644 staticfiles/rest_framework/fonts/glyphicons-halflings-regular.ttf create mode 100644 staticfiles/rest_framework/fonts/glyphicons-halflings-regular.woff create mode 100644 staticfiles/rest_framework/fonts/glyphicons-halflings-regular.woff2 create mode 100644 staticfiles/rest_framework/img/glyphicons-halflings-white.png create mode 100644 staticfiles/rest_framework/img/glyphicons-halflings.png create mode 100644 staticfiles/rest_framework/img/grid.png create mode 100644 staticfiles/rest_framework/js/ajax-form.js create mode 100644 staticfiles/rest_framework/js/bootstrap.min.js create mode 100644 staticfiles/rest_framework/js/coreapi-0.1.1.js create mode 100644 staticfiles/rest_framework/js/csrf.js create mode 100644 staticfiles/rest_framework/js/default.js create mode 100644 staticfiles/rest_framework/js/jquery-3.7.1.min.js create mode 100644 staticfiles/rest_framework/js/load-ajax-form.js create mode 100644 staticfiles/rest_framework/js/prettify-min.js diff --git a/.docker/back-end/Dockerfile b/.docker/back-end/Dockerfile index 883d59f..c97b8e7 100644 --- a/.docker/back-end/Dockerfile +++ b/.docker/back-end/Dockerfile @@ -7,6 +7,9 @@ WORKDIR /app # Forçando output sem buffer (Error Handling?) ENV PYTHONUNBUFFERED=1 +# Indicate this is running in Docker +ENV DOCKER_CONTAINER=true + # Copia os arquivos do projeto para o contêiner COPY requirements.txt . diff --git a/.docker/django-auth/Dockerfile b/.docker/django-auth/Dockerfile new file mode 100644 index 0000000..5bcc87c --- /dev/null +++ b/.docker/django-auth/Dockerfile @@ -0,0 +1,30 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + gcc \ + postgresql-client \ + && rm -rf /var/lib/apt/lists/* + +# Copy requirements and install Python dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Copy application code +COPY . . + +# Copy and set up entrypoint script +COPY entrypoint.sh /app/entrypoint.sh +RUN chmod +x /app/entrypoint.sh + +# Set Python path to include src directory +ENV PYTHONPATH=/app/src:/app + +# Indicate this is running in Docker +ENV DOCKER_CONTAINER=true + +EXPOSE 8001 + +CMD ["/app/entrypoint.sh"] \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..747a507 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,44 @@ +# Virtual environments +.venv/ +.venv-*/ +venv/ +env/ + +# Python cache +__pycache__/ +*.pyc +*.pyo +*.pyd +.Python + +# IDE files +.vscode/ +.idea/ +*.swp +*.swo + +# OS files +.DS_Store +Thumbs.db + +# Git +.git/ +.gitignore + +# Documentation +*.md +docs/ + +# Test files +test_*.py +*_test.py + +# Logs +*.log + +# Database files +*.db +*.sqlite3 + +# Node modules (if any) +node_modules/ \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 42e28dd..7143b7b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,8 @@ services: context: . dockerfile: .docker/db/Dockerfile restart: always + env_file: + - .env environment: POSTGRES_USER: ${DB_USER} POSTGRES_PASSWORD: ${DB_PASSWORD} @@ -36,6 +38,8 @@ services: volumes: - .:/app # Monta o código local (opcional, para desenvolvimento) - /var/run/docker.sock:/var/run/docker.sock # Monta o socket do host + env_file: + - .env environment: - GITHUB_TOKEN=${GITHUB_TOKEN} - DB_HOST=${DB_HOST} @@ -46,20 +50,63 @@ services: - DB_URL=${DB_URL} - GEMINI_API_KEY=${GEMINI_API_KEY} - GEMINI_MODEL_NAME=${GEMINI_MODEL_NAME} + - INTERNAL_AUTH_TOKEN=${INTERNAL_AUTH_TOKEN} + - JWT_SECRET_KEY=${JWT_SECRET_KEY} + - DJANGO_VALIDATE_URL=http://django-auth:8001/internal/validate-token/ command: ["python", "main.py", "--etl"] ports: - 8000:8000 depends_on: - db + - django-auth networks: - open - oraculo + django-auth: + container_name: django-auth-container + build: + context: . + dockerfile: .docker/django-auth/Dockerfile + volumes: + - .:/app + env_file: + - .env + environment: + - DJANGO_SECRET_KEY=${DJANGO_SECRET_KEY} + - FERNET_KEY=${FERNET_KEY} + - DEBUG=${DEBUG} + - DB_HOST=${DB_HOST} + - DB_PORT=${DB_PORT} + - DB_NAME=${DB_NAME} + - DB_USER=${DB_USER} + - DB_PASSWORD=${DB_PASSWORD} + - CREATE_SUPERUSER=${CREATE_SUPERUSER:-false} + - INTERNAL_AUTH_TOKEN=${INTERNAL_AUTH_TOKEN} + - JWT_SECRET_KEY=${JWT_SECRET_KEY} + ports: + - 8001:8001 + depends_on: + - db + healthcheck: + test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8001/api/me/')"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + networks: + - oraculo + front-end: container_name: open-webui-container build: context: . dockerfile: .docker/front-end/Dockerfile + env_file: + - .env + environment: + - INTERNAL_AUTH_TOKEN=${INTERNAL_AUTH_TOKEN} + - JWT_SECRET_KEY=${JWT_SECRET_KEY} ports: - 3000:8080 volumes: @@ -68,5 +115,6 @@ services: depends_on: - db - back-end + - django-auth networks: - oraculo diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..85e273f --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' + +echo "=== Django Auth Service Starting ===" + +# Debug: Show critical environment variables +echo "Environment variables check:" +echo " JWT_SECRET_KEY: ${JWT_SECRET_KEY:0:20}..." +echo " INTERNAL_AUTH_TOKEN: ${INTERNAL_AUTH_TOKEN:0:20}..." +echo " DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:0:20}..." +echo " DB_HOST: ${DB_HOST:-not_set}" + +# Wait for database +echo "Waiting for database at ${DB_HOST:-db}:${DB_PORT:-5432}..." +while ! pg_isready -h "${DB_HOST:-db}" -p "${DB_PORT:-5432}" -U "${DB_USER:-postgres}" > /dev/null 2>&1; do + echo "Database not ready, waiting..." + sleep 2 +done +echo "✓ Database is ready!" + +# Change to Django project directory +cd /app/src/django_auth + +# Run Django migrations +echo "Running Django migrations..." +python manage.py migrate --noinput + +# Collect static files (skip if fails, not critical for development) +echo "Collecting static files..." +python manage.py collectstatic --noinput || echo "Static files collection skipped" + +# Create superuser if environment variable is set +if [ "${CREATE_SUPERUSER:-false}" = "true" ]; then + echo "Creating superuser..." + python manage.py shell -c " +from django.contrib.auth.models import User +if not User.objects.filter(username='admin').exists(): + User.objects.create_superuser('admin', 'admin@example.com', 'admin123') + print('Superuser created: admin/admin123') +else: + print('Superuser already exists') +" || echo "Superuser creation skipped" +fi + +# Show migration status for debugging +echo "Migration status:" +python manage.py showmigrations --plan || true + +echo "Starting Django development server on 0.0.0.0:8001..." +exec python manage.py runserver 0.0.0.0:8001 \ No newline at end of file diff --git a/example.env b/example.env index bcee7a6..71fb637 100644 --- a/example.env +++ b/example.env @@ -1,5 +1,5 @@ # Airbyte -GITHUB_TOKEN= +GITHUB_TOKEN= # Database credentials DB_HOST=db @@ -11,6 +11,18 @@ DB_USER=postgres DB_PASSWORD=postgres DB_URL=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} +# Django Authentication Service +DJANGO_SECRET_KEY=_!4)%93^%r##9x7vfb5f7k++)55#d0x-oy)sdw2*o&(qe^$=m +FERNET_KEY=NcGXqZ6IMCBJGDDqchlpWJLNGpstFvgC5Nw_ksDB-qk= +DEBUG=True +CREATE_SUPERUSER=false + +# Internal authentication for backend-to-backend communication +INTERNAL_AUTH_TOKEN=UfBsUbCUaUmAZ-NlA43gLMBjShEpjW4T6be_NgVc3dI + +# JWT Secret Key for token generation and validation +JWT_SECRET_KEY=jwt-secret-key-for-oraculo-auth-system-keep-secure-2024 + # Google cloud gemini -GEMINI_API_KEY= +GEMINI_API_KEY= GEMINI_MODEL_NAME=gemini-2.0-flash \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 2bd7127..1bb37ee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,15 @@ -airbyte==0.31.3 FastAPI==0.115.9 uvicorn==0.34.3 -psycopg2-binary==2.9.10 python-dotenv==1.1.0 + +psycopg2-binary==2.9.10 +SQLAlchemy>=2.0.0 + +pydantic>=2.0.0 + +airbyte==0.31.3 +pandas==2.2.3 + vanna==0.7.9 chromadb google-genai @@ -11,18 +18,27 @@ onnxruntime==1.22.0 langchain-google-genai<1.0.0 langchain -pytest==7.4.0 -pytest-asyncio==0.21.1 -pytest-mock==3.12.0 -pytest-cov==4.1.0 -httpx -requests-mock==1.11.0 - torch>=2.2.0,<2.8.0 transformers>=4.35.0,<5.0.0 tokenizers>=0.15.0,<1.0.0 scikit-learn>=1.5.2,<2.0.0 numpy>=1.21.0,<1.27.0 -matplotlib==3.9.2 -pandas==2.2.3 \ No newline at end of file +matplotlib==3.9.2 + +Django>=4.2,<5.0 +djangorestframework>=3.14.0 +djangorestframework-simplejwt>=5.2.0 +cryptography>=3.4.8 +gunicorn>=21.2.0 + +httpx +requests>=2.25.0 +requests-mock==1.11.0 + +pytz>=2021.1 + +pytest==7.4.0 +pytest-asyncio==0.21.1 +pytest-mock==3.12.0 +pytest-cov==4.1.0 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/api/__init__.py b/src/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/api/controller/__init__.py b/src/api/controller/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/api/database/__init__.py b/src/api/database/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/api/endpoints/__init__.py b/src/api/endpoints/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/api/endpoints/routes.py b/src/api/endpoints/routes.py index ac4905d..24b826d 100644 --- a/src/api/endpoints/routes.py +++ b/src/api/endpoints/routes.py @@ -1,7 +1,8 @@ -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, HTTPException, Depends from fastapi.responses import FileResponse from src.api.models import Question from src.api.controller.AskController import AskController +from src.api.middleware.auth import validate_user_jwt import os router = APIRouter() @@ -9,10 +10,15 @@ ask = AskController() @router.post("/ask") -async def ask_question(question: Question): +async def ask_question(question: Question, user_info: dict = Depends(validate_user_jwt)): + """Ask a question to the LLM - requires valid JWT and AccessToken""" try: - return ask.ask(question) + print(f"[ASK] Processing question for user {user_info.get('user_id')}: {question.question}") + result = ask.ask(question) + print(f"[ASK] Response generated successfully") + return result except Exception as e: + print(f"[ASK] Error processing question: {e}") raise HTTPException(status_code=500, detail=str(e)) diff --git a/src/api/middleware/__init__.py b/src/api/middleware/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/api/middleware/auth.py b/src/api/middleware/auth.py new file mode 100644 index 0000000..799e8ef --- /dev/null +++ b/src/api/middleware/auth.py @@ -0,0 +1,91 @@ +import os +import sys +import requests +from fastapi import Depends, HTTPException, status +from fastapi.security import HTTPBearer + +JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY") +if not JWT_SECRET_KEY or JWT_SECRET_KEY.strip() == '': + print("CRITICAL ERROR: JWT_SECRET_KEY environment variable is not set or empty!") + print("This is required for JWT token validation in FastAPI.") + print("Available environment variables:") + for key in sorted(os.environ.keys()): + if 'JWT' in key or 'SECRET' in key or 'TOKEN' in key: + print(f" {key}={os.environ[key][:20]}..." if len(os.environ[key]) > 20 else f" {key}={os.environ[key]}") + print("Please ensure JWT_SECRET_KEY is set in Docker Compose environment.") + sys.exit(1) + +security = HTTPBearer() +DJANGO_VALIDATE_URL = os.getenv("DJANGO_VALIDATE_URL", "http://django-auth:8001/internal/validate-token/") +INTERNAL_AUTH_TOKEN = os.getenv("INTERNAL_AUTH_TOKEN") + +if not INTERNAL_AUTH_TOKEN or INTERNAL_AUTH_TOKEN.strip() == '': + print("CRITICAL ERROR: INTERNAL_AUTH_TOKEN environment variable is not set or empty!") + print("This is required for backend-to-backend authentication.") + print("Available environment variables:") + for key in sorted(os.environ.keys()): + if 'JWT' in key or 'SECRET' in key or 'TOKEN' in key: + print(f" {key}={os.environ[key][:20]}..." if len(os.environ[key]) > 20 else f" {key}={os.environ[key]}") + print("Please ensure INTERNAL_AUTH_TOKEN is set in Docker Compose environment.") + sys.exit(1) + +def validate_user_jwt(credentials=Depends(security)): + """Validate JWT token with Django auth service and check AccessToken existence""" + if not INTERNAL_AUTH_TOKEN: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Internal auth not configured" + ) + + jwt_token = credentials.credentials + headers = { + "Authorization": f"Bearer {INTERNAL_AUTH_TOKEN}", + "Content-Type": "application/json" + } + + try: + print(f"[AUTH] Validating JWT with Django at {DJANGO_VALIDATE_URL}") + resp = requests.post( + DJANGO_VALIDATE_URL, + json={"jwt": jwt_token}, + headers=headers, + timeout=10 + ) + print(f"[AUTH] Django response: {resp.status_code} - {resp.text}") + except requests.RequestException as e: + print(f"[AUTH] Request failed: {e}") + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Auth validation failed - service unavailable" + ) + + if resp.status_code != 200: + try: + error_detail = resp.json().get("detail", "Unauthorized") + except: + error_detail = f"Unauthorized (HTTP {resp.status_code})" + print(f"[AUTH] Validation failed: {error_detail}") + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=error_detail + ) + + try: + body = resp.json() + if not body.get("has_active_access_token"): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="No active access token" + ) + + print(f"[AUTH] Validation successful for user {body.get('user_id')}") + return { + "user_id": body.get("user_id"), + "username": body.get("username") + } + except Exception as e: + print(f"[AUTH] Response parsing failed: {e}") + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Invalid response from auth service" + ) \ No newline at end of file diff --git a/src/api/static/graficos/29f4c871-9113-4540-9202-b1c98ea11c7f.png b/src/api/static/graficos/29f4c871-9113-4540-9202-b1c98ea11c7f.png new file mode 100644 index 0000000000000000000000000000000000000000..57a271f22502997b6aa8b641fdd1544e1de28973 GIT binary patch literal 12405 zcmeHtXH=9~x^5w@cAKzNf>ihQI@AE$44L@k0w|a%( z3JQg?TK^aA!xRelCJKdX{QG72P1PQKKm4WQrE}EF$j!ma_k@Q%<-iHAGtO>a&ZlfP z`Ph4So^o@QlU9-5ExGBWm)99jRT&wVzg{5i=HV#wqXBmtKIDfpznFPaC_E>~AFc;l zX{RU@nQndUpN;))4|VwanM}~9hqmw6zs~#2E9~sqP3K;7uhGkRaOe9SHX;x1rJda? zvgeVq6K_pQriuC*$8!oE8JExFf#l-6p%z&~bZC)DPb; z>C!G48L0EVk>6r9(54nX9P5->I!2RZETK>~{dPJ|19$bU`(|_*y5rl+vob z9~1vFvEcDW@&-MzV6SwSw_QSye_Zli>t{Zx zV;fR+qa!SR+P0o<$r8zTYKbvORIPe(d2`Q5C}+;WE&J}>Eisz2{mK*XjC!VfVr6{i zYQ#c?$>(g~J%vK@G*b)(8$qAeM5m!x@mSyq)eG#dKqQ;9UBFSK+5qsMbFRm z0=w;gdH3MZ<_l{?1UsI1N1kqaRF$4xCKx*3BWC;T&p+gxY)m=X^r&f@+gNXcbqsa0 zZso(Yq+=h4#y-D{jN4^eZJ%Jt7d$ulQmVW+-aI8Q&nr@FeS30Kx@pbU1dDZ4>fBJF z^^Nur_E>Tay)Vi92O}=$1_*-BxKV@gLh=Xzkr(;{Nu4 zl1~0W)olkP z_{FH4kP}J)J74wskG-44yID12v8get5@ZWLc)( zxw9!EBBJ}lIi8sEg&{Y(cXO7dP=ck8S)NO~;^^2|s`o&%JA0;2PhY=wn+DI@G{abI zyUx!)|LpbU&DPlPw*5PljNMMWx-HsJ2SElO4in_O0`o^_8SXo&` z2`Wh3-+yCWqMC2a{QUg%OSh2qIyyR3s(bC$1Z`aKskgVPir-q8%4^MixY5Uf^}h{rS>N-v*5-?F4Ddy7?GWyQW7b?$sL|wcXv_KlSzLU0fs5{WU#XdTK1F|Bs6{ z$-$H17gh`Dq7qW~UR*=AB6P@>yG%rwi>u(q4LL{MVxJ)!d>%7nF4MADadu*We{L|> z&?0!Ei5^*>W|%CB;~a6-P*X)v;q(T;fR{z+!o=d;-N%bmD!;{bVmJ5IlQKn+Df_gphF2!HeDjev@W-7uTq((8~#$V{*7@rttoKONtr zj)if5{qyoTHNkHmFN#%n29Agj6lzS>(?em}jDD(>J^A`h(Lh#l_qXRfUHv^>@B9_* zu=MWVo-VJk3LN4spYN5iog8eF^%-nETI}Ou5%A?6eIl!P_=$l0$%CszROOp9%+{j_ zB1u^~yt=)Sd-)p4+?RTy{#%Ai#$E|1oHmwsWhy`M9^k`y4tjxn)&Y+Mc4Gn8@Ld;u=!Fj)~q!N>Fd^ zL-{SbmF0#x>Ypy{wE?6@k}?BS*gpMzDGRmlJl@9@6lq6kuNduR$Xa)3!6YZ;zP zuZ|T<*3tIqOZ5F5pLr}_!U>R$_hIWi8M|iNqJ@;Qm|f;m!yUPwU*2*|4w*gW+IEgd z^XRbed{W?Wt++T@bcXX7s<(c0bdKBTN-vWhgP9Gj|$u&@W_ zg|75=9J2Bq5)yU69ezF0z0E2!pRO{b=0?3Yp{uZF`jYj^Ll(ptG*Z8cfz=!390-C& ziKrDYT?P#4bl^GAzy7+cy{lGFl$^M@Vt~XOKr_Eg*|g34r|nuh$JED%JJhgs#~jGn z)jPLrb$10fPgJbt?2f4>KsULM`b4$D`dOFvdEp@ovvKWx3EA9cWkLQy_25vd2d9MnE=|Fyx$-%Wmc_@Acqwx}MuJQ%VLU9H+W2;>k@SbnAp!|!>&=0>Yj}LSmF6XcxSd|7uiE2ElA0;S@62(*X zikfRzCbP%4y9si&@8nwIynfp z=T5wg?fWprMH<&0%R6~_&iDBR(e_I}?oBbxwj#|=j}V-TTJtBE{(Xry-xX}mLLUxa zwpvgd^t0z)f|Z1C`>fNS%I24hGJuJUQn@3iPMs3=`|ukJWUXc?zr|WCMg;gyrP@fz zda&bh#ZY%zre>IHDH_*F@S^=UcHeu}-eSF_)JkW>FaONPXZ@gEUW2W&S@h30Egp2> zL=h0)7Rr@yItd(G9bdnJFd?Sb+XLjRJ-}Y=zbXIlStPBnx%j-v=i->5Cj(im_fFYW z^*7`e8<=f%RMD6Fx4KgzrRz!)zr`OdbhTW(&D!nBl`4I=*Ndq6M3LJ>{}y_Fk*Di^ z`M&e#&$C)>V;5Tk4ozfRt|OL@NhJWLKKN z{*|G#U($pY=C4c?N*#TChv{N%*<9e#?l=AMVk-8fYx?|9GH1ST$IhMMfD$FbhMA+; zNoDyVSvaAo^^NE6?MsLctjPqyuEOa#;%c2;HhcPpi%YG#kkPSYf`m8@KhV>z1fvtB zUM}trtd81v=-|P%JnG-}fR*(%-;zJ|X4{CP`LfRi0c8W=mwPX)3jcBMg-U>U_j0Z2 zpNS@ON6T>eHgwiJ|1_^m>G)wgvm>8nL%ov;ww17F2W0(6KTX#fhFmdczuwE^@+~L0 z$+WNyB}Sgawzn?MKIV7h@m5lE!L#Gxn!&S`3N04v%crYkx_@6O9Y*);i=S~8`_R59 z89V`BdZ^7FY)Ld^;bZ1dn`vi&r)_ij(b?`u84t#<`}TQ`+#WkXl;LH2v-6x9zXfNa zAi}~}Jv9mRg_}-U;bA+b*6g!xPSJ_%e{*l&JbS8K##7?GHG4F{58K7a2n43qphCK7 z4C!5kiG%~Dp_AmtIxcWFvPZ|B1kH?k$W+cv4haD$qp*Ty^-rvWqab1C3FA)2l3C&|_Ihye)G0*IMmtiJ1JO1TryCK>|hIyfMVJ8ZncZ%uR zux-S4K`qmzZmfh}P&KxIGD@IZM~kT68)W}f%}ux>GfY+c{Iik(g)5hTP3g-ce873EGn#M^1ah$85x<`sSz`5vAtTx&^N`c8NJlY2S}0w1u*8ua~XS221xy{&SMO8R4t<4H5+b<>}u7 zVzb|Sw^-VuAIHcwsLSD|N*~~WqTSg>#+)4lj2fh)(m27c zYtWU%h{Sg7cv1zRwdt-5XF)XRqQmsua7+rXy}G^T!_#xN9Q28P%@9_kb>)eRB7CU1 z2qJ=M_KfZeLat$86xYJ9;Bjk!z5+ef(UGL5tWoX1LtvoI#n|62_IH(sqD!d~XuhuQ??G0_q5gVKBhO_fsPuiHHq?{I^9!pZ!TjW) ziFv0we64ST!_nWqS++)4pvA)TfN;>ar>s=5g&pydX6sPEws}r1(rg?|w>Kd~y85`E(Jg{D8%b=`#(Bk%pwGwkJq2j*L zRSAh_p8eqde6>=gVaVv!>sp~9@@}2#uHfDlXER%JY->)o7r2lIW z6C@M>56lChU3|U{FQY}?T{Tltcyv~&b4i&KpXAX?i9w^aX3%yt*aR7mAOAD}GU)S0 zf4hBy7ANR0oVe+sQQEVilJPhD+PIbrUuuFyunWx0K=sSrLFmEQ*ZCvqbJm(tK|~bI@KBI=2J=4v%@bX3x`p4xuO~YcIXjiIFht1%VGz|=0^@5yp-?Sp<4X)Q97+_Vb~W;I+9PSF0&8?FnDF3 zbnQ(gwPohbe0EI}H=mm+gKLo+Jk_D(1ZyfjIXO8W_K4a*MlP+Fkq|m0 z8Obm63SIbGQFaiU>T^FwjZ|NzEt|{*~(sa zCj<=Y<1*>aW+5RV&Dhbw*wA^~^Pz6LOtb0@v=+uQAm_|rEG^zM*}u9H4c2WHPZ|*d zPK_x#L{X57+GJ~lua=_C+#0vwHnFyfcd1rcOL68UE?`PZibvnOG0rM6O?6;m)`~9u z)o0ygTFz3O_gV+BbTTZ93+icLBl1>$AJ4bCl`lv*?w~x-2D@p!(1{1{#{#(~vamcFO_wk~n-3Mgx%bAI>H^#( z0@W$Myi!;+K=IjsHACAw6o`PJ^XxR|)Yeic70p2Q3=8^hkT9Uf-HuB`(t8M;g12T3 z%2FuDizi>HjcCJ7P?`&Aw>> z(b#$EFh^FxYHigm`_j8c`cKRM`t|>i7yDltxBH{(M2`nH%`)dC0%7tN>~*tLc}&x5 z6-OKSFW>Y}Tf_f`Pu?H5@)9h*s`LC-0z`|!-Xqv);nQZ1?X!=C!|(iuV4OyUsU=)g zV%U(T;5E!t0WU1C3ZrgLfzu!hIbSErgMC?IBE5$cpfWT8IW<&jBZvnqS@v4OB(@ro z4}2)$yP_FKK?G7Dyu~_HLtLDk+39l5Tsi4Kf4%CvPiRunyt|HQqsmiZn&tplin=3q z+4R5ugE!0i@Zoh^w{E46m}VTkeA*aCO3sA7d6RFazatpOT{!&OyP?xYLC5BFq9m(PzDEljrez;~1?4AIfs z6A>9n^yndo<1KQgcPHpmChyC*D6Ju--n|vSc5uj9#Zq)lPx!>CEp>v9JCu2>jav>a zEEZgNMN0$RU6_*_Qc*MJ59*e__~W9eps9ts&S2hKgGLa;MZ=8nIonu`0-7E-&fP(5 z53wkvOTIl*?!9JYQ+s7A@FG$fE=>=3|D(Z1Bok7`y-V&wUCP4670?O^vX4a$;cRa* zZ21_k4ki4vk;T8^T>jr!OaJgao9y000D2lMM>twgAp%9%51BhZjA*GvlLK?G~($2 zYmOk%Vm2^3Wnt@IS9Z6F5>}!8&uZ)N?b0Bb$RcD}KJf~Nbs-6pP7IE9=6_b3=JGA# z-Iw;R3E#U$SVZ@xb2Br@-x2{GoD^+N+ zA}?6g`wv6V*O5S1*Jw)sZ))y zhi|w%2&sZxz74}8P6N;TnAfa_c_L0L|xj*GLXh#0A_hL1X zc4~u<_u9u|>72I$Jz$TKlp+d79nwm2z40Pofbdu0T|zLn+V4*6`}NlpB)n4#XjKJG zf5D5xdV3%c5~tf5LimjC?+=GmIq;;R$i0X3GI}=BNEh|3Sm^`3_Ga-WlWPY$JR3CJ z;dSVt!Fe*^lJoof`=it4!@Ak&X|7%MzjR8w+)$IhS=inyjwEXacSE^I<~mn~Q5zxN zl>2Ub)>Y|gYlBY1xk(cQet}p>>_G;?kCNP(n}Gnck(j#-&_uUn3Gda|y2rukcp8b( z{?ynbllXtdk?!yD*FT@w|10;Ly2zXVwPf`l?mPd7+y=mz#ENh!1BnK>DSv9+x#c`D zh%ho~HE2f#zoQ+6&M>TPKE1fiYAI(chz9ikF%5sL`_8#F5ok9i|Iz&pwQ&bEkqjs( zl!Ts0plsOlGdUw=b4T8Q9#%9T>|OFHo!H$}DzP2T7baZ0rj4dFJcn+xTnnupr!IoSzx5GQ zVH3$Cp=N7B=7#uR-co7^?tse@ry+>f&p%>PFOdd~J3lV;&_i#}|EGq3&$!ONt@t0( zxIEyW6T6j+cuYbG`F+0OC=s{?8@SS>mO@7cPhvQdF8aYpPDQBJ2=9u9I@GZHdYTqlYyx~SPm<_!}m79HesJV`NUVFnv&Oc-x9 zSX69_5)gAmdPISpe4lsfMlYykw5fG)K64ft?9k!ESLQ-UUPmQSql;R9%MK|s%ZGEz zF%x9mmhIUxqQ#)Od2vw6w}`z$CNr*?TUl6G{O}gXyrAiLkiFqIVwpt2g>jx-0G%T- z`y24CX8;v#5=7+opoS2f#A7lU{(~nD)4FQafx$4_t5(`-)n;95tOh36xHfgwV4C*j@`*_8orOE*g3P}`!y zyYuU^7f79K5EQ#N>hM>=NnA^O9MJEC;-65m(>}EfxEKTI`QXHr=(*h(FWBY#s}!YO zZ1HFs^=gI@4EZaktY`_CXfj}@`GA81|}k45b7d*BqKTGxR8JVO1B7ZW-6r0 zWq53JgZCzoN)r@z|8g&ZP#udPR#mTo?=ccqA){=BSGhw{GHQ*8Y9)+!QwI)`s@SLJ zme-JpAAnda_GEEJ4U=XsGCeUBq0^A0kqWs>9OCK5*pLk*;qNHJVmcTFTZz`nMkD}425h_6jN5aBL)CjjDfy~?uVguYip68Fh!E;us z@B8m7d@INj)d+j;pC3&qk3xj3ek99cBN-RKfEcn)%Xy4$#DK`Elueb6RFR@0V)WwiU!_Woee)OGh;g=+##Au2hjH6R0gIuGoZdDq(I*0oK?ka0v$#h) znXIq{RyLLfPLbv7LD<0jG(%!5lCzPZQ(PQCLM2;5khhs&I?1WY(I!I@^YeXLGE)MS zR?M1yP`iWAW+8T5jBQASvM|x2haAfWmXNvq9GO`nnNH2cb zk4$zE)Bd`u_i1hI{fVjy*tB&Dr|0LKKcyuFNRWw7l1^f(tr|jspG>CFYbX`*;JsZ` zD1}B8UD2m2`?@i=8Hw$$f(;Hoi;qklT{D{^(+1%7E~5p>2(ntSLW}cYBf%qqjo7!N zMQ1)byqv;tT{Rg@#R0bu;>>l$A`XdHQKgZXi%d(pmM=^aK;C~_+5PI2EJow5YXtg` znq*;2rV@jfo`o9Nn?@vlMIU}&nSwz$Qmte#!a-vhr7S7(HCGuo8HBqo=V%~I(kQqk zeu%Jb0p~fGE~_T`l0Yg#Y+X#}*dq03&5t$IT-#}+=s!2qUKrcOVNa1zT>F-yOLsxL zYa|>D9sFC-Ur22z&*&YNGOL_DtNi8e)ox53M8Igss8=NuZ{z)qo5@fj`l>9MmH;j) z`HPY90Q5gevc|-!Mf{dqZ%dpIa>jD-at%r%L2U_lMRO0qu07~}irrp1|Q z=mCHB9v|t_(v1}rK`a(dhEXu8Bbe*h5JOHR{GRgKb}eEsl2Clr#@$;;?M@@#Bzw`8 zu`v?Urp@MV(PXqI%^DmCI$QY0=3OvQSJS4}i_6k_hS(hy`3|a>5 zBIQHzDU4=D5nG6)-CDSw<&bsKIr5xOe;p$W}rh!m1uYMG*uNt)ApuQ2;Ribnj2LxiT1;YF0gD_vbNQg z$e_vDhU^HeoM!dd!Vn`oaPa}PaX+U>^q*2T~|ApeL6|`ni mKRXer@Za8mzh8K>wJy;2t=k#w3~fxI=<670XZ`8;@BafZ8heod literal 0 HcmV?d00001 diff --git a/src/api/static/graficos/dd549a0f-9ca8-47eb-91f6-58c57bbb7c7b.png b/src/api/static/graficos/dd549a0f-9ca8-47eb-91f6-58c57bbb7c7b.png new file mode 100644 index 0000000000000000000000000000000000000000..57a271f22502997b6aa8b641fdd1544e1de28973 GIT binary patch literal 12405 zcmeHtXH=9~x^5w@cAKzNf>ihQI@AE$44L@k0w|a%( z3JQg?TK^aA!xRelCJKdX{QG72P1PQKKm4WQrE}EF$j!ma_k@Q%<-iHAGtO>a&ZlfP z`Ph4So^o@QlU9-5ExGBWm)99jRT&wVzg{5i=HV#wqXBmtKIDfpznFPaC_E>~AFc;l zX{RU@nQndUpN;))4|VwanM}~9hqmw6zs~#2E9~sqP3K;7uhGkRaOe9SHX;x1rJda? zvgeVq6K_pQriuC*$8!oE8JExFf#l-6p%z&~bZC)DPb; z>C!G48L0EVk>6r9(54nX9P5->I!2RZETK>~{dPJ|19$bU`(|_*y5rl+vob z9~1vFvEcDW@&-MzV6SwSw_QSye_Zli>t{Zx zV;fR+qa!SR+P0o<$r8zTYKbvORIPe(d2`Q5C}+;WE&J}>Eisz2{mK*XjC!VfVr6{i zYQ#c?$>(g~J%vK@G*b)(8$qAeM5m!x@mSyq)eG#dKqQ;9UBFSK+5qsMbFRm z0=w;gdH3MZ<_l{?1UsI1N1kqaRF$4xCKx*3BWC;T&p+gxY)m=X^r&f@+gNXcbqsa0 zZso(Yq+=h4#y-D{jN4^eZJ%Jt7d$ulQmVW+-aI8Q&nr@FeS30Kx@pbU1dDZ4>fBJF z^^Nur_E>Tay)Vi92O}=$1_*-BxKV@gLh=Xzkr(;{Nu4 zl1~0W)olkP z_{FH4kP}J)J74wskG-44yID12v8get5@ZWLc)( zxw9!EBBJ}lIi8sEg&{Y(cXO7dP=ck8S)NO~;^^2|s`o&%JA0;2PhY=wn+DI@G{abI zyUx!)|LpbU&DPlPw*5PljNMMWx-HsJ2SElO4in_O0`o^_8SXo&` z2`Wh3-+yCWqMC2a{QUg%OSh2qIyyR3s(bC$1Z`aKskgVPir-q8%4^MixY5Uf^}h{rS>N-v*5-?F4Ddy7?GWyQW7b?$sL|wcXv_KlSzLU0fs5{WU#XdTK1F|Bs6{ z$-$H17gh`Dq7qW~UR*=AB6P@>yG%rwi>u(q4LL{MVxJ)!d>%7nF4MADadu*We{L|> z&?0!Ei5^*>W|%CB;~a6-P*X)v;q(T;fR{z+!o=d;-N%bmD!;{bVmJ5IlQKn+Df_gphF2!HeDjev@W-7uTq((8~#$V{*7@rttoKONtr zj)if5{qyoTHNkHmFN#%n29Agj6lzS>(?em}jDD(>J^A`h(Lh#l_qXRfUHv^>@B9_* zu=MWVo-VJk3LN4spYN5iog8eF^%-nETI}Ou5%A?6eIl!P_=$l0$%CszROOp9%+{j_ zB1u^~yt=)Sd-)p4+?RTy{#%Ai#$E|1oHmwsWhy`M9^k`y4tjxn)&Y+Mc4Gn8@Ld;u=!Fj)~q!N>Fd^ zL-{SbmF0#x>Ypy{wE?6@k}?BS*gpMzDGRmlJl@9@6lq6kuNduR$Xa)3!6YZ;zP zuZ|T<*3tIqOZ5F5pLr}_!U>R$_hIWi8M|iNqJ@;Qm|f;m!yUPwU*2*|4w*gW+IEgd z^XRbed{W?Wt++T@bcXX7s<(c0bdKBTN-vWhgP9Gj|$u&@W_ zg|75=9J2Bq5)yU69ezF0z0E2!pRO{b=0?3Yp{uZF`jYj^Ll(ptG*Z8cfz=!390-C& ziKrDYT?P#4bl^GAzy7+cy{lGFl$^M@Vt~XOKr_Eg*|g34r|nuh$JED%JJhgs#~jGn z)jPLrb$10fPgJbt?2f4>KsULM`b4$D`dOFvdEp@ovvKWx3EA9cWkLQy_25vd2d9MnE=|Fyx$-%Wmc_@Acqwx}MuJQ%VLU9H+W2;>k@SbnAp!|!>&=0>Yj}LSmF6XcxSd|7uiE2ElA0;S@62(*X zikfRzCbP%4y9si&@8nwIynfp z=T5wg?fWprMH<&0%R6~_&iDBR(e_I}?oBbxwj#|=j}V-TTJtBE{(Xry-xX}mLLUxa zwpvgd^t0z)f|Z1C`>fNS%I24hGJuJUQn@3iPMs3=`|ukJWUXc?zr|WCMg;gyrP@fz zda&bh#ZY%zre>IHDH_*F@S^=UcHeu}-eSF_)JkW>FaONPXZ@gEUW2W&S@h30Egp2> zL=h0)7Rr@yItd(G9bdnJFd?Sb+XLjRJ-}Y=zbXIlStPBnx%j-v=i->5Cj(im_fFYW z^*7`e8<=f%RMD6Fx4KgzrRz!)zr`OdbhTW(&D!nBl`4I=*Ndq6M3LJ>{}y_Fk*Di^ z`M&e#&$C)>V;5Tk4ozfRt|OL@NhJWLKKN z{*|G#U($pY=C4c?N*#TChv{N%*<9e#?l=AMVk-8fYx?|9GH1ST$IhMMfD$FbhMA+; zNoDyVSvaAo^^NE6?MsLctjPqyuEOa#;%c2;HhcPpi%YG#kkPSYf`m8@KhV>z1fvtB zUM}trtd81v=-|P%JnG-}fR*(%-;zJ|X4{CP`LfRi0c8W=mwPX)3jcBMg-U>U_j0Z2 zpNS@ON6T>eHgwiJ|1_^m>G)wgvm>8nL%ov;ww17F2W0(6KTX#fhFmdczuwE^@+~L0 z$+WNyB}Sgawzn?MKIV7h@m5lE!L#Gxn!&S`3N04v%crYkx_@6O9Y*);i=S~8`_R59 z89V`BdZ^7FY)Ld^;bZ1dn`vi&r)_ij(b?`u84t#<`}TQ`+#WkXl;LH2v-6x9zXfNa zAi}~}Jv9mRg_}-U;bA+b*6g!xPSJ_%e{*l&JbS8K##7?GHG4F{58K7a2n43qphCK7 z4C!5kiG%~Dp_AmtIxcWFvPZ|B1kH?k$W+cv4haD$qp*Ty^-rvWqab1C3FA)2l3C&|_Ihye)G0*IMmtiJ1JO1TryCK>|hIyfMVJ8ZncZ%uR zux-S4K`qmzZmfh}P&KxIGD@IZM~kT68)W}f%}ux>GfY+c{Iik(g)5hTP3g-ce873EGn#M^1ah$85x<`sSz`5vAtTx&^N`c8NJlY2S}0w1u*8ua~XS221xy{&SMO8R4t<4H5+b<>}u7 zVzb|Sw^-VuAIHcwsLSD|N*~~WqTSg>#+)4lj2fh)(m27c zYtWU%h{Sg7cv1zRwdt-5XF)XRqQmsua7+rXy}G^T!_#xN9Q28P%@9_kb>)eRB7CU1 z2qJ=M_KfZeLat$86xYJ9;Bjk!z5+ef(UGL5tWoX1LtvoI#n|62_IH(sqD!d~XuhuQ??G0_q5gVKBhO_fsPuiHHq?{I^9!pZ!TjW) ziFv0we64ST!_nWqS++)4pvA)TfN;>ar>s=5g&pydX6sPEws}r1(rg?|w>Kd~y85`E(Jg{D8%b=`#(Bk%pwGwkJq2j*L zRSAh_p8eqde6>=gVaVv!>sp~9@@}2#uHfDlXER%JY->)o7r2lIW z6C@M>56lChU3|U{FQY}?T{Tltcyv~&b4i&KpXAX?i9w^aX3%yt*aR7mAOAD}GU)S0 zf4hBy7ANR0oVe+sQQEVilJPhD+PIbrUuuFyunWx0K=sSrLFmEQ*ZCvqbJm(tK|~bI@KBI=2J=4v%@bX3x`p4xuO~YcIXjiIFht1%VGz|=0^@5yp-?Sp<4X)Q97+_Vb~W;I+9PSF0&8?FnDF3 zbnQ(gwPohbe0EI}H=mm+gKLo+Jk_D(1ZyfjIXO8W_K4a*MlP+Fkq|m0 z8Obm63SIbGQFaiU>T^FwjZ|NzEt|{*~(sa zCj<=Y<1*>aW+5RV&Dhbw*wA^~^Pz6LOtb0@v=+uQAm_|rEG^zM*}u9H4c2WHPZ|*d zPK_x#L{X57+GJ~lua=_C+#0vwHnFyfcd1rcOL68UE?`PZibvnOG0rM6O?6;m)`~9u z)o0ygTFz3O_gV+BbTTZ93+icLBl1>$AJ4bCl`lv*?w~x-2D@p!(1{1{#{#(~vamcFO_wk~n-3Mgx%bAI>H^#( z0@W$Myi!;+K=IjsHACAw6o`PJ^XxR|)Yeic70p2Q3=8^hkT9Uf-HuB`(t8M;g12T3 z%2FuDizi>HjcCJ7P?`&Aw>> z(b#$EFh^FxYHigm`_j8c`cKRM`t|>i7yDltxBH{(M2`nH%`)dC0%7tN>~*tLc}&x5 z6-OKSFW>Y}Tf_f`Pu?H5@)9h*s`LC-0z`|!-Xqv);nQZ1?X!=C!|(iuV4OyUsU=)g zV%U(T;5E!t0WU1C3ZrgLfzu!hIbSErgMC?IBE5$cpfWT8IW<&jBZvnqS@v4OB(@ro z4}2)$yP_FKK?G7Dyu~_HLtLDk+39l5Tsi4Kf4%CvPiRunyt|HQqsmiZn&tplin=3q z+4R5ugE!0i@Zoh^w{E46m}VTkeA*aCO3sA7d6RFazatpOT{!&OyP?xYLC5BFq9m(PzDEljrez;~1?4AIfs z6A>9n^yndo<1KQgcPHpmChyC*D6Ju--n|vSc5uj9#Zq)lPx!>CEp>v9JCu2>jav>a zEEZgNMN0$RU6_*_Qc*MJ59*e__~W9eps9ts&S2hKgGLa;MZ=8nIonu`0-7E-&fP(5 z53wkvOTIl*?!9JYQ+s7A@FG$fE=>=3|D(Z1Bok7`y-V&wUCP4670?O^vX4a$;cRa* zZ21_k4ki4vk;T8^T>jr!OaJgao9y000D2lMM>twgAp%9%51BhZjA*GvlLK?G~($2 zYmOk%Vm2^3Wnt@IS9Z6F5>}!8&uZ)N?b0Bb$RcD}KJf~Nbs-6pP7IE9=6_b3=JGA# z-Iw;R3E#U$SVZ@xb2Br@-x2{GoD^+N+ zA}?6g`wv6V*O5S1*Jw)sZ))y zhi|w%2&sZxz74}8P6N;TnAfa_c_L0L|xj*GLXh#0A_hL1X zc4~u<_u9u|>72I$Jz$TKlp+d79nwm2z40Pofbdu0T|zLn+V4*6`}NlpB)n4#XjKJG zf5D5xdV3%c5~tf5LimjC?+=GmIq;;R$i0X3GI}=BNEh|3Sm^`3_Ga-WlWPY$JR3CJ z;dSVt!Fe*^lJoof`=it4!@Ak&X|7%MzjR8w+)$IhS=inyjwEXacSE^I<~mn~Q5zxN zl>2Ub)>Y|gYlBY1xk(cQet}p>>_G;?kCNP(n}Gnck(j#-&_uUn3Gda|y2rukcp8b( z{?ynbllXtdk?!yD*FT@w|10;Ly2zXVwPf`l?mPd7+y=mz#ENh!1BnK>DSv9+x#c`D zh%ho~HE2f#zoQ+6&M>TPKE1fiYAI(chz9ikF%5sL`_8#F5ok9i|Iz&pwQ&bEkqjs( zl!Ts0plsOlGdUw=b4T8Q9#%9T>|OFHo!H$}DzP2T7baZ0rj4dFJcn+xTnnupr!IoSzx5GQ zVH3$Cp=N7B=7#uR-co7^?tse@ry+>f&p%>PFOdd~J3lV;&_i#}|EGq3&$!ONt@t0( zxIEyW6T6j+cuYbG`F+0OC=s{?8@SS>mO@7cPhvQdF8aYpPDQBJ2=9u9I@GZHdYTqlYyx~SPm<_!}m79HesJV`NUVFnv&Oc-x9 zSX69_5)gAmdPISpe4lsfMlYykw5fG)K64ft?9k!ESLQ-UUPmQSql;R9%MK|s%ZGEz zF%x9mmhIUxqQ#)Od2vw6w}`z$CNr*?TUl6G{O}gXyrAiLkiFqIVwpt2g>jx-0G%T- z`y24CX8;v#5=7+opoS2f#A7lU{(~nD)4FQafx$4_t5(`-)n;95tOh36xHfgwV4C*j@`*_8orOE*g3P}`!y zyYuU^7f79K5EQ#N>hM>=NnA^O9MJEC;-65m(>}EfxEKTI`QXHr=(*h(FWBY#s}!YO zZ1HFs^=gI@4EZaktY`_CXfj}@`GA81|}k45b7d*BqKTGxR8JVO1B7ZW-6r0 zWq53JgZCzoN)r@z|8g&ZP#udPR#mTo?=ccqA){=BSGhw{GHQ*8Y9)+!QwI)`s@SLJ zme-JpAAnda_GEEJ4U=XsGCeUBq0^A0kqWs>9OCK5*pLk*;qNHJVmcTFTZz`nMkD}425h_6jN5aBL)CjjDfy~?uVguYip68Fh!E;us z@B8m7d@INj)d+j;pC3&qk3xj3ek99cBN-RKfEcn)%Xy4$#DK`Elueb6RFR@0V)WwiU!_Woee)OGh;g=+##Au2hjH6R0gIuGoZdDq(I*0oK?ka0v$#h) znXIq{RyLLfPLbv7LD<0jG(%!5lCzPZQ(PQCLM2;5khhs&I?1WY(I!I@^YeXLGE)MS zR?M1yP`iWAW+8T5jBQASvM|x2haAfWmXNvq9GO`nnNH2cb zk4$zE)Bd`u_i1hI{fVjy*tB&Dr|0LKKcyuFNRWw7l1^f(tr|jspG>CFYbX`*;JsZ` zD1}B8UD2m2`?@i=8Hw$$f(;Hoi;qklT{D{^(+1%7E~5p>2(ntSLW}cYBf%qqjo7!N zMQ1)byqv;tT{Rg@#R0bu;>>l$A`XdHQKgZXi%d(pmM=^aK;C~_+5PI2EJow5YXtg` znq*;2rV@jfo`o9Nn?@vlMIU}&nSwz$Qmte#!a-vhr7S7(HCGuo8HBqo=V%~I(kQqk zeu%Jb0p~fGE~_T`l0Yg#Y+X#}*dq03&5t$IT-#}+=s!2qUKrcOVNa1zT>F-yOLsxL zYa|>D9sFC-Ur22z&*&YNGOL_DtNi8e)ox53M8Igss8=NuZ{z)qo5@fj`l>9MmH;j) z`HPY90Q5gevc|-!Mf{dqZ%dpIa>jD-at%r%L2U_lMRO0qu07~}irrp1|Q z=mCHB9v|t_(v1}rK`a(dhEXu8Bbe*h5JOHR{GRgKb}eEsl2Clr#@$;;?M@@#Bzw`8 zu`v?Urp@MV(PXqI%^DmCI$QY0=3OvQSJS4}i_6k_hS(hy`3|a>5 zBIQHzDU4=D5nG6)-CDSw<&bsKIr5xOe;p$W}rh!m1uYMG*uNt)ApuQ2;Ribnj2LxiT1;YF0gD_vbNQg z$e_vDhU^HeoM!dd!Vn`oaPa}PaX+U>^q*2T~|ApeL6|`ni mKRXer@Za8mzh8K>wJy;2t=k#w3~fxI=<670XZ`8;@BafZ8heod literal 0 HcmV?d00001 diff --git a/src/assets/__init__.py b/src/assets/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/aux/__init__.py b/src/assets/aux/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/aux/env.py b/src/assets/aux/env.py index 58a1809..801735d 100644 --- a/src/assets/aux/env.py +++ b/src/assets/aux/env.py @@ -1,6 +1,17 @@ -from dotenv import load_dotenv from os import environ -load_dotenv() +# Load environment variables from .env file only if not in Docker +# Docker containers should use environment variables passed by Docker Compose +if not environ.get('DOCKER_CONTAINER'): + try: + from dotenv import load_dotenv + load_dotenv() + print("[ENV] Loaded .env file for local development") + except ImportError: + # dotenv not available, skip loading + print("[ENV] dotenv not available, using system environment variables") + pass +else: + print("[ENV] Running in Docker container, using Docker environment variables") env = environ \ No newline at end of file diff --git a/src/assets/open_web_ui/pipeline_api.py b/src/assets/open_web_ui/pipeline_api.py index e2978e5..dbe6fa0 100644 --- a/src/assets/open_web_ui/pipeline_api.py +++ b/src/assets/open_web_ui/pipeline_api.py @@ -1,6 +1,7 @@ from typing import Optional, Callable, Awaitable import time import requests +import os from pydantic import BaseModel, Field @@ -15,7 +16,15 @@ class Valves(BaseModel): ) bearer_token: str = Field( default="", - description="Token Bearer opcional para autenticação na API.", + description="REQUIRED: JWT token from Django auth service (http://localhost:8001). Get token via POST /api/token/ after registration.", + ) + django_validate_url: str = Field( + default="http://django-auth:8001/internal/validate-token/", + description="Django endpoint for JWT validation (internal use).", + ) + internal_auth_token: str = Field( + default="", + description="Internal authentication token for backend-to-backend communication. Leave empty to use INTERNAL_AUTH_TOKEN environment variable.", ) emit_interval: float = Field( default=2.0, @@ -27,7 +36,7 @@ class Valves(BaseModel): ) max_file_size: int = Field( default=1048576, - description="Tamanho máximo (bytes) para arquivos recebidos — 1 MB por padrão.", + description="Tamanho máximo (bytes) para arquivos recebidos — 1 MB por padrão.", ) def __init__(self): @@ -36,6 +45,18 @@ def __init__(self): self.name = "FastAPI Pipe" self.valves = self.Valves() self.last_emit_time = 0.0 # controle de throttle dos status + + # Load internal auth token from environment if not set in valves + if not self.valves.internal_auth_token: + env_token = os.getenv("INTERNAL_AUTH_TOKEN", "") + if env_token: + self.valves.internal_auth_token = env_token + print(f"[PIPELINE] Loaded INTERNAL_AUTH_TOKEN from environment: {env_token[:20]}...") + else: + print("[PIPELINE] WARNING: INTERNAL_AUTH_TOKEN not found in environment variables") + print(f"[PIPELINE] Available environment variables: {[k for k in os.environ.keys() if 'TOKEN' in k or 'AUTH' in k]}") + else: + print(f"[PIPELINE] Using INTERNAL_AUTH_TOKEN from valves: {self.valves.internal_auth_token[:20]}...") async def _emit_status( self, @@ -63,6 +84,86 @@ async def _emit_status( ) self.last_emit_time = now + def _validate_jwt_format(self, jwt_token: str) -> bool: + """Validate JWT token format (should have 3 parts separated by dots)""" + if not isinstance(jwt_token, str): + return False + + parts = jwt_token.strip().split('.') + return len(parts) == 3 and all(part for part in parts) + + async def _validate_user_jwt(self, user_jwt: str, __event_emitter__: Callable[[dict], Awaitable[None]]) -> tuple[bool, Optional[dict]]: + """ + Validate user JWT with Django auth service + + Returns: + tuple[bool, Optional[dict]]: (is_valid, user_info) + """ + # Check if internal auth token is configured + if not self.valves.internal_auth_token or self.valves.internal_auth_token.strip() == "": + # Try to reload from environment as a fallback + env_token = os.getenv("INTERNAL_AUTH_TOKEN", "") + if env_token and env_token.strip(): + self.valves.internal_auth_token = env_token.strip() + print(f"[PIPELINE] Reloaded INTERNAL_AUTH_TOKEN from environment: {env_token[:20]}...") + else: + error_msg = f"Internal auth token not configured. Environment check: INTERNAL_AUTH_TOKEN={'present' if env_token else 'missing'}" + await self._emit_status(__event_emitter__, "error", error_msg, True) + print(f"[PIPELINE] ERROR: {error_msg}") + print(f"[PIPELINE] Available env vars: {[k for k in os.environ.keys() if 'TOKEN' in k or 'AUTH' in k]}") + return False, None + + # Validate JWT format before sending to Django + if not self._validate_jwt_format(user_jwt): + await self._emit_status(__event_emitter__, "error", "Invalid JWT format", True) + return False, None + + headers = { + "Authorization": f"Bearer {self.valves.internal_auth_token}", + "Content-Type": "application/json" + } + + payload = {"jwt": user_jwt} + + try: + await self._emit_status(__event_emitter__, "info", "Validating authentication...", False) + response = requests.post( + self.valves.django_validate_url, + json=payload, + headers=headers, + timeout=15, # Increased timeout for better reliability + ) + + if response.status_code == 200: + try: + user_info = response.json() + username = user_info.get('username', 'unknown') + await self._emit_status(__event_emitter__, "info", f"Authentication validated for {username}", False) + return True, user_info + except ValueError: + await self._emit_status(__event_emitter__, "error", "Invalid response from auth service", True) + return False, None + else: + error_msg = "Authentication failed" + try: + error_detail = response.json().get("detail", "Invalid token") + error_msg = f"Authentication failed: {error_detail}" + except: + error_msg = f"Authentication failed (HTTP {response.status_code})" + + await self._emit_status(__event_emitter__, "error", error_msg, True) + return False, None + + except requests.Timeout: + await self._emit_status(__event_emitter__, "error", "Authentication service timeout", True) + return False, None + except requests.ConnectionError: + await self._emit_status(__event_emitter__, "error", "Cannot connect to authentication service", True) + return False, None + except requests.RequestException as exc: + await self._emit_status(__event_emitter__, "error", f"Auth validation error: {exc}", True) + return False, None + async def pipe( self, body: dict, @@ -73,6 +174,40 @@ async def pipe( await self._emit_status(__event_emitter__, "info", "Processando entrada...", False) + # Extract user JWT from OpenWebUI context or valves + user_jwt = None + jwt_source = "unknown" + + # First try to get JWT from OpenWebUI user context (preferred method) + if __user__ and isinstance(__user__, dict): + # Try multiple possible field names for JWT token + for field_name in ["token", "jwt", "access_token", "bearer_token"]: + token = __user__.get(field_name) + if token and isinstance(token, str) and token.strip(): + user_jwt = token.strip() + jwt_source = f"user_context.{field_name}" + break + + # Fallback to valves configuration + if not user_jwt and self.valves.bearer_token: + token = self.valves.bearer_token.strip() + if token: + user_jwt = token + jwt_source = "valves.bearer_token" + + # Check if we have a JWT token + if not user_jwt: + await self._emit_status(__event_emitter__, "error", "Authentication required", True) + return {"error": "Authentication required. Please log in at Django Auth (http://localhost:8001) and provide the JWT token in the pipeline settings."} + + # Log JWT source for debugging + print(f"[PIPELINE] Using JWT from: {jwt_source}") + + # Validate the user JWT with Django + is_valid, user_info = await self._validate_user_jwt(user_jwt, __event_emitter__) + if not is_valid: + return {"error": "Authentication failed. Please check your JWT token and try again."} + messages = body.get("messages", []) if not messages: await self._emit_status(__event_emitter__, "error", "Nenhuma mensagem encontrada", True) @@ -81,9 +216,11 @@ async def pipe( last_content = messages[-1]["content"] question = self._extract_text(last_content) - headers = {"Content-Type": "application/json"} - if self.valves.bearer_token: - headers["Authorization"] = f"Bearer {self.valves.bearer_token}" + # Use the user's JWT for FastAPI call (FastAPI will validate it again with Django) + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {user_jwt}" + } payload = {"question": question} diff --git a/src/assets/pattern/__init__.py b/src/assets/pattern/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/django_auth/__init__.py b/src/django_auth/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/django_auth/apps/__init__.py b/src/django_auth/apps/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/django_auth/apps/auth_app/__init__.py b/src/django_auth/apps/auth_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/django_auth/apps/auth_app/admin.py b/src/django_auth/apps/auth_app/admin.py new file mode 100644 index 0000000..a73ac2e --- /dev/null +++ b/src/django_auth/apps/auth_app/admin.py @@ -0,0 +1,26 @@ +from django.contrib import admin +from .models import Repository, AccessToken + + +@admin.register(Repository) +class RepositoryAdmin(admin.ModelAdmin): + list_display = ('name', 'owner', 'url', 'created_at') + list_filter = ('created_at', 'owner') + search_fields = ('name', 'url', 'owner__username', 'owner__email') + readonly_fields = ('created_at', 'updated_at') + + +@admin.register(AccessToken) +class AccessTokenAdmin(admin.ModelAdmin): + list_display = ('owner', 'service', 'masked_token', 'created_at', 'updated_at') + list_filter = ('service', 'created_at', 'owner') + search_fields = ('owner__username', 'owner__email', 'service') + readonly_fields = ('encrypted_token', 'last_four', 'created_at', 'updated_at') + + def masked_token(self, obj): + return obj.get_masked_token() + masked_token.short_description = 'Token (Masked)' + + def has_change_permission(self, request, obj=None): + # Prevent editing encrypted tokens through admin + return False \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/apps.py b/src/django_auth/apps/auth_app/apps.py new file mode 100644 index 0000000..f29133a --- /dev/null +++ b/src/django_auth/apps/auth_app/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AuthAppConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'django_auth.apps.auth_app' \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/forms.py b/src/django_auth/apps/auth_app/forms.py new file mode 100644 index 0000000..c878c91 --- /dev/null +++ b/src/django_auth/apps/auth_app/forms.py @@ -0,0 +1,55 @@ +from django import forms +from django.contrib.auth.models import User +from django.contrib.auth.forms import UserCreationForm +from .models import AccessToken + + +class UserRegistrationForm(UserCreationForm): + email = forms.EmailField(required=True) + first_name = forms.CharField(max_length=30, required=False) + last_name = forms.CharField(max_length=30, required=False) + + class Meta: + model = User + fields = ('email', 'first_name', 'last_name', 'password1', 'password2') + + def clean_email(self): + email = self.cleaned_data['email'] + if User.objects.filter(email=email).exists(): + raise forms.ValidationError("User with this email already exists") + return email + + def save(self, commit=True): + user = super().save(commit=False) + user.email = self.cleaned_data['email'] + user.username = self.cleaned_data['email'] # Use email as username + user.first_name = self.cleaned_data['first_name'] + user.last_name = self.cleaned_data['last_name'] + if commit: + user.save() + return user + + +class TokenForm(forms.ModelForm): + token = forms.CharField( + widget=forms.PasswordInput(attrs={ + 'class': 'form-control', + 'placeholder': 'Leave blank to generate JWT token automatically' + }), + help_text='A JWT token will be generated automatically for API authentication', + required=False + ) + + class Meta: + model = AccessToken + fields = ['service', 'token'] + widgets = { + 'service': forms.Select(attrs={'class': 'form-control'}), + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if self.instance and self.instance.pk: + # For editing, provide regeneration option + self.fields['token'].help_text = 'Leave blank to keep current token, or enter any value to regenerate a new JWT token' + self.fields['token'].widget.attrs['placeholder'] = 'Enter any value to regenerate token' \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/migrations/0001_initial.py b/src/django_auth/apps/auth_app/migrations/0001_initial.py new file mode 100644 index 0000000..3e75b1e --- /dev/null +++ b/src/django_auth/apps/auth_app/migrations/0001_initial.py @@ -0,0 +1,89 @@ +# Generated by Django 4.2.7 on 2025-11-30 17:42 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="Repository", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ("url", models.URLField()), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "owner", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="repositories", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "ordering": ["-created_at"], + "unique_together": {("owner", "name")}, + }, + ), + migrations.CreateModel( + name="AccessToken", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "service", + models.CharField( + choices=[ + ("github", "GitHub"), + ("gitlab", "GitLab"), + ("bitbucket", "Bitbucket"), + ("other", "Other"), + ], + max_length=50, + ), + ), + ("encrypted_token", models.BinaryField()), + ("last_four", models.CharField(max_length=4)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "owner", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="access_tokens", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "ordering": ["-updated_at"], + "unique_together": {("owner", "service")}, + }, + ), + ] diff --git a/src/django_auth/apps/auth_app/migrations/0002_remove_unique_constraint.py b/src/django_auth/apps/auth_app/migrations/0002_remove_unique_constraint.py new file mode 100644 index 0000000..53ced2b --- /dev/null +++ b/src/django_auth/apps/auth_app/migrations/0002_remove_unique_constraint.py @@ -0,0 +1,16 @@ +# Generated migration to remove unique constraint on AccessToken +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth_app', '0001_initial'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='accesstoken', + unique_together=set(), + ), + ] \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/migrations/__init__.py b/src/django_auth/apps/auth_app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/django_auth/apps/auth_app/models.py b/src/django_auth/apps/auth_app/models.py new file mode 100644 index 0000000..cea35c5 --- /dev/null +++ b/src/django_auth/apps/auth_app/models.py @@ -0,0 +1,66 @@ +from django.db import models +from django.contrib.auth.models import User +from cryptography.fernet import Fernet +from django.conf import settings + + +class Repository(models.Model): + """Minimal repository model for user ownership""" + name = models.CharField(max_length=255) + url = models.URLField() + owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='repositories') + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + unique_together = ['owner', 'name'] + ordering = ['-created_at'] + + def __str__(self): + return f"{self.owner.username}/{self.name}" + + +class AccessToken(models.Model): + """Encrypted token storage for various services""" + SERVICE_CHOICES = [ + ('github', 'GitHub'), + ('gitlab', 'GitLab'), + ('bitbucket', 'Bitbucket'), + ('other', 'Other'), + ] + + owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='access_tokens') + service = models.CharField(max_length=50, choices=SERVICE_CHOICES) + encrypted_token = models.BinaryField() # Stores encrypted token + last_four = models.CharField(max_length=4) # Last 4 chars for display + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + ordering = ['-updated_at'] + + def set_token(self, plain_token): + """Encrypt and store token, save last 4 chars for display""" + if not plain_token: + raise ValueError("Token cannot be empty") + + fernet = Fernet(settings.FERNET_KEY.encode()) + self.encrypted_token = fernet.encrypt(plain_token.encode()) + self.last_four = plain_token[-4:] if len(plain_token) >= 4 else plain_token + + def get_token(self): + """Decrypt and return the full token - use sparingly""" + if not self.encrypted_token: + return None + + fernet = Fernet(settings.FERNET_KEY.encode()) + return fernet.decrypt(self.encrypted_token).decode() + + def get_masked_token(self): + """Return masked token for display""" + if not self.last_four: + return "****" + return f"****{self.last_four}" + + def __str__(self): + return f"{self.owner.username} - {self.service} (****{self.last_four})" \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/serializers.py b/src/django_auth/apps/auth_app/serializers.py new file mode 100644 index 0000000..10d27b9 --- /dev/null +++ b/src/django_auth/apps/auth_app/serializers.py @@ -0,0 +1,102 @@ +from rest_framework import serializers +from django.contrib.auth.models import User +from django.contrib.auth.password_validation import validate_password +from .models import Repository, AccessToken + + +class UserRegistrationSerializer(serializers.ModelSerializer): + password = serializers.CharField(write_only=True, validators=[validate_password]) + password_confirm = serializers.CharField(write_only=True) + + class Meta: + model = User + fields = ('email', 'password', 'password_confirm', 'first_name', 'last_name') + + def validate(self, attrs): + if attrs['password'] != attrs['password_confirm']: + raise serializers.ValidationError("Passwords don't match") + return attrs + + def validate_email(self, value): + if User.objects.filter(email=value).exists(): + raise serializers.ValidationError("User with this email already exists") + return value + + def create(self, validated_data): + validated_data.pop('password_confirm') + user = User.objects.create_user( + username=validated_data['email'], # Use email as username + email=validated_data['email'], + password=validated_data['password'], + first_name=validated_data.get('first_name', ''), + last_name=validated_data.get('last_name', '') + ) + return user + + +class UserProfileSerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = ('id', 'email', 'first_name', 'last_name', 'date_joined') + read_only_fields = ('id', 'date_joined') + + +class RepositorySerializer(serializers.ModelSerializer): + owner = serializers.StringRelatedField(read_only=True) + + class Meta: + model = Repository + fields = ('id', 'name', 'url', 'owner', 'created_at', 'updated_at') + read_only_fields = ('id', 'owner', 'created_at', 'updated_at') + + def create(self, validated_data): + validated_data['owner'] = self.context['request'].user + return super().create(validated_data) + + +class AccessTokenSerializer(serializers.ModelSerializer): + token = serializers.CharField(write_only=True, help_text="The actual token (will be encrypted)") + masked_token = serializers.SerializerMethodField(read_only=True) + owner = serializers.StringRelatedField(read_only=True) + + class Meta: + model = AccessToken + fields = ('id', 'service', 'token', 'masked_token', 'owner', 'created_at', 'updated_at') + read_only_fields = ('id', 'owner', 'masked_token', 'created_at', 'updated_at') + + def get_masked_token(self, obj): + return obj.get_masked_token() + + def create(self, validated_data): + token = validated_data.pop('token') + validated_data['owner'] = self.context['request'].user + + # Always create new token (no unique constraint anymore) + access_token = AccessToken.objects.create(**validated_data) + access_token.set_token(token) + access_token.save() + return access_token + + def update(self, instance, validated_data): + token = validated_data.pop('token', None) + if token: + instance.set_token(token) + + for attr, value in validated_data.items(): + setattr(instance, attr, value) + + instance.save() + return instance + + +class AccessTokenMetadataSerializer(serializers.ModelSerializer): + """Serializer for returning only metadata without token field""" + masked_token = serializers.SerializerMethodField() + owner = serializers.StringRelatedField(read_only=True) + + class Meta: + model = AccessToken + fields = ('id', 'service', 'masked_token', 'owner', 'created_at', 'updated_at') + + def get_masked_token(self, obj): + return obj.get_masked_token() \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/tests.py b/src/django_auth/apps/auth_app/tests.py new file mode 100644 index 0000000..afd534f --- /dev/null +++ b/src/django_auth/apps/auth_app/tests.py @@ -0,0 +1,293 @@ +from django.test import TestCase, Client +from django.contrib.auth.models import User +from django.urls import reverse +from django.conf import settings +from rest_framework.test import APITestCase +from rest_framework import status +from .models import Repository, AccessToken +from .ui_views import generate_jwt_token +from cryptography.fernet import Fernet +import json +import jwt + + +class AuthModelTests(TestCase): + def setUp(self): + self.user = User.objects.create_user( + username='test@example.com', + email='test@example.com', + password='testpass123' + ) + + def test_repository_creation(self): + repo = Repository.objects.create( + name='test-repo', + url='https://github.com/user/test-repo', + owner=self.user + ) + self.assertEqual(str(repo), 'test@example.com/test-repo') + + def test_access_token_encryption(self): + token = AccessToken.objects.create( + owner=self.user, + service='github' + ) + plain_token = 'ghp_1234567890abcdef' + token.set_token(plain_token) + token.save() + + # Token should be encrypted in database + self.assertNotEqual(token.encrypted_token, plain_token.encode()) + # Should be able to decrypt + self.assertEqual(token.get_token(), plain_token) + # Should show masked version + self.assertEqual(token.get_masked_token(), '****cdef') + + def test_access_token_unique_per_service(self): + AccessToken.objects.create(owner=self.user, service='github') + # Should not be able to create another github token for same user + with self.assertRaises(Exception): + AccessToken.objects.create(owner=self.user, service='github') + + +class AuthAPITests(APITestCase): + def setUp(self): + self.user = User.objects.create_user( + username='test@example.com', + email='test@example.com', + password='testpass123' + ) + + def test_user_registration(self): + url = reverse('auth_app:register') + data = { + 'email': 'newuser@example.com', + 'password': 'newpass123', + 'password_confirm': 'newpass123', + 'first_name': 'New', + 'last_name': 'User' + } + response = self.client.post(url, data) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertTrue(User.objects.filter(email='newuser@example.com').exists()) + + def test_jwt_token_obtain(self): + url = reverse('auth_app:token_obtain_pair') + data = { + 'username': 'test@example.com', + 'password': 'testpass123' + } + response = self.client.post(url, data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIn('access', response.data) + self.assertIn('refresh', response.data) + + def test_repository_acl(self): + # Create another user + other_user = User.objects.create_user( + username='other@example.com', + email='other@example.com', + password='otherpass123' + ) + + # Create repository for other user + other_repo = Repository.objects.create( + name='other-repo', + url='https://github.com/other/repo', + owner=other_user + ) + + # Login as first user + self.client.force_authenticate(user=self.user) + + # Should not see other user's repository + url = reverse('auth_app:repository_list_create') + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 0) + + # Should not be able to access other user's repository directly + url = reverse('auth_app:repository_detail', kwargs={'pk': other_repo.pk}) + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + def test_token_acl(self): + # Create another user with token + other_user = User.objects.create_user( + username='other@example.com', + email='other@example.com', + password='otherpass123' + ) + other_token = AccessToken.objects.create( + owner=other_user, + service='github' + ) + other_token.set_token('ghp_other_token') + other_token.save() + + # Login as first user + self.client.force_authenticate(user=self.user) + + # Should not see other user's tokens + url = reverse('auth_app:token_list_create') + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 0) + + # Should not be able to access other user's token directly + url = reverse('auth_app:token_detail', kwargs={'pk': other_token.pk}) + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + def test_token_creation_and_masking(self): + self.client.force_authenticate(user=self.user) + + url = reverse('auth_app:token_list_create') + data = { + 'service': 'github', + 'token': 'ghp_1234567890abcdef' + } + response = self.client.post(url, data) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # Check that token is masked in response + self.assertEqual(response.data['masked_token'], '****cdef') + self.assertNotIn('token', response.data) # Full token should not be returned + + # Verify token is encrypted in database + token = AccessToken.objects.get(pk=response.data['id']) + self.assertEqual(token.get_token(), 'ghp_1234567890abcdef') + + +class AuthUITests(TestCase): + def setUp(self): + self.client = Client() + self.user = User.objects.create_user( + username='test@example.com', + email='test@example.com', + password='testpass123' + ) + + def test_login_required_for_token_pages(self): + # Should redirect to login + response = self.client.get('/tokens/') + self.assertEqual(response.status_code, 302) + self.assertIn('/login/', response.url) + + def test_token_list_view(self): + self.client.login(username='test@example.com', password='testpass123') + + # Create a token + token = AccessToken.objects.create(owner=self.user, service='github') + token.set_token('ghp_test_token') + token.save() + + response = self.client.get('/tokens/') + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'GitHub') + self.assertContains(response, '****') # Masked token + + def test_token_creation_form(self): + self.client.login(username='test@example.com', password='testpass123') + + # GET form + response = self.client.get('/tokens/new/') + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'Add New Token') + + # POST form + response = self.client.post('/tokens/new/', { + 'service': 'github', + 'token': 'ghp_new_test_token' + }) + self.assertEqual(response.status_code, 302) # Redirect after success + + # Verify token was created + self.assertTrue(AccessToken.objects.filter(owner=self.user, service='github').exists()) + + def test_registration_form(self): + response = self.client.post('/register/', { + 'email': 'newuser@example.com', + 'first_name': 'New', + 'last_name': 'User', + 'password1': 'complexpass123', + 'password2': 'complexpass123' + }) + self.assertEqual(response.status_code, 302) # Redirect after success + self.assertTrue(User.objects.filter(email='newuser@example.com').exists()) + + +class JWTTokenTests(TestCase): + def setUp(self): + self.user = User.objects.create_user( + username='test@example.com', + email='test@example.com', + password='testpass123' + ) + + def test_generate_jwt_token_returns_string_and_contains_user_id(self): + """Unit: test_generate_jwt_token_returns_string_and_contains_user_id""" + token = generate_jwt_token(self.user) + + # Should return a string + self.assertIsInstance(token, str) + + # Should be decodable with our secret + decoded = jwt.decode(token, settings.JWT_SECRET_KEY, algorithms=["HS256"]) + + # Should contain user_id + self.assertEqual(decoded['user_id'], self.user.id) + self.assertEqual(decoded['username'], self.user.get_username()) + self.assertIn('iat', decoded) + self.assertIn('exp', decoded) + + def test_token_creation_flow_one_time_display(self): + """Integration: test_token_creation_flow_one_time_display""" + self.client.login(username='test@example.com', password='testpass123') + + # POST to create token + response = self.client.post('/tokens/new/', { + 'service': 'github', + }) + + # Should redirect to created page + self.assertEqual(response.status_code, 302) + token_id = AccessToken.objects.get(owner=self.user, service='github').pk + self.assertIn(f'/tokens/{token_id}/created/', response.url) + + # GET the created page - should show token + response = self.client.get(f'/tokens/{token_id}/created/') + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'copy it now') + self.assertContains(response, 'eyJ') # JWT tokens start with eyJ + + # GET the same page again - should redirect with error + response = self.client.get(f'/tokens/{token_id}/created/') + self.assertEqual(response.status_code, 302) + self.assertIn('/tokens/', response.url) + + def test_encrypted_token_saved(self): + """DB: test_encrypted_token_saved""" + self.client.login(username='test@example.com', password='testpass123') + + # Create token via UI + response = self.client.post('/tokens/new/', { + 'service': 'github', + }) + + # Check database record + token = AccessToken.objects.get(owner=self.user, service='github') + + # Should have encrypted_token + self.assertIsNotNone(token.encrypted_token) + + # Decrypt and verify it's a valid JWT + fernet = Fernet(settings.FERNET_KEY.encode()) + decrypted_token = fernet.decrypt(token.encrypted_token).decode() + + # Should be decodable JWT + decoded = jwt.decode(decrypted_token, settings.JWT_SECRET_KEY, algorithms=["HS256"]) + self.assertEqual(decoded['user_id'], self.user.id) + + # Last four should match + self.assertEqual(token.last_four, decrypted_token[-4:]) \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/ui_urls.py b/src/django_auth/apps/auth_app/ui_urls.py new file mode 100644 index 0000000..7f94060 --- /dev/null +++ b/src/django_auth/apps/auth_app/ui_urls.py @@ -0,0 +1,20 @@ +from django.urls import path +from django.contrib.auth import views as auth_views +from . import ui_views + +urlpatterns = [ + # Authentication UI + path('login/', auth_views.LoginView.as_view(template_name='auth_app/login.html'), name='login'), + path('logout/', auth_views.LogoutView.as_view(), name='logout'), + path('register/', ui_views.register_view, name='register'), + + # Token management UI + path('tokens/', ui_views.token_list_view, name='token_list'), + path('tokens/new/', ui_views.token_create_view, name='token_create'), + path('tokens//edit/', ui_views.token_edit_view, name='token_edit'), + path('tokens//delete/', ui_views.token_delete_view, name='token_delete'), + path('tokens//created/', ui_views.token_created_view, name='token_created'), + + # Redirect root to tokens + path('', ui_views.token_list_view, name='home'), +] \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/ui_views.py b/src/django_auth/apps/auth_app/ui_views.py new file mode 100644 index 0000000..64f71ee --- /dev/null +++ b/src/django_auth/apps/auth_app/ui_views.py @@ -0,0 +1,155 @@ +from django.shortcuts import render, redirect, get_object_or_404 +from django.contrib.auth.decorators import login_required +from django.contrib.auth import login +from django.contrib import messages +from django.views.decorators.http import require_http_methods +from django.views.decorators.csrf import csrf_protect +from django.conf import settings +from cryptography.fernet import Fernet +import jwt +from datetime import datetime, timedelta +from .models import AccessToken +from .forms import TokenForm, UserRegistrationForm + + +def generate_jwt_token(user, exp_hours: int = 2) -> str: + from rest_framework_simplejwt.tokens import RefreshToken + + # Use SimpleJWT to generate a token exactly like the standard API does + refresh = RefreshToken.for_user(user) + access_token = refresh.access_token + + # DO NOT modify the token - let SimpleJWT handle everything + return str(access_token) + + +def register_view(request): + if request.method == 'POST': + form = UserRegistrationForm(request.POST) + if form.is_valid(): + user = form.save() + login(request, user) + messages.success(request, 'Registration successful!') + return redirect('token_list') + else: + form = UserRegistrationForm() + return render(request, 'auth_app/register.html', {'form': form}) + + +@login_required +def token_list_view(request): + tokens = AccessToken.objects.filter(owner=request.user) + return render(request, 'auth_app/token_list.html', {'tokens': tokens}) + + +@login_required +@csrf_protect +def token_create_view(request): + if request.method == 'POST': + form = TokenForm(request.POST) + if form.is_valid(): + # Generate JWT token for the user + raw_jwt = generate_jwt_token(request.user) + + # Create and save the AccessToken with encrypted JWT + token = form.save(commit=False) + token.owner = request.user + + # Encrypt and store the JWT token + fernet = Fernet(settings.FERNET_KEY.encode()) + token.encrypted_token = fernet.encrypt(raw_jwt.encode()) + token.last_four = raw_jwt[-4:] + token.save() + + # Store one-time display info in session + request.session["show_token_id"] = token.pk + request.session["show_token_value"] = raw_jwt + + messages.success(request, f'{token.service} token created successfully!') + return redirect('token_created', pk=token.pk) + else: + form = TokenForm() + return render(request, 'auth_app/token_form.html', { + 'form': form, + 'title': 'Add New Token' + }) + + +@login_required +@csrf_protect +def token_edit_view(request, pk): + token = get_object_or_404(AccessToken, pk=pk, owner=request.user) + + if request.method == 'POST': + form = TokenForm(request.POST, instance=token) + if form.is_valid(): + # Check if user wants to regenerate the token + regenerate_token = form.cleaned_data.get('token') + + if regenerate_token: # User provided new token input (regenerate) + # Generate new JWT token + raw_jwt = generate_jwt_token(request.user) + + # Encrypt and store the new JWT token + fernet = Fernet(settings.FERNET_KEY.encode()) + token.encrypted_token = fernet.encrypt(raw_jwt.encode()) + token.last_four = raw_jwt[-4:] + token.save() + + # Store one-time display info in session + request.session["show_token_id"] = token.pk + request.session["show_token_value"] = raw_jwt + + messages.success(request, f'{token.service} token regenerated successfully!') + return redirect('token_created', pk=token.pk) + else: + # Just update service type without regenerating token + form.save() + messages.success(request, f'{token.service} token updated successfully!') + return redirect('token_list') + else: + form = TokenForm(instance=token) + + return render(request, 'auth_app/token_form.html', { + 'form': form, + 'title': f'Edit {token.service} Token', + 'token': token + }) + + +@login_required +@require_http_methods(["POST"]) +@csrf_protect +def token_delete_view(request, pk): + token = get_object_or_404(AccessToken, pk=pk, owner=request.user) + service = token.service + token.delete() + messages.success(request, f'{service} token deleted successfully!') + return redirect('token_list') + + +@login_required +def token_created_view(request, pk): + """ + Display the full JWT token exactly once after creation. + Uses session-based security to prevent repeat access. + """ + token = get_object_or_404(AccessToken, pk=pk, owner=request.user) + + # Check if this token was just created (stored in session) + show_token_id = request.session.get("show_token_id") + jwt_token = request.session.get("show_token_value") + + if not jwt_token or show_token_id != pk: + # Token not in session or wrong token - redirect with error + messages.error(request, 'Token display is only available immediately after creation.') + return redirect('token_list') + + # Remove from session to prevent repeat access + request.session.pop("show_token_id", None) + request.session.pop("show_token_value", None) + + return render(request, 'auth_app/token_created.html', { + 'token': token, + 'jwt_token': jwt_token, + }) \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/urls.py b/src/django_auth/apps/auth_app/urls.py new file mode 100644 index 0000000..bcc063c --- /dev/null +++ b/src/django_auth/apps/auth_app/urls.py @@ -0,0 +1,23 @@ +from django.urls import path +from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView +from . import views + +app_name = 'auth_app' + +urlpatterns = [ + # Authentication endpoints + path('register/', views.UserRegistrationView.as_view(), name='register'), + path('login/', views.login_view, name='login'), + path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), + path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), + path('me/', views.UserProfileView.as_view(), name='user_profile'), + + # Repository endpoints + path('repositories/', views.RepositoryListCreateView.as_view(), name='repository_list_create'), + path('repositories//', views.RepositoryDetailView.as_view(), name='repository_detail'), + + # Token endpoints + path('tokens/', views.AccessTokenListCreateView.as_view(), name='token_list_create'), + path('tokens//', views.AccessTokenDetailView.as_view(), name='token_detail'), + path('tokens/current/', views.current_tokens_view, name='current_tokens'), +] \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/urls_internal.py b/src/django_auth/apps/auth_app/urls_internal.py new file mode 100644 index 0000000..adabf69 --- /dev/null +++ b/src/django_auth/apps/auth_app/urls_internal.py @@ -0,0 +1,6 @@ +from django.urls import path +from .views_internal import validate_token_for_backend + +urlpatterns = [ + path('validate-token/', validate_token_for_backend, name='validate-token-internal'), +] \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/views.py b/src/django_auth/apps/auth_app/views.py new file mode 100644 index 0000000..e0fe7ff --- /dev/null +++ b/src/django_auth/apps/auth_app/views.py @@ -0,0 +1,126 @@ +from rest_framework import generics, status, permissions +from rest_framework.decorators import api_view, permission_classes +from rest_framework.response import Response +from rest_framework_simplejwt.views import TokenObtainPairView +from rest_framework_simplejwt.tokens import RefreshToken +from django.contrib.auth import authenticate +from django.contrib.auth.models import User +from .models import Repository, AccessToken +from .serializers import ( + UserRegistrationSerializer, + UserProfileSerializer, + RepositorySerializer, + AccessTokenSerializer, + AccessTokenMetadataSerializer +) + + +class UserRegistrationView(generics.CreateAPIView): + queryset = User.objects.all() + serializer_class = UserRegistrationSerializer + permission_classes = [permissions.AllowAny] + + +class UserProfileView(generics.RetrieveUpdateAPIView): + serializer_class = UserProfileSerializer + permission_classes = [permissions.IsAuthenticated] + + def get_object(self): + return self.request.user + + +class RepositoryListCreateView(generics.ListCreateAPIView): + serializer_class = RepositorySerializer + permission_classes = [permissions.IsAuthenticated] + + def get_queryset(self): + return Repository.objects.filter(owner=self.request.user) + + +class RepositoryDetailView(generics.RetrieveUpdateDestroyAPIView): + serializer_class = RepositorySerializer + permission_classes = [permissions.IsAuthenticated] + + def get_queryset(self): + return Repository.objects.filter(owner=self.request.user) + + +class AccessTokenListCreateView(generics.ListCreateAPIView): + serializer_class = AccessTokenSerializer + permission_classes = [permissions.IsAuthenticated] + + def get_queryset(self): + return AccessToken.objects.filter(owner=self.request.user) + + def list(self, request, *args, **kwargs): + """Override to use metadata serializer for listing""" + queryset = self.get_queryset() + serializer = AccessTokenMetadataSerializer(queryset, many=True) + return Response(serializer.data) + + +class AccessTokenDetailView(generics.RetrieveUpdateDestroyAPIView): + serializer_class = AccessTokenSerializer + permission_classes = [permissions.IsAuthenticated] + + def get_queryset(self): + return AccessToken.objects.filter(owner=self.request.user) + + def retrieve(self, request, *args, **kwargs): + """Override to use metadata serializer for retrieval""" + instance = self.get_object() + serializer = AccessTokenMetadataSerializer(instance) + return Response(serializer.data) + + +@api_view(['POST']) +@permission_classes([permissions.AllowAny]) +def login_view(request): + """Login endpoint that returns JWT token""" + username = request.data.get('username') + password = request.data.get('password') + + if not username or not password: + return Response( + {'error': 'Username and password required'}, + status=status.HTTP_400_BAD_REQUEST + ) + + user = authenticate(username=username, password=password) + if user is None: + return Response( + {'error': 'Invalid credentials'}, + status=status.HTTP_401_UNAUTHORIZED + ) + + # Generate JWT token + refresh = RefreshToken.for_user(user) + access_token = str(refresh.access_token) + + return Response({ + 'token': access_token, + 'user_id': user.id, + 'username': user.username, + 'email': user.email + }, status=status.HTTP_200_OK) + + +@api_view(["GET"]) +@permission_classes([permissions.IsAuthenticated]) +def me(request): + """Return authenticated user info""" + user = request.user + return Response({ + "id": user.id, + "username": user.get_username(), + "email": getattr(user, "email", "") + }) + + +@api_view(['GET']) +@permission_classes([permissions.IsAuthenticated]) +def current_tokens_view(request): + """Return currently active token metadata per service""" + tokens = AccessToken.objects.filter(owner=request.user) + serializer = AccessTokenMetadataSerializer(tokens, many=True) + return Response(serializer.data) \ No newline at end of file diff --git a/src/django_auth/apps/auth_app/views_internal.py b/src/django_auth/apps/auth_app/views_internal.py new file mode 100644 index 0000000..1a2c389 --- /dev/null +++ b/src/django_auth/apps/auth_app/views_internal.py @@ -0,0 +1,110 @@ +import os +import hmac +import jwt +from django.conf import settings +from django.contrib.auth import get_user_model +from rest_framework.decorators import api_view, permission_classes +from rest_framework.permissions import AllowAny +from rest_framework.response import Response +from rest_framework import status +from .models import AccessToken + +User = get_user_model() + +from rest_framework.decorators import authentication_classes + +@api_view(["POST"]) +@authentication_classes([]) # Disable all authentication for this view +@permission_classes([AllowAny]) +def validate_token_for_backend(request): + """ + Internal endpoint to validate JWT tokens for backend services. + + Expects: + - Authorization: Bearer + - JSON body: {"jwt": ""} + + Returns: + - 200: Valid JWT with user info + - 400: Missing JWT in request body + - 401: Invalid JWT or missing internal auth + - 403: Invalid internal auth token + """ + # Validate internal authentication + auth = request.META.get("HTTP_AUTHORIZATION", "") + if not auth.startswith("Bearer "): + return Response({"detail": "Missing internal auth header"}, status=status.HTTP_401_UNAUTHORIZED) + + provided = auth.split(" ", 1)[1] + expected = getattr(settings, "INTERNAL_AUTH_TOKEN", None) + if not expected or not hmac.compare_digest(provided, expected): + return Response({"detail": "Invalid internal auth token"}, status=status.HTTP_403_FORBIDDEN) + + # Extract JWT from request body + jwt_token = request.data.get("jwt") + if not jwt_token: + return Response({"detail": "Missing jwt field in request body"}, status=status.HTTP_400_BAD_REQUEST) + + # Validate JWT format (should have 3 parts) + if not isinstance(jwt_token, str) or len(jwt_token.split('.')) != 3: + return Response({"detail": "Invalid JWT format"}, status=status.HTTP_401_UNAUTHORIZED) + + try: + # Decode and validate JWT using the same settings as token generation + decoded_token = jwt.decode( + jwt_token, + settings.SIMPLE_JWT['SIGNING_KEY'], + algorithms=[settings.SIMPLE_JWT['ALGORITHM']], + options={ + "verify_signature": True, + "verify_exp": True, + "verify_iat": True, + "require": ["exp", "iat", "user_id", "token_type"] + } + ) + + # Validate token type + if decoded_token.get('token_type') != 'access': + return Response({"detail": "Invalid token type - expected access token"}, status=status.HTTP_401_UNAUTHORIZED) + + # Extract user_id + user_id = decoded_token.get('user_id') + if not user_id: + return Response({"detail": "Missing user_id in JWT payload"}, status=status.HTTP_401_UNAUTHORIZED) + + # Try to get user info, but don't fail if database is unavailable + username = f"user_{user_id}" # Default username + has_active_access_token = True # JWT validation doesn't require AccessToken records + + try: + user = User.objects.get(id=user_id) + username = user.username + + # AccessToken model is for service tokens (GitHub, GitLab, etc.), not JWT validation + # JWT tokens are validated cryptographically, not via database records + has_active_access_token = True + + except Exception as db_error: + # Log database error but don't fail validation + # JWT is valid even if we can't check database + print(f"[WARNING] Database unavailable during JWT validation: {db_error}") + has_active_access_token = True # JWT validation is independent of database + + except jwt.ExpiredSignatureError: + return Response({"detail": "JWT token has expired"}, status=status.HTTP_401_UNAUTHORIZED) + except jwt.InvalidSignatureError: + return Response({"detail": "JWT signature verification failed"}, status=status.HTTP_401_UNAUTHORIZED) + except jwt.DecodeError: + return Response({"detail": "JWT decode error - malformed token"}, status=status.HTTP_401_UNAUTHORIZED) + except jwt.InvalidTokenError as e: + return Response({"detail": f"Invalid JWT: {str(e)}"}, status=status.HTTP_401_UNAUTHORIZED) + except Exception as e: + return Response({"detail": f"Token validation error: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + # JWT token is valid + return Response({ + "user_id": user_id, + "username": username, + "has_active_access_token": has_active_access_token, + "token_valid": True + }, status=status.HTTP_200_OK) \ No newline at end of file diff --git a/src/django_auth/generate_keys.py b/src/django_auth/generate_keys.py new file mode 100644 index 0000000..f133576 --- /dev/null +++ b/src/django_auth/generate_keys.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +""" +Script to generate secure keys for Django authentication service. +Run this script to generate the required environment variables. +""" + +import secrets +from cryptography.fernet import Fernet + +def generate_django_secret_key(): + """Generate a secure Django secret key""" + return ''.join(secrets.choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for _ in range(50)) + +def generate_fernet_key(): + """Generate a Fernet encryption key""" + return Fernet.generate_key().decode() + +if __name__ == '__main__': + print("=== Django Authentication Service - Key Generator ===\n") + + django_key = generate_django_secret_key() + fernet_key = generate_fernet_key() + + print("Add these to your .env file:\n") + print(f"DJANGO_SECRET_KEY={django_key}") + print(f"FERNET_KEY={fernet_key}") + print(f"DEBUG=True") + print("\nIMPORTANT: Keep these keys secure and never commit them to version control!") \ No newline at end of file diff --git a/src/django_auth/manage.py b/src/django_auth/manage.py new file mode 100644 index 0000000..5144cb3 --- /dev/null +++ b/src/django_auth/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +import os +import sys +from pathlib import Path + +# Add the project root and src directory to Python path +project_root = Path(__file__).resolve().parent.parent.parent +src_dir = project_root / 'src' +sys.path.insert(0, str(project_root)) +sys.path.insert(0, str(src_dir)) + +if __name__ == '__main__': + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_auth.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) \ No newline at end of file diff --git a/src/django_auth/settings.py b/src/django_auth/settings.py new file mode 100644 index 0000000..ef42385 --- /dev/null +++ b/src/django_auth/settings.py @@ -0,0 +1,160 @@ +import os +from pathlib import Path + +# Load environment variables from .env file only if not in Docker +# Docker containers should use environment variables passed by Docker Compose +if not os.getenv('DOCKER_CONTAINER'): + try: + from dotenv import load_dotenv + load_dotenv() + except ImportError: + # dotenv not available, skip loading + pass + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent.parent + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = os.getenv('DJANGO_SECRET_KEY', 'django-insecure-change-me-in-production') + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = os.getenv('DEBUG', 'True').lower() == 'true' + +ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'django-auth', '0.0.0.0'] + +# Application definition +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'rest_framework', + 'rest_framework_simplejwt', + 'django_auth.apps.auth_app', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'django_auth.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [BASE_DIR / 'src' / 'django_auth' / 'templates'], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'django_auth.wsgi.application' + + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': os.getenv('DB_NAME', 'databasex'), + 'USER': os.getenv('DB_USER', 'postgres'), + 'PASSWORD': os.getenv('DB_PASSWORD', 'postgres'), + 'HOST': os.getenv('DB_HOST', 'localhost'), + 'PORT': os.getenv('DB_PORT', '5432'), + } +} + +# Password validation +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + +# Internationalization +LANGUAGE_CODE = 'en-us' +TIME_ZONE = 'UTC' +USE_I18N = True +USE_TZ = True + +# Static files (CSS, JavaScript, Images) +STATIC_URL = '/static/' +STATIC_ROOT = BASE_DIR / 'staticfiles' + +# Default primary key field type +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +# REST Framework configuration +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework_simplejwt.authentication.JWTAuthentication', + ), + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.IsAuthenticated', + ], +} + +# JWT Configuration +from datetime import timedelta + +JWT_SECRET_KEY = os.getenv('JWT_SECRET_KEY') + +if not JWT_SECRET_KEY or JWT_SECRET_KEY.strip() == '': + import sys + print("CRITICAL ERROR: JWT_SECRET_KEY environment variable is not set or empty!") + print("This is required for JWT token generation and validation.") + print("Available environment variables:") + for key in sorted(os.environ.keys()): + if 'JWT' in key or 'SECRET' in key or 'TOKEN' in key: + print(f" {key}={os.environ[key][:20]}..." if len(os.environ[key]) > 20 else f" {key}={os.environ[key]}") + print("Please ensure JWT_SECRET_KEY is set in Docker Compose environment.") + sys.exit(1) + +SIMPLE_JWT = { + 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60), + 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), + 'ROTATE_REFRESH_TOKENS': True, + 'SIGNING_KEY': JWT_SECRET_KEY, + 'ALGORITHM': 'HS256', +} + +FERNET_KEY = os.getenv('FERNET_KEY') +if not FERNET_KEY: + from cryptography.fernet import Fernet + FERNET_KEY = Fernet.generate_key().decode() + print(f"Generated FERNET_KEY for development: {FERNET_KEY}") + +INTERNAL_AUTH_TOKEN = os.getenv('INTERNAL_AUTH_TOKEN') +if not INTERNAL_AUTH_TOKEN: + import sys + print("CRITICAL ERROR: INTERNAL_AUTH_TOKEN environment variable is not set!") + print("This is required for backend-to-backend authentication.") + print("Please ensure INTERNAL_AUTH_TOKEN is set in Docker Compose environment.") + sys.exit(1) + +# Login/Logout URLs +LOGIN_URL = '/login/' +LOGIN_REDIRECT_URL = '/tokens/' +LOGOUT_REDIRECT_URL = '/login/' \ No newline at end of file diff --git a/src/django_auth/templates/auth_app/login.html b/src/django_auth/templates/auth_app/login.html new file mode 100644 index 0000000..3a44ec2 --- /dev/null +++ b/src/django_auth/templates/auth_app/login.html @@ -0,0 +1,30 @@ +{% extends 'base.html' %} + +{% block title %}Login - Oráculo{% endblock %} + +{% block content %} +
+
+
+
+

Login

+
+
+
+ {% csrf_token %} +
+ + +
+
+ + +
+ + Don't have an account? Register +
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/src/django_auth/templates/auth_app/register.html b/src/django_auth/templates/auth_app/register.html new file mode 100644 index 0000000..89e15fd --- /dev/null +++ b/src/django_auth/templates/auth_app/register.html @@ -0,0 +1,49 @@ +{% extends 'base.html' %} + +{% block title %}Register - Oráculo{% endblock %} + +{% block content %} +
+
+
+
+

Register

+
+
+
+ {% csrf_token %} + {% if form.errors %} +
+ {{ form.errors }} +
+ {% endif %} + +
+ + {{ form.email }} +
+
+ + {{ form.first_name }} +
+
+ + {{ form.last_name }} +
+
+ + {{ form.password1 }} +
+
+ + {{ form.password2 }} +
+ + + Already have an account? Login +
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/src/django_auth/templates/auth_app/token_created.html b/src/django_auth/templates/auth_app/token_created.html new file mode 100644 index 0000000..7d9046f --- /dev/null +++ b/src/django_auth/templates/auth_app/token_created.html @@ -0,0 +1,95 @@ +{% extends 'base.html' %} + +{% block title %}Token Created - Oráculo{% endblock %} + +{% block content %} +
+
+
+
+

Token Created Successfully

+
+
+
+ Important: + This is the only time you will see your full access token. + Copy it now and store it securely - you won't be able to see it again. +
+ +
+
Token Details
+
+
+ Service: {{ token.get_service_display }} +
+
+ Created: {{ token.created_at|date:"M d, Y H:i" }} +
+
+
+ +
+
Your Access Token
+

Copy this token and paste it into OpenWebUI or use it as a Bearer token in API requests:

+ +
+
{{ jwt_token }}
+ +
+
+ +
+
How to use this token:
+
    +
  • OpenWebUI: Paste this token in the pipeline settings as your Bearer token
  • +
  • API Requests: Include as Authorization: Bearer <token> header
  • +
  • FastAPI: This token will authenticate you with the /ask endpoint
  • +
+
+ + +
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/src/django_auth/templates/auth_app/token_form.html b/src/django_auth/templates/auth_app/token_form.html new file mode 100644 index 0000000..bc35acc --- /dev/null +++ b/src/django_auth/templates/auth_app/token_form.html @@ -0,0 +1,58 @@ +{% extends 'base.html' %} + +{% block title %}{{ title }} - Oráculo{% endblock %} + +{% block content %} +
+
+
+
+

{{ title }}

+
+
+
+ {% csrf_token %} + {% if form.errors %} +
+ {{ form.errors }} +
+ {% endif %} + +
+ + {{ form.service }} + {% if token %} +
Current: {{ token.get_service_display }}
+ {% endif %} +
+ +
+ + {{ form.token }} +
{{ form.token.help_text }}
+ {% if token %} +
Current token: {{ token.get_masked_token }}
+ {% endif %} +
+ +
+ JWT Token Generation: + {% if token %} + A new JWT token will be generated if you enter any value above. The token will be encrypted before storage and displayed once after creation. + {% else %} + A JWT token will be automatically generated for API authentication. You'll see the full token once after creation to copy for use in OpenWebUI. + {% endif %} +
+ +
+ + Cancel +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/src/django_auth/templates/auth_app/token_list.html b/src/django_auth/templates/auth_app/token_list.html new file mode 100644 index 0000000..714743e --- /dev/null +++ b/src/django_auth/templates/auth_app/token_list.html @@ -0,0 +1,77 @@ +{% extends 'base.html' %} + +{% block title %}Token Management - Oráculo{% endblock %} + +{% block content %} +
+

Your Access Tokens

+ Add New Token +
+ +{% if tokens %} +
+ {% for token in tokens %} +
+
+
+
+ {{ token.get_service_display }} + {{ token.get_masked_token }} +
+

+ + Created: {{ token.created_at|date:"M d, Y" }}
+ Updated: {{ token.updated_at|date:"M d, Y" }} +
+

+
+ Edit + + Delete + +
+
+
+
+ {% endfor %} +
+{% else %} +
+

No tokens configured

+

Add your first access token to get started.

+ Add Token +
+{% endif %} + + + + + +{% endblock %} \ No newline at end of file diff --git a/src/django_auth/templates/base.html b/src/django_auth/templates/base.html new file mode 100644 index 0000000..3e6ce7f --- /dev/null +++ b/src/django_auth/templates/base.html @@ -0,0 +1,42 @@ + + + + + + {% block title %}Oráculo - Token Management{% endblock %} + + + + + +
+ {% if messages %} + {% for message in messages %} + + {% endfor %} + {% endif %} + + {% block content %} + {% endblock %} +
+ + + + \ No newline at end of file diff --git a/src/django_auth/urls.py b/src/django_auth/urls.py new file mode 100644 index 0000000..7b79086 --- /dev/null +++ b/src/django_auth/urls.py @@ -0,0 +1,9 @@ +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('api/', include('django_auth.apps.auth_app.urls')), + path('internal/', include('django_auth.apps.auth_app.urls_internal')), + path('', include('django_auth.apps.auth_app.ui_urls')), +] \ No newline at end of file diff --git a/src/django_auth/wsgi.py b/src/django_auth/wsgi.py new file mode 100644 index 0000000..bedde8a --- /dev/null +++ b/src/django_auth/wsgi.py @@ -0,0 +1,6 @@ +import os +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_auth.settings') + +application = get_wsgi_application() \ No newline at end of file diff --git a/src/etl/__init__.py b/src/etl/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/staticfiles/admin/css/autocomplete.css b/staticfiles/admin/css/autocomplete.css new file mode 100644 index 0000000..69c94e7 --- /dev/null +++ b/staticfiles/admin/css/autocomplete.css @@ -0,0 +1,275 @@ +select.admin-autocomplete { + width: 20em; +} + +.select2-container--admin-autocomplete.select2-container { + min-height: 30px; +} + +.select2-container--admin-autocomplete .select2-selection--single, +.select2-container--admin-autocomplete .select2-selection--multiple { + min-height: 30px; + padding: 0; +} + +.select2-container--admin-autocomplete.select2-container--focus .select2-selection, +.select2-container--admin-autocomplete.select2-container--open .select2-selection { + border-color: var(--body-quiet-color); + min-height: 30px; +} + +.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--single, +.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--single { + padding: 0; +} + +.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--multiple, +.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--multiple { + padding: 0; +} + +.select2-container--admin-autocomplete .select2-selection--single { + background-color: var(--body-bg); + border: 1px solid var(--border-color); + border-radius: 4px; +} + +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered { + color: var(--body-fg); + line-height: 30px; +} + +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; +} + +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder { + color: var(--body-quiet-color); +} + +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow { + height: 26px; + position: absolute; + top: 1px; + right: 1px; + width: 20px; +} + +.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b { + border-color: #888 transparent transparent transparent; + border-style: solid; + border-width: 5px 4px 0 4px; + height: 0; + left: 50%; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; +} + +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; +} + +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__arrow { + left: 1px; + right: auto; +} + +.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single { + background-color: var(--darkened-bg); + cursor: default; +} + +.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single .select2-selection__clear { + display: none; +} + +.select2-container--admin-autocomplete.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #888 transparent; + border-width: 0 4px 5px 4px; +} + +.select2-container--admin-autocomplete .select2-selection--multiple { + background-color: var(--body-bg); + border: 1px solid var(--border-color); + border-radius: 4px; + cursor: text; +} + +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered { + box-sizing: border-box; + list-style: none; + margin: 0; + padding: 0 10px 5px 5px; + width: 100%; + display: flex; + flex-wrap: wrap; +} + +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li { + list-style: none; +} + +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder { + color: var(--body-quiet-color); + margin-top: 5px; + float: left; +} + +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; + margin: 5px; + position: absolute; + right: 0; +} + +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice { + background-color: var(--darkened-bg); + border: 1px solid var(--border-color); + border-radius: 4px; + cursor: default; + float: left; + margin-right: 5px; + margin-top: 5px; + padding: 0 5px; +} + +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove { + color: var(--body-quiet-color); + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 2px; +} + +.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover { + color: var(--body-fg); +} + +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-search--inline { + float: right; +} + +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + margin-left: 5px; + margin-right: auto; +} + +.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; +} + +.select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple { + border: solid var(--body-quiet-color) 1px; + outline: 0; +} + +.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple { + background-color: var(--darkened-bg); + cursor: default; +} + +.select2-container--admin-autocomplete.select2-container--disabled .select2-selection__choice__remove { + display: none; +} + +.select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--multiple { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +.select2-container--admin-autocomplete .select2-search--dropdown { + background: var(--darkened-bg); +} + +.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field { + background: var(--body-bg); + color: var(--body-fg); + border: 1px solid var(--border-color); + border-radius: 4px; +} + +.select2-container--admin-autocomplete .select2-search--inline .select2-search__field { + background: transparent; + color: var(--body-fg); + border: none; + outline: 0; + box-shadow: none; + -webkit-appearance: textfield; +} + +.select2-container--admin-autocomplete .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; + color: var(--body-fg); + background: var(--body-bg); +} + +.select2-container--admin-autocomplete .select2-results__option[role=group] { + padding: 0; +} + +.select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] { + color: var(--body-quiet-color); +} + +.select2-container--admin-autocomplete .select2-results__option[aria-selected=true] { + background-color: var(--selected-bg); + color: var(--body-fg); +} + +.select2-container--admin-autocomplete .select2-results__option .select2-results__option { + padding-left: 1em; +} + +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__group { + padding-left: 0; +} + +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option { + margin-left: -1em; + padding-left: 2em; +} + +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -2em; + padding-left: 3em; +} + +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -3em; + padding-left: 4em; +} + +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -4em; + padding-left: 5em; +} + +.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -5em; + padding-left: 6em; +} + +.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] { + background-color: var(--primary); + color: var(--primary-fg); +} + +.select2-container--admin-autocomplete .select2-results__group { + cursor: default; + display: block; + padding: 6px; +} diff --git a/staticfiles/admin/css/base.css b/staticfiles/admin/css/base.css new file mode 100644 index 0000000..93db7d0 --- /dev/null +++ b/staticfiles/admin/css/base.css @@ -0,0 +1,1145 @@ +/* + DJANGO Admin styles +*/ + +/* VARIABLE DEFINITIONS */ +html[data-theme="light"], +:root { + --primary: #79aec8; + --secondary: #417690; + --accent: #f5dd5d; + --primary-fg: #fff; + + --body-fg: #333; + --body-bg: #fff; + --body-quiet-color: #666; + --body-loud-color: #000; + + --header-color: #ffc; + --header-branding-color: var(--accent); + --header-bg: var(--secondary); + --header-link-color: var(--primary-fg); + + --breadcrumbs-fg: #c4dce8; + --breadcrumbs-link-fg: var(--body-bg); + --breadcrumbs-bg: var(--primary); + + --link-fg: #417893; + --link-hover-color: #036; + --link-selected-fg: #5b80b2; + + --hairline-color: #e8e8e8; + --border-color: #ccc; + + --error-fg: #ba2121; + + --message-success-bg: #dfd; + --message-warning-bg: #ffc; + --message-error-bg: #ffefef; + + --darkened-bg: #f8f8f8; /* A bit darker than --body-bg */ + --selected-bg: #e4e4e4; /* E.g. selected table cells */ + --selected-row: #ffc; + + --button-fg: #fff; + --button-bg: var(--primary); + --button-hover-bg: #609ab6; + --default-button-bg: var(--secondary); + --default-button-hover-bg: #205067; + --close-button-bg: #747474; + --close-button-hover-bg: #333; + --delete-button-bg: #ba2121; + --delete-button-hover-bg: #a41515; + + --object-tools-fg: var(--button-fg); + --object-tools-bg: var(--close-button-bg); + --object-tools-hover-bg: var(--close-button-hover-bg); + + --font-family-primary: + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + system-ui, + Roboto, + "Helvetica Neue", + Arial, + sans-serif, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; + --font-family-monospace: + ui-monospace, + Menlo, + Monaco, + "Cascadia Mono", + "Segoe UI Mono", + "Roboto Mono", + "Oxygen Mono", + "Ubuntu Monospace", + "Source Code Pro", + "Fira Mono", + "Droid Sans Mono", + "Courier New", + monospace, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; +} + +html, body { + height: 100%; +} + +body { + margin: 0; + padding: 0; + font-size: 0.875rem; + font-family: var(--font-family-primary); + color: var(--body-fg); + background: var(--body-bg); +} + +/* LINKS */ + +a:link, a:visited { + color: var(--link-fg); + text-decoration: none; + transition: color 0.15s, background 0.15s; +} + +a:focus, a:hover { + color: var(--link-hover-color); +} + +a:focus { + text-decoration: underline; +} + +a img { + border: none; +} + +a.section:link, a.section:visited { + color: var(--header-link-color); + text-decoration: none; +} + +a.section:focus, a.section:hover { + text-decoration: underline; +} + +/* GLOBAL DEFAULTS */ + +p, ol, ul, dl { + margin: .2em 0 .8em 0; +} + +p { + padding: 0; + line-height: 140%; +} + +h1,h2,h3,h4,h5 { + font-weight: bold; +} + +h1 { + margin: 0 0 20px; + font-weight: 300; + font-size: 1.25rem; + color: var(--body-quiet-color); +} + +h2 { + font-size: 1rem; + margin: 1em 0 .5em 0; +} + +h2.subhead { + font-weight: normal; + margin-top: 0; +} + +h3 { + font-size: 0.875rem; + margin: .8em 0 .3em 0; + color: var(--body-quiet-color); + font-weight: bold; +} + +h4 { + font-size: 0.75rem; + margin: 1em 0 .8em 0; + padding-bottom: 3px; +} + +h5 { + font-size: 0.625rem; + margin: 1.5em 0 .5em 0; + color: var(--body-quiet-color); + text-transform: uppercase; + letter-spacing: 1px; +} + +ul > li { + list-style-type: square; + padding: 1px 0; +} + +li ul { + margin-bottom: 0; +} + +li, dt, dd { + font-size: 0.8125rem; + line-height: 1.25rem; +} + +dt { + font-weight: bold; + margin-top: 4px; +} + +dd { + margin-left: 0; +} + +form { + margin: 0; + padding: 0; +} + +fieldset { + margin: 0; + min-width: 0; + padding: 0; + border: none; + border-top: 1px solid var(--hairline-color); +} + +blockquote { + font-size: 0.6875rem; + color: #777; + margin-left: 2px; + padding-left: 10px; + border-left: 5px solid #ddd; +} + +code, pre { + font-family: var(--font-family-monospace); + color: var(--body-quiet-color); + font-size: 0.75rem; + overflow-x: auto; +} + +pre.literal-block { + margin: 10px; + background: var(--darkened-bg); + padding: 6px 8px; +} + +code strong { + color: #930; +} + +hr { + clear: both; + color: var(--hairline-color); + background-color: var(--hairline-color); + height: 1px; + border: none; + margin: 0; + padding: 0; + line-height: 1px; +} + +/* TEXT STYLES & MODIFIERS */ + +.small { + font-size: 0.6875rem; +} + +.mini { + font-size: 0.625rem; +} + +.help, p.help, form p.help, div.help, form div.help, div.help li { + font-size: 0.6875rem; + color: var(--body-quiet-color); +} + +div.help ul { + margin-bottom: 0; +} + +.help-tooltip { + cursor: help; +} + +p img, h1 img, h2 img, h3 img, h4 img, td img { + vertical-align: middle; +} + +.quiet, a.quiet:link, a.quiet:visited { + color: var(--body-quiet-color); + font-weight: normal; +} + +.clear { + clear: both; +} + +.nowrap { + white-space: nowrap; +} + +.hidden { + display: none !important; +} + +/* TABLES */ + +table { + border-collapse: collapse; + border-color: var(--border-color); +} + +td, th { + font-size: 0.8125rem; + line-height: 1rem; + border-bottom: 1px solid var(--hairline-color); + vertical-align: top; + padding: 8px; +} + +th { + font-weight: 600; + text-align: left; +} + +thead th, +tfoot td { + color: var(--body-quiet-color); + padding: 5px 10px; + font-size: 0.6875rem; + background: var(--body-bg); + border: none; + border-top: 1px solid var(--hairline-color); + border-bottom: 1px solid var(--hairline-color); +} + +tfoot td { + border-bottom: none; + border-top: 1px solid var(--hairline-color); +} + +thead th.required { + color: var(--body-loud-color); +} + +tr.alt { + background: var(--darkened-bg); +} + +tr:nth-child(odd), .row-form-errors { + background: var(--body-bg); +} + +tr:nth-child(even), +tr:nth-child(even) .errorlist, +tr:nth-child(odd) + .row-form-errors, +tr:nth-child(odd) + .row-form-errors .errorlist { + background: var(--darkened-bg); +} + +/* SORTABLE TABLES */ + +thead th { + padding: 5px 10px; + line-height: normal; + text-transform: uppercase; + background: var(--darkened-bg); +} + +thead th a:link, thead th a:visited { + color: var(--body-quiet-color); +} + +thead th.sorted { + background: var(--selected-bg); +} + +thead th.sorted .text { + padding-right: 42px; +} + +table thead th .text span { + padding: 8px 10px; + display: block; +} + +table thead th .text a { + display: block; + cursor: pointer; + padding: 8px 10px; +} + +table thead th .text a:focus, table thead th .text a:hover { + background: var(--selected-bg); +} + +thead th.sorted a.sortremove { + visibility: hidden; +} + +table thead th.sorted:hover a.sortremove { + visibility: visible; +} + +table thead th.sorted .sortoptions { + display: block; + padding: 9px 5px 0 5px; + float: right; + text-align: right; +} + +table thead th.sorted .sortpriority { + font-size: .8em; + min-width: 12px; + text-align: center; + vertical-align: 3px; + margin-left: 2px; + margin-right: 2px; +} + +table thead th.sorted .sortoptions a { + position: relative; + width: 14px; + height: 14px; + display: inline-block; + background: url(../img/sorting-icons.svg) 0 0 no-repeat; + background-size: 14px auto; +} + +table thead th.sorted .sortoptions a.sortremove { + background-position: 0 0; +} + +table thead th.sorted .sortoptions a.sortremove:after { + content: '\\'; + position: absolute; + top: -6px; + left: 3px; + font-weight: 200; + font-size: 1.125rem; + color: var(--body-quiet-color); +} + +table thead th.sorted .sortoptions a.sortremove:focus:after, +table thead th.sorted .sortoptions a.sortremove:hover:after { + color: var(--link-fg); +} + +table thead th.sorted .sortoptions a.sortremove:focus, +table thead th.sorted .sortoptions a.sortremove:hover { + background-position: 0 -14px; +} + +table thead th.sorted .sortoptions a.ascending { + background-position: 0 -28px; +} + +table thead th.sorted .sortoptions a.ascending:focus, +table thead th.sorted .sortoptions a.ascending:hover { + background-position: 0 -42px; +} + +table thead th.sorted .sortoptions a.descending { + top: 1px; + background-position: 0 -56px; +} + +table thead th.sorted .sortoptions a.descending:focus, +table thead th.sorted .sortoptions a.descending:hover { + background-position: 0 -70px; +} + +/* FORM DEFAULTS */ + +input, textarea, select, .form-row p, form .button { + margin: 2px 0; + padding: 2px 3px; + vertical-align: middle; + font-family: var(--font-family-primary); + font-weight: normal; + font-size: 0.8125rem; +} +.form-row div.help { + padding: 2px 3px; +} + +textarea { + vertical-align: top; +} + +input[type=text], input[type=password], input[type=email], input[type=url], +input[type=number], input[type=tel], textarea, select, .vTextField { + border: 1px solid var(--border-color); + border-radius: 4px; + padding: 5px 6px; + margin-top: 0; + color: var(--body-fg); + background-color: var(--body-bg); +} + +input[type=text]:focus, input[type=password]:focus, input[type=email]:focus, +input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus, +textarea:focus, select:focus, .vTextField:focus { + border-color: var(--body-quiet-color); +} + +select { + height: 1.875rem; +} + +select[multiple] { + /* Allow HTML size attribute to override the height in the rule above. */ + height: auto; + min-height: 150px; +} + +/* FORM BUTTONS */ + +.button, input[type=submit], input[type=button], .submit-row input, a.button { + background: var(--button-bg); + padding: 10px 15px; + border: none; + border-radius: 4px; + color: var(--button-fg); + cursor: pointer; + transition: background 0.15s; +} + +a.button { + padding: 4px 5px; +} + +.button:active, input[type=submit]:active, input[type=button]:active, +.button:focus, input[type=submit]:focus, input[type=button]:focus, +.button:hover, input[type=submit]:hover, input[type=button]:hover { + background: var(--button-hover-bg); +} + +.button[disabled], input[type=submit][disabled], input[type=button][disabled] { + opacity: 0.4; +} + +.button.default, input[type=submit].default, .submit-row input.default { + border: none; + font-weight: 400; + background: var(--default-button-bg); +} + +.button.default:active, input[type=submit].default:active, +.button.default:focus, input[type=submit].default:focus, +.button.default:hover, input[type=submit].default:hover { + background: var(--default-button-hover-bg); +} + +.button[disabled].default, +input[type=submit][disabled].default, +input[type=button][disabled].default { + opacity: 0.4; +} + + +/* MODULES */ + +.module { + border: none; + margin-bottom: 30px; + background: var(--body-bg); +} + +.module p, .module ul, .module h3, .module h4, .module dl, .module pre { + padding-left: 10px; + padding-right: 10px; +} + +.module blockquote { + margin-left: 12px; +} + +.module ul, .module ol { + margin-left: 1.5em; +} + +.module h3 { + margin-top: .6em; +} + +.module h2, .module caption, .inline-group h2 { + margin: 0; + padding: 8px; + font-weight: 400; + font-size: 0.8125rem; + text-align: left; + background: var(--primary); + color: var(--header-link-color); +} + +.module caption, +.inline-group h2 { + font-size: 0.75rem; + letter-spacing: 0.5px; + text-transform: uppercase; +} + +.module table { + border-collapse: collapse; +} + +/* MESSAGES & ERRORS */ + +ul.messagelist { + padding: 0; + margin: 0; +} + +ul.messagelist li { + display: block; + font-weight: 400; + font-size: 0.8125rem; + padding: 10px 10px 10px 65px; + margin: 0 0 10px 0; + background: var(--message-success-bg) url(../img/icon-yes.svg) 40px 12px no-repeat; + background-size: 16px auto; + color: var(--body-fg); + word-break: break-word; +} + +ul.messagelist li.warning { + background: var(--message-warning-bg) url(../img/icon-alert.svg) 40px 14px no-repeat; + background-size: 14px auto; +} + +ul.messagelist li.error { + background: var(--message-error-bg) url(../img/icon-no.svg) 40px 12px no-repeat; + background-size: 16px auto; +} + +.errornote { + font-size: 0.875rem; + font-weight: 700; + display: block; + padding: 10px 12px; + margin: 0 0 10px 0; + color: var(--error-fg); + border: 1px solid var(--error-fg); + border-radius: 4px; + background-color: var(--body-bg); + background-position: 5px 12px; + overflow-wrap: break-word; +} + +ul.errorlist { + margin: 0 0 4px; + padding: 0; + color: var(--error-fg); + background: var(--body-bg); +} + +ul.errorlist li { + font-size: 0.8125rem; + display: block; + margin-bottom: 4px; + overflow-wrap: break-word; +} + +ul.errorlist li:first-child { + margin-top: 0; +} + +ul.errorlist li a { + color: inherit; + text-decoration: underline; +} + +td ul.errorlist { + margin: 0; + padding: 0; +} + +td ul.errorlist li { + margin: 0; +} + +.form-row.errors { + margin: 0; + border: none; + border-bottom: 1px solid var(--hairline-color); + background: none; +} + +.form-row.errors ul.errorlist li { + padding-left: 0; +} + +.errors input, .errors select, .errors textarea, +td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea { + border: 1px solid var(--error-fg); +} + +.description { + font-size: 0.75rem; + padding: 5px 0 0 12px; +} + +/* BREADCRUMBS */ + +div.breadcrumbs { + background: var(--breadcrumbs-bg); + padding: 10px 40px; + border: none; + color: var(--breadcrumbs-fg); + text-align: left; +} + +div.breadcrumbs a { + color: var(--breadcrumbs-link-fg); +} + +div.breadcrumbs a:focus, div.breadcrumbs a:hover { + color: var(--breadcrumbs-fg); +} + +/* ACTION ICONS */ + +.viewlink, .inlineviewlink { + padding-left: 16px; + background: url(../img/icon-viewlink.svg) 0 1px no-repeat; +} + +.addlink { + padding-left: 16px; + background: url(../img/icon-addlink.svg) 0 1px no-repeat; +} + +.changelink, .inlinechangelink { + padding-left: 16px; + background: url(../img/icon-changelink.svg) 0 1px no-repeat; +} + +.deletelink { + padding-left: 16px; + background: url(../img/icon-deletelink.svg) 0 1px no-repeat; +} + +a.deletelink:link, a.deletelink:visited { + color: #CC3434; /* XXX Probably unused? */ +} + +a.deletelink:focus, a.deletelink:hover { + color: #993333; /* XXX Probably unused? */ + text-decoration: none; +} + +/* OBJECT TOOLS */ + +.object-tools { + font-size: 0.625rem; + font-weight: bold; + padding-left: 0; + float: right; + position: relative; + margin-top: -48px; +} + +.object-tools li { + display: block; + float: left; + margin-left: 5px; + height: 1rem; +} + +.object-tools a { + border-radius: 15px; +} + +.object-tools a:link, .object-tools a:visited { + display: block; + float: left; + padding: 3px 12px; + background: var(--object-tools-bg); + color: var(--object-tools-fg); + font-weight: 400; + font-size: 0.6875rem; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.object-tools a:focus, .object-tools a:hover { + background-color: var(--object-tools-hover-bg); +} + +.object-tools a:focus{ + text-decoration: none; +} + +.object-tools a.viewsitelink, .object-tools a.addlink { + background-repeat: no-repeat; + background-position: right 7px center; + padding-right: 26px; +} + +.object-tools a.viewsitelink { + background-image: url(../img/tooltag-arrowright.svg); +} + +.object-tools a.addlink { + background-image: url(../img/tooltag-add.svg); +} + +/* OBJECT HISTORY */ + +#change-history table { + width: 100%; +} + +#change-history table tbody th { + width: 16em; +} + +#change-history .paginator { + color: var(--body-quiet-color); + border-bottom: 1px solid var(--hairline-color); + background: var(--body-bg); + overflow: hidden; +} + +/* PAGE STRUCTURE */ + +#container { + position: relative; + width: 100%; + min-width: 980px; + padding: 0; + display: flex; + flex-direction: column; + height: 100%; +} + +#container > div { + flex-shrink: 0; +} + +#container > .main { + display: flex; + flex: 1 0 auto; +} + +.main > .content { + flex: 1 0; + max-width: 100%; +} + +.skip-to-content-link { + position: absolute; + top: -999px; + margin: 5px; + padding: 5px; + background: var(--body-bg); + z-index: 1; +} + +.skip-to-content-link:focus { + left: 0px; + top: 0px; +} + +#content { + padding: 20px 40px; +} + +.dashboard #content { + width: 600px; +} + +#content-main { + float: left; + width: 100%; +} + +#content-related { + float: right; + width: 260px; + position: relative; + margin-right: -300px; +} + +#footer { + clear: both; + padding: 10px; +} + +/* COLUMN TYPES */ + +.colMS { + margin-right: 300px; +} + +.colSM { + margin-left: 300px; +} + +.colSM #content-related { + float: left; + margin-right: 0; + margin-left: -300px; +} + +.colSM #content-main { + float: right; +} + +.popup .colM { + width: auto; +} + +/* HEADER */ + +#header { + width: auto; + height: auto; + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 40px; + background: var(--header-bg); + color: var(--header-color); + overflow: hidden; +} + +#header a:link, #header a:visited, #logout-form button { + color: var(--header-link-color); +} + +#header a:focus , #header a:hover { + text-decoration: underline; +} + +#branding { + display: flex; +} + +#branding h1 { + padding: 0; + margin: 0; + margin-inline-end: 20px; + font-weight: 300; + font-size: 1.5rem; + color: var(--header-branding-color); +} + +#branding h1 a:link, #branding h1 a:visited { + color: var(--accent); +} + +#branding h2 { + padding: 0 10px; + font-size: 0.875rem; + margin: -8px 0 8px 0; + font-weight: normal; + color: var(--header-color); +} + +#branding a:hover { + text-decoration: none; +} + +#logout-form { + display: inline; +} + +#logout-form button { + background: none; + border: 0; + cursor: pointer; + font-family: var(--font-family-primary); +} + +#user-tools { + float: right; + margin: 0 0 0 20px; + text-align: right; +} + +#user-tools, #logout-form button{ + padding: 0; + font-weight: 300; + font-size: 0.6875rem; + letter-spacing: 0.5px; + text-transform: uppercase; +} + +#user-tools a, #logout-form button { + border-bottom: 1px solid rgba(255, 255, 255, 0.25); +} + +#user-tools a:focus, #user-tools a:hover, +#logout-form button:active, #logout-form button:hover { + text-decoration: none; + border-bottom: 0; +} + +#logout-form button:active, #logout-form button:hover { + margin-bottom: 1px; +} + +/* SIDEBAR */ + +#content-related { + background: var(--darkened-bg); +} + +#content-related .module { + background: none; +} + +#content-related h3 { + color: var(--body-quiet-color); + padding: 0 16px; + margin: 0 0 16px; +} + +#content-related h4 { + font-size: 0.8125rem; +} + +#content-related p { + padding-left: 16px; + padding-right: 16px; +} + +#content-related .actionlist { + padding: 0; + margin: 16px; +} + +#content-related .actionlist li { + line-height: 1.2; + margin-bottom: 10px; + padding-left: 18px; +} + +#content-related .module h2 { + background: none; + padding: 16px; + margin-bottom: 16px; + border-bottom: 1px solid var(--hairline-color); + font-size: 1.125rem; + color: var(--body-fg); +} + +.delete-confirmation form input[type="submit"] { + background: var(--delete-button-bg); + border-radius: 4px; + padding: 10px 15px; + color: var(--button-fg); +} + +.delete-confirmation form input[type="submit"]:active, +.delete-confirmation form input[type="submit"]:focus, +.delete-confirmation form input[type="submit"]:hover { + background: var(--delete-button-hover-bg); +} + +.delete-confirmation form .cancel-link { + display: inline-block; + vertical-align: middle; + height: 0.9375rem; + line-height: 0.9375rem; + border-radius: 4px; + padding: 10px 15px; + color: var(--button-fg); + background: var(--close-button-bg); + margin: 0 0 0 10px; +} + +.delete-confirmation form .cancel-link:active, +.delete-confirmation form .cancel-link:focus, +.delete-confirmation form .cancel-link:hover { + background: var(--close-button-hover-bg); +} + +/* POPUP */ +.popup #content { + padding: 20px; +} + +.popup #container { + min-width: 0; +} + +.popup #header { + padding: 10px 20px; +} + +/* PAGINATOR */ + +.paginator { + display: flex; + align-items: center; + gap: 4px; + font-size: 0.8125rem; + padding-top: 10px; + padding-bottom: 10px; + line-height: 22px; + margin: 0; + border-top: 1px solid var(--hairline-color); + width: 100%; +} + +.paginator a:link, .paginator a:visited { + padding: 2px 6px; + background: var(--button-bg); + text-decoration: none; + color: var(--button-fg); +} + +.paginator a.showall { + border: none; + background: none; + color: var(--link-fg); +} + +.paginator a.showall:focus, .paginator a.showall:hover { + background: none; + color: var(--link-hover-color); +} + +.paginator .end { + margin-right: 6px; +} + +.paginator .this-page { + padding: 2px 6px; + font-weight: bold; + font-size: 0.8125rem; + vertical-align: top; +} + +.paginator a:focus, .paginator a:hover { + color: white; + background: var(--link-hover-color); +} + +.paginator input { + margin-left: auto; +} + +.base-svgs { + display: none; +} diff --git a/staticfiles/admin/css/changelists.css b/staticfiles/admin/css/changelists.css new file mode 100644 index 0000000..a754513 --- /dev/null +++ b/staticfiles/admin/css/changelists.css @@ -0,0 +1,328 @@ +/* CHANGELISTS */ + +#changelist { + display: flex; + align-items: flex-start; + justify-content: space-between; +} + +#changelist .changelist-form-container { + flex: 1 1 auto; + min-width: 0; +} + +#changelist table { + width: 100%; +} + +.change-list .hiddenfields { display:none; } + +.change-list .filtered table { + border-right: none; +} + +.change-list .filtered { + min-height: 400px; +} + +.change-list .filtered .results, .change-list .filtered .paginator, +.filtered #toolbar, .filtered div.xfull { + width: auto; +} + +.change-list .filtered table tbody th { + padding-right: 1em; +} + +#changelist-form .results { + overflow-x: auto; + width: 100%; +} + +#changelist .toplinks { + border-bottom: 1px solid var(--hairline-color); +} + +#changelist .paginator { + color: var(--body-quiet-color); + border-bottom: 1px solid var(--hairline-color); + background: var(--body-bg); + overflow: hidden; +} + +/* CHANGELIST TABLES */ + +#changelist table thead th { + padding: 0; + white-space: nowrap; + vertical-align: middle; +} + +#changelist table thead th.action-checkbox-column { + width: 1.5em; + text-align: center; +} + +#changelist table tbody td.action-checkbox { + text-align: center; +} + +#changelist table tfoot { + color: var(--body-quiet-color); +} + +/* TOOLBAR */ + +#toolbar { + padding: 8px 10px; + margin-bottom: 15px; + border-top: 1px solid var(--hairline-color); + border-bottom: 1px solid var(--hairline-color); + background: var(--darkened-bg); + color: var(--body-quiet-color); +} + +#toolbar form input { + border-radius: 4px; + font-size: 0.875rem; + padding: 5px; + color: var(--body-fg); +} + +#toolbar #searchbar { + height: 1.1875rem; + border: 1px solid var(--border-color); + padding: 2px 5px; + margin: 0; + vertical-align: top; + font-size: 0.8125rem; + max-width: 100%; +} + +#toolbar #searchbar:focus { + border-color: var(--body-quiet-color); +} + +#toolbar form input[type="submit"] { + border: 1px solid var(--border-color); + font-size: 0.8125rem; + padding: 4px 8px; + margin: 0; + vertical-align: middle; + background: var(--body-bg); + box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; + cursor: pointer; + color: var(--body-fg); +} + +#toolbar form input[type="submit"]:focus, +#toolbar form input[type="submit"]:hover { + border-color: var(--body-quiet-color); +} + +#changelist-search img { + vertical-align: middle; + margin-right: 4px; +} + +#changelist-search .help { + word-break: break-word; +} + +/* FILTER COLUMN */ + +#changelist-filter { + flex: 0 0 240px; + order: 1; + background: var(--darkened-bg); + border-left: none; + margin: 0 0 0 30px; +} + +#changelist-filter h2 { + font-size: 0.875rem; + text-transform: uppercase; + letter-spacing: 0.5px; + padding: 5px 15px; + margin-bottom: 12px; + border-bottom: none; +} + +#changelist-filter h3, +#changelist-filter details summary { + font-weight: 400; + padding: 0 15px; + margin-bottom: 10px; +} + +#changelist-filter details summary > * { + display: inline; +} + +#changelist-filter details > summary { + list-style-type: none; +} + +#changelist-filter details > summary::-webkit-details-marker { + display: none; +} + +#changelist-filter details > summary::before { + content: '→'; + font-weight: bold; + color: var(--link-hover-color); +} + +#changelist-filter details[open] > summary::before { + content: '↓'; +} + +#changelist-filter ul { + margin: 5px 0; + padding: 0 15px 15px; + border-bottom: 1px solid var(--hairline-color); +} + +#changelist-filter ul:last-child { + border-bottom: none; +} + +#changelist-filter li { + list-style-type: none; + margin-left: 0; + padding-left: 0; +} + +#changelist-filter a { + display: block; + color: var(--body-quiet-color); + word-break: break-word; +} + +#changelist-filter li.selected { + border-left: 5px solid var(--hairline-color); + padding-left: 10px; + margin-left: -15px; +} + +#changelist-filter li.selected a { + color: var(--link-selected-fg); +} + +#changelist-filter a:focus, #changelist-filter a:hover, +#changelist-filter li.selected a:focus, +#changelist-filter li.selected a:hover { + color: var(--link-hover-color); +} + +#changelist-filter #changelist-filter-clear a { + font-size: 0.8125rem; + padding-bottom: 10px; + border-bottom: 1px solid var(--hairline-color); +} + +/* DATE DRILLDOWN */ + +.change-list .toplinks { + display: flex; + padding-bottom: 5px; + flex-wrap: wrap; + gap: 3px 17px; + font-weight: bold; +} + +.change-list .toplinks a { + font-size: 0.8125rem; +} + +.change-list .toplinks .date-back { + color: var(--body-quiet-color); +} + +.change-list .toplinks .date-back:focus, +.change-list .toplinks .date-back:hover { + color: var(--link-hover-color); +} + +/* ACTIONS */ + +.filtered .actions { + border-right: none; +} + +#changelist table input { + margin: 0; + vertical-align: baseline; +} + +/* Once the :has() pseudo-class is supported by all browsers, the tr.selected + selector and the JS adding the class can be removed. */ +#changelist tbody tr.selected { + background-color: var(--selected-row); +} + +#changelist tbody tr:has(.action-select:checked) { + background-color: var(--selected-row); +} + +#changelist .actions { + padding: 10px; + background: var(--body-bg); + border-top: none; + border-bottom: none; + line-height: 1.5rem; + color: var(--body-quiet-color); + width: 100%; +} + +#changelist .actions span.all, +#changelist .actions span.action-counter, +#changelist .actions span.clear, +#changelist .actions span.question { + font-size: 0.8125rem; + margin: 0 0.5em; +} + +#changelist .actions:last-child { + border-bottom: none; +} + +#changelist .actions select { + vertical-align: top; + height: 1.5rem; + color: var(--body-fg); + border: 1px solid var(--border-color); + border-radius: 4px; + font-size: 0.875rem; + padding: 0 0 0 4px; + margin: 0; + margin-left: 10px; +} + +#changelist .actions select:focus { + border-color: var(--body-quiet-color); +} + +#changelist .actions label { + display: inline-block; + vertical-align: middle; + font-size: 0.8125rem; +} + +#changelist .actions .button { + font-size: 0.8125rem; + border: 1px solid var(--border-color); + border-radius: 4px; + background: var(--body-bg); + box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; + cursor: pointer; + height: 1.5rem; + line-height: 1; + padding: 4px 8px; + margin: 0; + color: var(--body-fg); +} + +#changelist .actions .button:focus, #changelist .actions .button:hover { + border-color: var(--body-quiet-color); +} diff --git a/staticfiles/admin/css/dark_mode.css b/staticfiles/admin/css/dark_mode.css new file mode 100644 index 0000000..6d08233 --- /dev/null +++ b/staticfiles/admin/css/dark_mode.css @@ -0,0 +1,137 @@ +@media (prefers-color-scheme: dark) { + :root { + --primary: #264b5d; + --primary-fg: #f7f7f7; + + --body-fg: #eeeeee; + --body-bg: #121212; + --body-quiet-color: #e0e0e0; + --body-loud-color: #ffffff; + + --breadcrumbs-link-fg: #e0e0e0; + --breadcrumbs-bg: var(--primary); + + --link-fg: #81d4fa; + --link-hover-color: #4ac1f7; + --link-selected-fg: #6f94c6; + + --hairline-color: #272727; + --border-color: #353535; + + --error-fg: #e35f5f; + --message-success-bg: #006b1b; + --message-warning-bg: #583305; + --message-error-bg: #570808; + + --darkened-bg: #212121; + --selected-bg: #1b1b1b; + --selected-row: #00363a; + + --close-button-bg: #333333; + --close-button-hover-bg: #666666; + } + } + + +html[data-theme="dark"] { + --primary: #264b5d; + --primary-fg: #f7f7f7; + + --body-fg: #eeeeee; + --body-bg: #121212; + --body-quiet-color: #e0e0e0; + --body-loud-color: #ffffff; + + --breadcrumbs-link-fg: #e0e0e0; + --breadcrumbs-bg: var(--primary); + + --link-fg: #81d4fa; + --link-hover-color: #4ac1f7; + --link-selected-fg: #6f94c6; + + --hairline-color: #272727; + --border-color: #353535; + + --error-fg: #e35f5f; + --message-success-bg: #006b1b; + --message-warning-bg: #583305; + --message-error-bg: #570808; + + --darkened-bg: #212121; + --selected-bg: #1b1b1b; + --selected-row: #00363a; + + --close-button-bg: #333333; + --close-button-hover-bg: #666666; +} + +/* THEME SWITCH */ +.theme-toggle { + cursor: pointer; + border: none; + padding: 0; + background: transparent; + vertical-align: middle; + margin-inline-start: 5px; + margin-top: -1px; +} + +.theme-toggle svg { + vertical-align: middle; + height: 1rem; + width: 1rem; + display: none; +} + +/* +Fully hide screen reader text so we only show the one matching the current +theme. +*/ +.theme-toggle .visually-hidden { + display: none; +} + +html[data-theme="auto"] .theme-toggle .theme-label-when-auto { + display: block; +} + +html[data-theme="dark"] .theme-toggle .theme-label-when-dark { + display: block; +} + +html[data-theme="light"] .theme-toggle .theme-label-when-light { + display: block; +} + +/* ICONS */ +.theme-toggle svg.theme-icon-when-auto, +.theme-toggle svg.theme-icon-when-dark, +.theme-toggle svg.theme-icon-when-light { + fill: var(--header-link-color); + color: var(--header-bg); +} + +html[data-theme="auto"] .theme-toggle svg.theme-icon-when-auto { + display: block; +} + +html[data-theme="dark"] .theme-toggle svg.theme-icon-when-dark { + display: block; +} + +html[data-theme="light"] .theme-toggle svg.theme-icon-when-light { + display: block; +} + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0,0,0,0); + white-space: nowrap; + border: 0; + color: var(--body-fg); + background-color: var(--body-bg); +} diff --git a/staticfiles/admin/css/dashboard.css b/staticfiles/admin/css/dashboard.css new file mode 100644 index 0000000..242b81a --- /dev/null +++ b/staticfiles/admin/css/dashboard.css @@ -0,0 +1,29 @@ +/* DASHBOARD */ +.dashboard td, .dashboard th { + word-break: break-word; +} + +.dashboard .module table th { + width: 100%; +} + +.dashboard .module table td { + white-space: nowrap; +} + +.dashboard .module table td a { + display: block; + padding-right: .6em; +} + +/* RECENT ACTIONS MODULE */ + +.module ul.actionlist { + margin-left: 0; +} + +ul.actionlist li { + list-style-type: none; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/staticfiles/admin/css/forms.css b/staticfiles/admin/css/forms.css new file mode 100644 index 0000000..9a8dad0 --- /dev/null +++ b/staticfiles/admin/css/forms.css @@ -0,0 +1,534 @@ +@import url('widgets.css'); + +/* FORM ROWS */ + +.form-row { + overflow: hidden; + padding: 10px; + font-size: 0.8125rem; + border-bottom: 1px solid var(--hairline-color); +} + +.form-row img, .form-row input { + vertical-align: middle; +} + +.form-row label input[type="checkbox"] { + margin-top: 0; + vertical-align: 0; +} + +form .form-row p { + padding-left: 0; +} + +.flex-container { + display: flex; +} + +.form-multiline { + flex-wrap: wrap; +} + +.form-multiline > div { + padding-bottom: 10px; +} + +/* FORM LABELS */ + +label { + font-weight: normal; + color: var(--body-quiet-color); + font-size: 0.8125rem; +} + +.required label, label.required { + font-weight: bold; + color: var(--body-fg); +} + +/* RADIO BUTTONS */ + +form div.radiolist div { + padding-right: 7px; +} + +form div.radiolist.inline div { + display: inline-block; +} + +form div.radiolist label { + width: auto; +} + +form div.radiolist input[type="radio"] { + margin: -2px 4px 0 0; + padding: 0; +} + +form ul.inline { + margin-left: 0; + padding: 0; +} + +form ul.inline li { + float: left; + padding-right: 7px; +} + +/* ALIGNED FIELDSETS */ + +.aligned label { + display: block; + padding: 4px 10px 0 0; + min-width: 160px; + width: 160px; + word-wrap: break-word; + line-height: 1; +} + +.aligned label:not(.vCheckboxLabel):after { + content: ''; + display: inline-block; + vertical-align: middle; + height: 1.625rem; +} + +.aligned label + p, .aligned .checkbox-row + div.help, .aligned label + div.readonly { + padding: 6px 0; + margin-top: 0; + margin-bottom: 0; + margin-left: 0; + overflow-wrap: break-word; +} + +.aligned ul label { + display: inline; + float: none; + width: auto; +} + +.aligned .form-row input { + margin-bottom: 0; +} + +.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { + width: 350px; +} + +form .aligned ul { + margin-left: 160px; + padding-left: 10px; +} + +form .aligned div.radiolist { + display: inline-block; + margin: 0; + padding: 0; +} + +form .aligned p.help, +form .aligned div.help { + margin-top: 0; + margin-left: 160px; + padding-left: 10px; +} + +form .aligned p.date div.help.timezonewarning, +form .aligned p.datetime div.help.timezonewarning, +form .aligned p.time div.help.timezonewarning { + margin-left: 0; + padding-left: 0; + font-weight: normal; +} + +form .aligned p.help:last-child, +form .aligned div.help:last-child { + margin-bottom: 0; + padding-bottom: 0; +} + +form .aligned input + p.help, +form .aligned textarea + p.help, +form .aligned select + p.help, +form .aligned input + div.help, +form .aligned textarea + div.help, +form .aligned select + div.help { + margin-left: 160px; + padding-left: 10px; +} + +form .aligned ul li { + list-style: none; +} + +form .aligned table p { + margin-left: 0; + padding-left: 0; +} + +.aligned .vCheckboxLabel { + float: none; + width: auto; + display: inline-block; + vertical-align: -3px; + padding: 0 0 5px 5px; +} + +.aligned .vCheckboxLabel + p.help, +.aligned .vCheckboxLabel + div.help { + margin-top: -4px; +} + +.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { + width: 610px; +} + +fieldset .fieldBox { + margin-right: 20px; +} + +/* WIDE FIELDSETS */ + +.wide label { + width: 200px; +} + +form .wide p, +form .wide ul.errorlist, +form .wide input + p.help, +form .wide input + div.help { + margin-left: 200px; +} + +form .wide p.help, +form .wide div.help { + padding-left: 50px; +} + +form div.help ul { + padding-left: 0; + margin-left: 0; +} + +.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { + width: 450px; +} + +/* COLLAPSED FIELDSETS */ + +fieldset.collapsed * { + display: none; +} + +fieldset.collapsed h2, fieldset.collapsed { + display: block; +} + +fieldset.collapsed { + border: 1px solid var(--hairline-color); + border-radius: 4px; + overflow: hidden; +} + +fieldset.collapsed h2 { + background: var(--darkened-bg); + color: var(--body-quiet-color); +} + +fieldset .collapse-toggle { + color: var(--header-link-color); +} + +fieldset.collapsed .collapse-toggle { + background: transparent; + display: inline; + color: var(--link-fg); +} + +/* MONOSPACE TEXTAREAS */ + +fieldset.monospace textarea { + font-family: var(--font-family-monospace); +} + +/* SUBMIT ROW */ + +.submit-row { + padding: 12px 14px 12px; + margin: 0 0 20px; + background: var(--darkened-bg); + border: 1px solid var(--hairline-color); + border-radius: 4px; + overflow: hidden; + display: flex; + gap: 10px; + flex-wrap: wrap; +} + +body.popup .submit-row { + overflow: auto; +} + +.submit-row input { + height: 2.1875rem; + line-height: 0.9375rem; +} + +.submit-row input, .submit-row a { + margin: 0; +} + +.submit-row input.default { + text-transform: uppercase; +} + +.submit-row a.deletelink { + margin-left: auto; +} + +.submit-row a.deletelink { + display: block; + background: var(--delete-button-bg); + border-radius: 4px; + padding: 0.625rem 0.9375rem; + height: 0.9375rem; + line-height: 0.9375rem; + color: var(--button-fg); +} + +.submit-row a.closelink { + display: inline-block; + background: var(--close-button-bg); + border-radius: 4px; + padding: 10px 15px; + height: 0.9375rem; + line-height: 0.9375rem; + color: var(--button-fg); +} + +.submit-row a.deletelink:focus, +.submit-row a.deletelink:hover, +.submit-row a.deletelink:active { + background: var(--delete-button-hover-bg); + text-decoration: none; +} + +.submit-row a.closelink:focus, +.submit-row a.closelink:hover, +.submit-row a.closelink:active { + background: var(--close-button-hover-bg); + text-decoration: none; +} + +/* CUSTOM FORM FIELDS */ + +.vSelectMultipleField { + vertical-align: top; +} + +.vCheckboxField { + border: none; +} + +.vDateField, .vTimeField { + margin-right: 2px; + margin-bottom: 4px; +} + +.vDateField { + min-width: 6.85em; +} + +.vTimeField { + min-width: 4.7em; +} + +.vURLField { + width: 30em; +} + +.vLargeTextField, .vXMLLargeTextField { + width: 48em; +} + +.flatpages-flatpage #id_content { + height: 40.2em; +} + +.module table .vPositiveSmallIntegerField { + width: 2.2em; +} + +.vIntegerField { + width: 5em; +} + +.vBigIntegerField { + width: 10em; +} + +.vForeignKeyRawIdAdminField { + width: 5em; +} + +.vTextField, .vUUIDField { + width: 20em; +} + +/* INLINES */ + +.inline-group { + padding: 0; + margin: 0 0 30px; +} + +.inline-group thead th { + padding: 8px 10px; +} + +.inline-group .aligned label { + width: 160px; +} + +.inline-related { + position: relative; +} + +.inline-related h3 { + margin: 0; + color: var(--body-quiet-color); + padding: 5px; + font-size: 0.8125rem; + background: var(--darkened-bg); + border-top: 1px solid var(--hairline-color); + border-bottom: 1px solid var(--hairline-color); +} + +.inline-related h3 span.delete { + float: right; +} + +.inline-related h3 span.delete label { + margin-left: 2px; + font-size: 0.6875rem; +} + +.inline-related fieldset { + margin: 0; + background: var(--body-bg); + border: none; + width: 100%; +} + +.inline-related fieldset.module h3 { + margin: 0; + padding: 2px 5px 3px 5px; + font-size: 0.6875rem; + text-align: left; + font-weight: bold; + background: #bcd; + color: var(--body-bg); +} + +.inline-group .tabular fieldset.module { + border: none; +} + +.inline-related.tabular fieldset.module table { + width: 100%; + overflow-x: scroll; +} + +.last-related fieldset { + border: none; +} + +.inline-group .tabular tr.has_original td { + padding-top: 2em; +} + +.inline-group .tabular tr td.original { + padding: 2px 0 0 0; + width: 0; + _position: relative; +} + +.inline-group .tabular th.original { + width: 0px; + padding: 0; +} + +.inline-group .tabular td.original p { + position: absolute; + left: 0; + height: 1.1em; + padding: 2px 9px; + overflow: hidden; + font-size: 0.5625rem; + font-weight: bold; + color: var(--body-quiet-color); + _width: 700px; +} + +.inline-group ul.tools { + padding: 0; + margin: 0; + list-style: none; +} + +.inline-group ul.tools li { + display: inline; + padding: 0 5px; +} + +.inline-group div.add-row, +.inline-group .tabular tr.add-row td { + color: var(--body-quiet-color); + background: var(--darkened-bg); + padding: 8px 10px; + border-bottom: 1px solid var(--hairline-color); +} + +.inline-group .tabular tr.add-row td { + padding: 8px 10px; + border-bottom: 1px solid var(--hairline-color); +} + +.inline-group ul.tools a.add, +.inline-group div.add-row a, +.inline-group .tabular tr.add-row td a { + background: url(../img/icon-addlink.svg) 0 1px no-repeat; + padding-left: 16px; + font-size: 0.75rem; +} + +.empty-form { + display: none; +} + +/* RELATED FIELD ADD ONE / LOOKUP */ + +.related-lookup { + margin-left: 5px; + display: inline-block; + vertical-align: middle; + background-repeat: no-repeat; + background-size: 14px; +} + +.related-lookup { + width: 1rem; + height: 1rem; + background-image: url(../img/search.svg); +} + +form .related-widget-wrapper ul { + display: inline-block; + margin-left: 0; + padding-left: 0; +} + +.clearable-file-input input { + margin-top: 0; +} diff --git a/staticfiles/admin/css/login.css b/staticfiles/admin/css/login.css new file mode 100644 index 0000000..389772f --- /dev/null +++ b/staticfiles/admin/css/login.css @@ -0,0 +1,61 @@ +/* LOGIN FORM */ + +.login { + background: var(--darkened-bg); + height: auto; +} + +.login #header { + height: auto; + padding: 15px 16px; + justify-content: center; +} + +.login #header h1 { + font-size: 1.125rem; + margin: 0; +} + +.login #header h1 a { + color: var(--header-link-color); +} + +.login #content { + padding: 20px 20px 0; +} + +.login #container { + background: var(--body-bg); + border: 1px solid var(--hairline-color); + border-radius: 4px; + overflow: hidden; + width: 28em; + min-width: 300px; + margin: 100px auto; + height: auto; +} + +.login .form-row { + padding: 4px 0; +} + +.login .form-row label { + display: block; + line-height: 2em; +} + +.login .form-row #id_username, .login .form-row #id_password { + padding: 8px; + width: 100%; + box-sizing: border-box; +} + +.login .submit-row { + padding: 1em 0 0 0; + margin: 0; + text-align: center; +} + +.login .password-reset-link { + text-align: center; +} diff --git a/staticfiles/admin/css/nav_sidebar.css b/staticfiles/admin/css/nav_sidebar.css new file mode 100644 index 0000000..f76e6ce --- /dev/null +++ b/staticfiles/admin/css/nav_sidebar.css @@ -0,0 +1,144 @@ +.sticky { + position: sticky; + top: 0; + max-height: 100vh; +} + +.toggle-nav-sidebar { + z-index: 20; + left: 0; + display: flex; + align-items: center; + justify-content: center; + flex: 0 0 23px; + width: 23px; + border: 0; + border-right: 1px solid var(--hairline-color); + background-color: var(--body-bg); + cursor: pointer; + font-size: 1.25rem; + color: var(--link-fg); + padding: 0; +} + +[dir="rtl"] .toggle-nav-sidebar { + border-left: 1px solid var(--hairline-color); + border-right: 0; +} + +.toggle-nav-sidebar:hover, +.toggle-nav-sidebar:focus { + background-color: var(--darkened-bg); +} + +#nav-sidebar { + z-index: 15; + flex: 0 0 275px; + left: -276px; + margin-left: -276px; + border-top: 1px solid transparent; + border-right: 1px solid var(--hairline-color); + background-color: var(--body-bg); + overflow: auto; +} + +[dir="rtl"] #nav-sidebar { + border-left: 1px solid var(--hairline-color); + border-right: 0; + left: 0; + margin-left: 0; + right: -276px; + margin-right: -276px; +} + +.toggle-nav-sidebar::before { + content: '\00BB'; +} + +.main.shifted .toggle-nav-sidebar::before { + content: '\00AB'; +} + +.main > #nav-sidebar { + visibility: hidden; +} + +.main.shifted > #nav-sidebar { + margin-left: 0; + visibility: visible; +} + +[dir="rtl"] .main.shifted > #nav-sidebar { + margin-right: 0; +} + +#nav-sidebar .module th { + width: 100%; + overflow-wrap: anywhere; +} + +#nav-sidebar .module th, +#nav-sidebar .module caption { + padding-left: 16px; +} + +#nav-sidebar .module td { + white-space: nowrap; +} + +[dir="rtl"] #nav-sidebar .module th, +[dir="rtl"] #nav-sidebar .module caption { + padding-left: 8px; + padding-right: 16px; +} + +#nav-sidebar .current-app .section:link, +#nav-sidebar .current-app .section:visited { + color: var(--header-color); + font-weight: bold; +} + +#nav-sidebar .current-model { + background: var(--selected-row); +} + +.main > #nav-sidebar + .content { + max-width: calc(100% - 23px); +} + +.main.shifted > #nav-sidebar + .content { + max-width: calc(100% - 299px); +} + +@media (max-width: 767px) { + #nav-sidebar, #toggle-nav-sidebar { + display: none; + } + + .main > #nav-sidebar + .content, + .main.shifted > #nav-sidebar + .content { + max-width: 100%; + } +} + +#nav-filter { + width: 100%; + box-sizing: border-box; + padding: 2px 5px; + margin: 5px 0; + border: 1px solid var(--border-color); + background-color: var(--darkened-bg); + color: var(--body-fg); +} + +#nav-filter:focus { + border-color: var(--body-quiet-color); +} + +#nav-filter.no-results { + background: var(--message-error-bg); +} + +#nav-sidebar table { + width: 100%; +} diff --git a/staticfiles/admin/css/responsive.css b/staticfiles/admin/css/responsive.css new file mode 100644 index 0000000..1d0a188 --- /dev/null +++ b/staticfiles/admin/css/responsive.css @@ -0,0 +1,999 @@ +/* Tablets */ + +input[type="submit"], button { + -webkit-appearance: none; + appearance: none; +} + +@media (max-width: 1024px) { + /* Basic */ + + html { + -webkit-text-size-adjust: 100%; + } + + td, th { + padding: 10px; + font-size: 0.875rem; + } + + .small { + font-size: 0.75rem; + } + + /* Layout */ + + #container { + min-width: 0; + } + + #content { + padding: 15px 20px 20px; + } + + div.breadcrumbs { + padding: 10px 30px; + } + + /* Header */ + + #header { + flex-direction: column; + padding: 15px 30px; + justify-content: flex-start; + } + + #branding h1 { + margin: 0 0 8px; + line-height: 1.2; + } + + #user-tools { + margin: 0; + font-weight: 400; + line-height: 1.85; + text-align: left; + } + + #user-tools a { + display: inline-block; + line-height: 1.4; + } + + /* Dashboard */ + + .dashboard #content { + width: auto; + } + + #content-related { + margin-right: -290px; + } + + .colSM #content-related { + margin-left: -290px; + } + + .colMS { + margin-right: 290px; + } + + .colSM { + margin-left: 290px; + } + + .dashboard .module table td a { + padding-right: 0; + } + + td .changelink, td .addlink { + font-size: 0.8125rem; + } + + /* Changelist */ + + #toolbar { + border: none; + padding: 15px; + } + + #changelist-search > div { + display: flex; + flex-wrap: nowrap; + max-width: 480px; + } + + #changelist-search label { + line-height: 1.375rem; + } + + #toolbar form #searchbar { + flex: 1 0 auto; + width: 0; + height: 1.375rem; + margin: 0 10px 0 6px; + } + + #toolbar form input[type=submit] { + flex: 0 1 auto; + } + + #changelist-search .quiet { + width: 0; + flex: 1 0 auto; + margin: 5px 0 0 25px; + } + + #changelist .actions { + display: flex; + flex-wrap: wrap; + padding: 15px 0; + } + + #changelist .actions label { + display: flex; + } + + #changelist .actions select { + background: var(--body-bg); + } + + #changelist .actions .button { + min-width: 48px; + margin: 0 10px; + } + + #changelist .actions span.all, + #changelist .actions span.clear, + #changelist .actions span.question, + #changelist .actions span.action-counter { + font-size: 0.6875rem; + margin: 0 10px 0 0; + } + + #changelist-filter { + flex-basis: 200px; + } + + .change-list .filtered .results, + .change-list .filtered .paginator, + .filtered #toolbar, + .filtered .actions, + + #changelist .paginator { + border-top-color: var(--hairline-color); /* XXX Is this used at all? */ + } + + #changelist .results + .paginator { + border-top: none; + } + + /* Forms */ + + label { + font-size: 0.875rem; + } + + .form-row input[type=text], + .form-row input[type=password], + .form-row input[type=email], + .form-row input[type=url], + .form-row input[type=tel], + .form-row input[type=number], + .form-row textarea, + .form-row select, + .form-row .vTextField { + box-sizing: border-box; + margin: 0; + padding: 6px 8px; + min-height: 2.25rem; + font-size: 0.875rem; + } + + .form-row select { + height: 2.25rem; + } + + .form-row select[multiple] { + height: auto; + min-height: 0; + } + + fieldset .fieldBox + .fieldBox { + margin-top: 10px; + padding-top: 10px; + border-top: 1px solid var(--hairline-color); + } + + textarea { + max-width: 100%; + max-height: 120px; + } + + .aligned label { + padding-top: 6px; + } + + .aligned .related-lookup, + .aligned .datetimeshortcuts, + .aligned .related-lookup + strong { + align-self: center; + margin-left: 15px; + } + + form .aligned div.radiolist { + margin-left: 2px; + } + + .submit-row { + padding: 8px; + } + + .submit-row a.deletelink { + padding: 10px 7px; + } + + .button, input[type=submit], input[type=button], .submit-row input, a.button { + padding: 7px; + } + + /* Related widget */ + + .related-widget-wrapper { + float: none; + } + + .related-widget-wrapper-link + .selector { + max-width: calc(100% - 30px); + margin-right: 15px; + } + + select + .related-widget-wrapper-link, + .related-widget-wrapper-link + .related-widget-wrapper-link { + margin-left: 10px; + } + + /* Selector */ + + .selector { + display: flex; + width: 100%; + } + + .selector .selector-filter { + display: flex; + align-items: center; + } + + .selector .selector-filter label { + margin: 0 8px 0 0; + } + + .selector .selector-filter input { + width: auto; + min-height: 0; + flex: 1 1; + } + + .selector-available, .selector-chosen { + width: auto; + flex: 1 1; + display: flex; + flex-direction: column; + } + + .selector select { + width: 100%; + flex: 1 0 auto; + margin-bottom: 5px; + } + + .selector ul.selector-chooser { + width: 26px; + height: 52px; + padding: 2px 0; + margin: auto 15px; + border-radius: 20px; + transform: translateY(-10px); + } + + .selector-add, .selector-remove { + width: 20px; + height: 20px; + background-size: 20px auto; + } + + .selector-add { + background-position: 0 -120px; + } + + .selector-remove { + background-position: 0 -80px; + } + + a.selector-chooseall, a.selector-clearall { + align-self: center; + } + + .stacked { + flex-direction: column; + max-width: 480px; + } + + .stacked > * { + flex: 0 1 auto; + } + + .stacked select { + margin-bottom: 0; + } + + .stacked .selector-available, .stacked .selector-chosen { + width: auto; + } + + .stacked ul.selector-chooser { + width: 52px; + height: 26px; + padding: 0 2px; + margin: 15px auto; + transform: none; + } + + .stacked .selector-chooser li { + padding: 3px; + } + + .stacked .selector-add, .stacked .selector-remove { + background-size: 20px auto; + } + + .stacked .selector-add { + background-position: 0 -40px; + } + + .stacked .active.selector-add { + background-position: 0 -40px; + } + + .active.selector-add:focus, .active.selector-add:hover { + background-position: 0 -140px; + } + + .stacked .active.selector-add:focus, .stacked .active.selector-add:hover { + background-position: 0 -60px; + } + + .stacked .selector-remove { + background-position: 0 0; + } + + .stacked .active.selector-remove { + background-position: 0 0; + } + + .active.selector-remove:focus, .active.selector-remove:hover { + background-position: 0 -100px; + } + + .stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover { + background-position: 0 -20px; + } + + .help-tooltip, .selector .help-icon { + display: none; + } + + .datetime input { + width: 50%; + max-width: 120px; + } + + .datetime span { + font-size: 0.8125rem; + } + + .datetime .timezonewarning { + display: block; + font-size: 0.6875rem; + color: var(--body-quiet-color); + } + + .datetimeshortcuts { + color: var(--border-color); /* XXX Redundant, .datetime span also sets #ccc */ + } + + .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField { + width: 75%; + } + + .inline-group { + overflow: auto; + } + + /* Messages */ + + ul.messagelist li { + padding-left: 55px; + background-position: 30px 12px; + } + + ul.messagelist li.error { + background-position: 30px 12px; + } + + ul.messagelist li.warning { + background-position: 30px 14px; + } + + /* Login */ + + .login #header { + padding: 15px 20px; + } + + .login #branding h1 { + margin: 0; + } + + /* GIS */ + + div.olMap { + max-width: calc(100vw - 30px); + max-height: 300px; + } + + .olMap + .clear_features { + display: block; + margin-top: 10px; + } + + /* Docs */ + + .module table.xfull { + width: 100%; + } + + pre.literal-block { + overflow: auto; + } +} + +/* Mobile */ + +@media (max-width: 767px) { + /* Layout */ + + #header, #content, #footer { + padding: 15px; + } + + #footer:empty { + padding: 0; + } + + div.breadcrumbs { + padding: 10px 15px; + } + + /* Dashboard */ + + .colMS, .colSM { + margin: 0; + } + + #content-related, .colSM #content-related { + width: 100%; + margin: 0; + } + + #content-related .module { + margin-bottom: 0; + } + + #content-related .module h2 { + padding: 10px 15px; + font-size: 1rem; + } + + /* Changelist */ + + #changelist { + align-items: stretch; + flex-direction: column; + } + + #toolbar { + padding: 10px; + } + + #changelist-filter { + margin-left: 0; + } + + #changelist .actions label { + flex: 1 1; + } + + #changelist .actions select { + flex: 1 0; + width: 100%; + } + + #changelist .actions span { + flex: 1 0 100%; + } + + #changelist-filter { + position: static; + width: auto; + margin-top: 30px; + } + + .object-tools { + float: none; + margin: 0 0 15px; + padding: 0; + overflow: hidden; + } + + .object-tools li { + height: auto; + margin-left: 0; + } + + .object-tools li + li { + margin-left: 15px; + } + + /* Forms */ + + .form-row { + padding: 15px 0; + } + + .aligned .form-row, + .aligned .form-row > div { + max-width: 100vw; + } + + .aligned .form-row > div { + width: calc(100vw - 30px); + } + + .flex-container { + flex-flow: column; + } + + .flex-container.checkbox-row { + flex-flow: row; + } + + textarea { + max-width: none; + } + + .vURLField { + width: auto; + } + + fieldset .fieldBox + .fieldBox { + margin-top: 15px; + padding-top: 15px; + } + + fieldset.collapsed .form-row { + display: none; + } + + .aligned label { + width: 100%; + min-width: auto; + padding: 0 0 10px; + } + + .aligned label:after { + max-height: 0; + } + + .aligned .form-row input, + .aligned .form-row select, + .aligned .form-row textarea { + flex: 1 1 auto; + max-width: 100%; + } + + .aligned .checkbox-row input { + flex: 0 1 auto; + margin: 0; + } + + .aligned .vCheckboxLabel { + flex: 1 0; + padding: 1px 0 0 5px; + } + + .aligned label + p, + .aligned label + div.help, + .aligned label + div.readonly { + padding: 0; + margin-left: 0; + } + + .aligned p.file-upload { + font-size: 0.8125rem; + } + + span.clearable-file-input { + margin-left: 15px; + } + + span.clearable-file-input label { + font-size: 0.8125rem; + padding-bottom: 0; + } + + .aligned .timezonewarning { + flex: 1 0 100%; + margin-top: 5px; + } + + form .aligned .form-row div.help { + width: 100%; + margin: 5px 0 0; + padding: 0; + } + + form .aligned ul, + form .aligned ul.errorlist { + margin-left: 0; + padding-left: 0; + } + + form .aligned div.radiolist { + margin-top: 5px; + margin-right: 15px; + margin-bottom: -3px; + } + + form .aligned div.radiolist:not(.inline) div + div { + margin-top: 5px; + } + + /* Related widget */ + + .related-widget-wrapper { + width: 100%; + display: flex; + align-items: flex-start; + } + + .related-widget-wrapper .selector { + order: 1; + } + + .related-widget-wrapper > a { + order: 2; + } + + .related-widget-wrapper .radiolist ~ a { + align-self: flex-end; + } + + .related-widget-wrapper > select ~ a { + align-self: center; + } + + select + .related-widget-wrapper-link, + .related-widget-wrapper-link + .related-widget-wrapper-link { + margin-left: 15px; + } + + /* Selector */ + + .selector { + flex-direction: column; + } + + .selector > * { + float: none; + } + + .selector-available, .selector-chosen { + margin-bottom: 0; + flex: 1 1 auto; + } + + .selector select { + max-height: 96px; + } + + .selector ul.selector-chooser { + display: block; + float: none; + width: 52px; + height: 26px; + padding: 0 2px; + margin: 15px auto 20px; + transform: none; + } + + .selector ul.selector-chooser li { + float: left; + } + + .selector-remove { + background-position: 0 0; + } + + .active.selector-remove:focus, .active.selector-remove:hover { + background-position: 0 -20px; + } + + .selector-add { + background-position: 0 -40px; + } + + .active.selector-add:focus, .active.selector-add:hover { + background-position: 0 -60px; + } + + /* Inlines */ + + .inline-group[data-inline-type="stacked"] .inline-related { + border: 1px solid var(--hairline-color); + border-radius: 4px; + margin-top: 15px; + overflow: auto; + } + + .inline-group[data-inline-type="stacked"] .inline-related > * { + box-sizing: border-box; + } + + .inline-group[data-inline-type="stacked"] .inline-related .module { + padding: 0 10px; + } + + .inline-group[data-inline-type="stacked"] .inline-related .module .form-row { + border-top: 1px solid var(--hairline-color); + border-bottom: none; + } + + .inline-group[data-inline-type="stacked"] .inline-related .module .form-row:first-child { + border-top: none; + } + + .inline-group[data-inline-type="stacked"] .inline-related h3 { + padding: 10px; + border-top-width: 0; + border-bottom-width: 2px; + display: flex; + flex-wrap: wrap; + align-items: center; + } + + .inline-group[data-inline-type="stacked"] .inline-related h3 .inline_label { + margin-right: auto; + } + + .inline-group[data-inline-type="stacked"] .inline-related h3 span.delete { + float: none; + flex: 1 1 100%; + margin-top: 5px; + } + + .inline-group[data-inline-type="stacked"] .aligned .form-row > div:not([class]) { + width: 100%; + } + + .inline-group[data-inline-type="stacked"] .aligned label { + width: 100%; + } + + .inline-group[data-inline-type="stacked"] div.add-row { + margin-top: 15px; + border: 1px solid var(--hairline-color); + border-radius: 4px; + } + + .inline-group div.add-row, + .inline-group .tabular tr.add-row td { + padding: 0; + } + + .inline-group div.add-row a, + .inline-group .tabular tr.add-row td a { + display: block; + padding: 8px 10px 8px 26px; + background-position: 8px 9px; + } + + /* Submit row */ + + .submit-row { + padding: 10px; + margin: 0 0 15px; + flex-direction: column; + gap: 8px; + } + + .submit-row input, .submit-row input.default, .submit-row a { + text-align: center; + } + + .submit-row a.closelink { + padding: 10px 0; + text-align: center; + } + + .submit-row a.deletelink { + margin: 0; + } + + /* Messages */ + + ul.messagelist li { + padding-left: 40px; + background-position: 15px 12px; + } + + ul.messagelist li.error { + background-position: 15px 12px; + } + + ul.messagelist li.warning { + background-position: 15px 14px; + } + + /* Paginator */ + + .paginator .this-page, .paginator a:link, .paginator a:visited { + padding: 4px 10px; + } + + /* Login */ + + body.login { + padding: 0 15px; + } + + .login #container { + width: auto; + max-width: 480px; + margin: 50px auto; + } + + .login #header, + .login #content { + padding: 15px; + } + + .login #content-main { + float: none; + } + + .login .form-row { + padding: 0; + } + + .login .form-row + .form-row { + margin-top: 15px; + } + + .login .form-row label { + margin: 0 0 5px; + line-height: 1.2; + } + + .login .submit-row { + padding: 15px 0 0; + } + + .login br { + display: none; + } + + .login .submit-row input { + margin: 0; + text-transform: uppercase; + } + + .errornote { + margin: 0 0 20px; + padding: 8px 12px; + font-size: 0.8125rem; + } + + /* Calendar and clock */ + + .calendarbox, .clockbox { + position: fixed !important; + top: 50% !important; + left: 50% !important; + transform: translate(-50%, -50%); + margin: 0; + border: none; + overflow: visible; + } + + .calendarbox:before, .clockbox:before { + content: ''; + position: fixed; + top: 50%; + left: 50%; + width: 100vw; + height: 100vh; + background: rgba(0, 0, 0, 0.75); + transform: translate(-50%, -50%); + } + + .calendarbox > *, .clockbox > * { + position: relative; + z-index: 1; + } + + .calendarbox > div:first-child { + z-index: 2; + } + + .calendarbox .calendar, .clockbox h2 { + border-radius: 4px 4px 0 0; + overflow: hidden; + } + + .calendarbox .calendar-cancel, .clockbox .calendar-cancel { + border-radius: 0 0 4px 4px; + overflow: hidden; + } + + .calendar-shortcuts { + padding: 10px 0; + font-size: 0.75rem; + line-height: 0.75rem; + } + + .calendar-shortcuts a { + margin: 0 4px; + } + + .timelist a { + background: var(--body-bg); + padding: 4px; + } + + .calendar-cancel { + padding: 8px 10px; + } + + .clockbox h2 { + padding: 8px 15px; + } + + .calendar caption { + padding: 10px; + } + + .calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { + z-index: 1; + top: 10px; + } + + /* History */ + + table#change-history tbody th, table#change-history tbody td { + font-size: 0.8125rem; + word-break: break-word; + } + + table#change-history tbody th { + width: auto; + } + + /* Docs */ + + table.model tbody th, table.model tbody td { + font-size: 0.8125rem; + word-break: break-word; + } +} diff --git a/staticfiles/admin/css/responsive_rtl.css b/staticfiles/admin/css/responsive_rtl.css new file mode 100644 index 0000000..31dc8ff --- /dev/null +++ b/staticfiles/admin/css/responsive_rtl.css @@ -0,0 +1,84 @@ +/* TABLETS */ + +@media (max-width: 1024px) { + [dir="rtl"] .colMS { + margin-right: 0; + } + + [dir="rtl"] #user-tools { + text-align: right; + } + + [dir="rtl"] #changelist .actions label { + padding-left: 10px; + padding-right: 0; + } + + [dir="rtl"] #changelist .actions select { + margin-left: 0; + margin-right: 15px; + } + + [dir="rtl"] .change-list .filtered .results, + [dir="rtl"] .change-list .filtered .paginator, + [dir="rtl"] .filtered #toolbar, + [dir="rtl"] .filtered div.xfull, + [dir="rtl"] .filtered .actions, + [dir="rtl"] #changelist-filter { + margin-left: 0; + } + + [dir="rtl"] .inline-group ul.tools a.add, + [dir="rtl"] .inline-group div.add-row a, + [dir="rtl"] .inline-group .tabular tr.add-row td a { + padding: 8px 26px 8px 10px; + background-position: calc(100% - 8px) 9px; + } + + [dir="rtl"] .related-widget-wrapper-link + .selector { + margin-right: 0; + margin-left: 15px; + } + + [dir="rtl"] .selector .selector-filter label { + margin-right: 0; + margin-left: 8px; + } + + [dir="rtl"] .object-tools li { + float: right; + } + + [dir="rtl"] .object-tools li + li { + margin-left: 0; + margin-right: 15px; + } + + [dir="rtl"] .dashboard .module table td a { + padding-left: 0; + padding-right: 16px; + } +} + +/* MOBILE */ + +@media (max-width: 767px) { + [dir="rtl"] .aligned .related-lookup, + [dir="rtl"] .aligned .datetimeshortcuts { + margin-left: 0; + margin-right: 15px; + } + + [dir="rtl"] .aligned ul, + [dir="rtl"] form .aligned ul.errorlist { + margin-right: 0; + } + + [dir="rtl"] #changelist-filter { + margin-left: 0; + margin-right: 0; + } + [dir="rtl"] .aligned .vCheckboxLabel { + padding: 1px 5px 0 0; + } +} diff --git a/staticfiles/admin/css/rtl.css b/staticfiles/admin/css/rtl.css new file mode 100644 index 0000000..c349a93 --- /dev/null +++ b/staticfiles/admin/css/rtl.css @@ -0,0 +1,298 @@ +/* GLOBAL */ + +th { + text-align: right; +} + +.module h2, .module caption { + text-align: right; +} + +.module ul, .module ol { + margin-left: 0; + margin-right: 1.5em; +} + +.viewlink, .addlink, .changelink { + padding-left: 0; + padding-right: 16px; + background-position: 100% 1px; +} + +.deletelink { + padding-left: 0; + padding-right: 16px; + background-position: 100% 1px; +} + +.object-tools { + float: left; +} + +thead th:first-child, +tfoot td:first-child { + border-left: none; +} + +/* LAYOUT */ + +#user-tools { + right: auto; + left: 0; + text-align: left; +} + +div.breadcrumbs { + text-align: right; +} + +#content-main { + float: right; +} + +#content-related { + float: left; + margin-left: -300px; + margin-right: auto; +} + +.colMS { + margin-left: 300px; + margin-right: 0; +} + +/* SORTABLE TABLES */ + +table thead th.sorted .sortoptions { + float: left; +} + +thead th.sorted .text { + padding-right: 0; + padding-left: 42px; +} + +/* dashboard styles */ + +.dashboard .module table td a { + padding-left: .6em; + padding-right: 16px; +} + +/* changelists styles */ + +.change-list .filtered table { + border-left: none; + border-right: 0px none; +} + +#changelist-filter { + border-left: none; + border-right: none; + margin-left: 0; + margin-right: 30px; +} + +#changelist-filter li.selected { + border-left: none; + padding-left: 10px; + margin-left: 0; + border-right: 5px solid var(--hairline-color); + padding-right: 10px; + margin-right: -15px; +} + +#changelist table tbody td:first-child, #changelist table tbody th:first-child { + border-right: none; + border-left: none; +} + +.paginator .end { + margin-left: 6px; + margin-right: 0; +} + +.paginator input { + margin-left: 0; + margin-right: auto; +} + +/* FORMS */ + +.aligned label { + padding: 0 0 3px 1em; +} + +.submit-row a.deletelink { + margin-left: 0; + margin-right: auto; +} + +.vDateField, .vTimeField { + margin-left: 2px; +} + +.aligned .form-row input { + margin-left: 5px; +} + +form .aligned ul { + margin-right: 163px; + padding-right: 10px; + margin-left: 0; + padding-left: 0; +} + +form ul.inline li { + float: right; + padding-right: 0; + padding-left: 7px; +} + +form .aligned p.help, +form .aligned div.help { + margin-right: 160px; + padding-right: 10px; +} + +form div.help ul, +form .aligned .checkbox-row + .help, +form .aligned p.date div.help.timezonewarning, +form .aligned p.datetime div.help.timezonewarning, +form .aligned p.time div.help.timezonewarning { + margin-right: 0; + padding-right: 0; +} + +form .wide p.help, form .wide div.help { + padding-left: 0; + padding-right: 50px; +} + +form .wide p, +form .wide ul.errorlist, +form .wide input + p.help, +form .wide input + div.help { + margin-right: 200px; + margin-left: 0px; +} + +.submit-row { + text-align: right; +} + +fieldset .fieldBox { + margin-left: 20px; + margin-right: 0; +} + +.errorlist li { + background-position: 100% 12px; + padding: 0; +} + +.errornote { + background-position: 100% 12px; + padding: 10px 12px; +} + +/* WIDGETS */ + +.calendarnav-previous { + top: 0; + left: auto; + right: 10px; + background: url(../img/calendar-icons.svg) 0 -30px no-repeat; +} + +.calendarbox .calendarnav-previous:focus, +.calendarbox .calendarnav-previous:hover { + background-position: 0 -45px; +} + +.calendarnav-next { + top: 0; + right: auto; + left: 10px; + background: url(../img/calendar-icons.svg) 0 0 no-repeat; +} + +.calendarbox .calendarnav-next:focus, +.calendarbox .calendarnav-next:hover { + background-position: 0 -15px; +} + +.calendar caption, .calendarbox h2 { + text-align: center; +} + +.selector { + float: right; +} + +.selector .selector-filter { + text-align: right; +} + +.selector-add { + background: url(../img/selector-icons.svg) 0 -64px no-repeat; +} + +.active.selector-add:focus, .active.selector-add:hover { + background-position: 0 -80px; +} + +.selector-remove { + background: url(../img/selector-icons.svg) 0 -96px no-repeat; +} + +.active.selector-remove:focus, .active.selector-remove:hover { + background-position: 0 -112px; +} + +a.selector-chooseall { + background: url(../img/selector-icons.svg) right -128px no-repeat; +} + +a.active.selector-chooseall:focus, a.active.selector-chooseall:hover { + background-position: 100% -144px; +} + +a.selector-clearall { + background: url(../img/selector-icons.svg) 0 -160px no-repeat; +} + +a.active.selector-clearall:focus, a.active.selector-clearall:hover { + background-position: 0 -176px; +} + +.inline-deletelink { + float: left; +} + +form .form-row p.datetime { + overflow: hidden; +} + +.related-widget-wrapper { + float: right; +} + +/* MISC */ + +.inline-related h2, .inline-group h2 { + text-align: right +} + +.inline-related h3 span.delete { + padding-right: 20px; + padding-left: inherit; + left: 10px; + right: inherit; + float:left; +} + +.inline-related h3 span.delete label { + margin-left: inherit; + margin-right: 2px; +} diff --git a/staticfiles/admin/css/vendor/select2/LICENSE-SELECT2.md b/staticfiles/admin/css/vendor/select2/LICENSE-SELECT2.md new file mode 100644 index 0000000..8cb8a2b --- /dev/null +++ b/staticfiles/admin/css/vendor/select2/LICENSE-SELECT2.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/staticfiles/admin/css/vendor/select2/select2.css b/staticfiles/admin/css/vendor/select2/select2.css new file mode 100644 index 0000000..750b320 --- /dev/null +++ b/staticfiles/admin/css/vendor/select2/select2.css @@ -0,0 +1,481 @@ +.select2-container { + box-sizing: border-box; + display: inline-block; + margin: 0; + position: relative; + vertical-align: middle; } + .select2-container .select2-selection--single { + box-sizing: border-box; + cursor: pointer; + display: block; + height: 28px; + user-select: none; + -webkit-user-select: none; } + .select2-container .select2-selection--single .select2-selection__rendered { + display: block; + padding-left: 8px; + padding-right: 20px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } + .select2-container .select2-selection--single .select2-selection__clear { + position: relative; } + .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { + padding-right: 8px; + padding-left: 20px; } + .select2-container .select2-selection--multiple { + box-sizing: border-box; + cursor: pointer; + display: block; + min-height: 32px; + user-select: none; + -webkit-user-select: none; } + .select2-container .select2-selection--multiple .select2-selection__rendered { + display: inline-block; + overflow: hidden; + padding-left: 8px; + text-overflow: ellipsis; + white-space: nowrap; } + .select2-container .select2-search--inline { + float: left; } + .select2-container .select2-search--inline .select2-search__field { + box-sizing: border-box; + border: none; + font-size: 100%; + margin-top: 5px; + padding: 0; } + .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { + -webkit-appearance: none; } + +.select2-dropdown { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + box-sizing: border-box; + display: block; + position: absolute; + left: -100000px; + width: 100%; + z-index: 1051; } + +.select2-results { + display: block; } + +.select2-results__options { + list-style: none; + margin: 0; + padding: 0; } + +.select2-results__option { + padding: 6px; + user-select: none; + -webkit-user-select: none; } + .select2-results__option[aria-selected] { + cursor: pointer; } + +.select2-container--open .select2-dropdown { + left: 0; } + +.select2-container--open .select2-dropdown--above { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--open .select2-dropdown--below { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-search--dropdown { + display: block; + padding: 4px; } + .select2-search--dropdown .select2-search__field { + padding: 4px; + width: 100%; + box-sizing: border-box; } + .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { + -webkit-appearance: none; } + .select2-search--dropdown.select2-search--hide { + display: none; } + +.select2-close-mask { + border: 0; + margin: 0; + padding: 0; + display: block; + position: fixed; + left: 0; + top: 0; + min-height: 100%; + min-width: 100%; + height: auto; + width: auto; + opacity: 0; + z-index: 99; + background-color: #fff; + filter: alpha(opacity=0); } + +.select2-hidden-accessible { + border: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(50%) !important; + clip-path: inset(50%) !important; + height: 1px !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + width: 1px !important; + white-space: nowrap !important; } + +.select2-container--default .select2-selection--single { + background-color: #fff; + border: 1px solid #aaa; + border-radius: 4px; } + .select2-container--default .select2-selection--single .select2-selection__rendered { + color: #444; + line-height: 28px; } + .select2-container--default .select2-selection--single .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; } + .select2-container--default .select2-selection--single .select2-selection__placeholder { + color: #999; } + .select2-container--default .select2-selection--single .select2-selection__arrow { + height: 26px; + position: absolute; + top: 1px; + right: 1px; + width: 20px; } + .select2-container--default .select2-selection--single .select2-selection__arrow b { + border-color: #888 transparent transparent transparent; + border-style: solid; + border-width: 5px 4px 0 4px; + height: 0; + left: 50%; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; } + +.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; } + +.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { + left: 1px; + right: auto; } + +.select2-container--default.select2-container--disabled .select2-selection--single { + background-color: #eee; + cursor: default; } + .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { + display: none; } + +.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #888 transparent; + border-width: 0 4px 5px 4px; } + +.select2-container--default .select2-selection--multiple { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + cursor: text; } + .select2-container--default .select2-selection--multiple .select2-selection__rendered { + box-sizing: border-box; + list-style: none; + margin: 0; + padding: 0 5px; + width: 100%; } + .select2-container--default .select2-selection--multiple .select2-selection__rendered li { + list-style: none; } + .select2-container--default .select2-selection--multiple .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; + margin-top: 5px; + margin-right: 10px; + padding: 1px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice { + background-color: #e4e4e4; + border: 1px solid #aaa; + border-radius: 4px; + cursor: default; + float: left; + margin-right: 5px; + margin-top: 5px; + padding: 0 5px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { + color: #999; + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 2px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #333; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { + float: right; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + margin-left: 5px; + margin-right: auto; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; } + +.select2-container--default.select2-container--focus .select2-selection--multiple { + border: solid black 1px; + outline: 0; } + +.select2-container--default.select2-container--disabled .select2-selection--multiple { + background-color: #eee; + cursor: default; } + +.select2-container--default.select2-container--disabled .select2-selection__choice__remove { + display: none; } + +.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--default .select2-search--dropdown .select2-search__field { + border: 1px solid #aaa; } + +.select2-container--default .select2-search--inline .select2-search__field { + background: transparent; + border: none; + outline: 0; + box-shadow: none; + -webkit-appearance: textfield; } + +.select2-container--default .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; } + +.select2-container--default .select2-results__option[role=group] { + padding: 0; } + +.select2-container--default .select2-results__option[aria-disabled=true] { + color: #999; } + +.select2-container--default .select2-results__option[aria-selected=true] { + background-color: #ddd; } + +.select2-container--default .select2-results__option .select2-results__option { + padding-left: 1em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__group { + padding-left: 0; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option { + margin-left: -1em; + padding-left: 2em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -2em; + padding-left: 3em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -3em; + padding-left: 4em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -4em; + padding-left: 5em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -5em; + padding-left: 6em; } + +.select2-container--default .select2-results__option--highlighted[aria-selected] { + background-color: #5897fb; + color: white; } + +.select2-container--default .select2-results__group { + cursor: default; + display: block; + padding: 6px; } + +.select2-container--classic .select2-selection--single { + background-color: #f7f7f7; + border: 1px solid #aaa; + border-radius: 4px; + outline: 0; + background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); + background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); + background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } + .select2-container--classic .select2-selection--single:focus { + border: 1px solid #5897fb; } + .select2-container--classic .select2-selection--single .select2-selection__rendered { + color: #444; + line-height: 28px; } + .select2-container--classic .select2-selection--single .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; + margin-right: 10px; } + .select2-container--classic .select2-selection--single .select2-selection__placeholder { + color: #999; } + .select2-container--classic .select2-selection--single .select2-selection__arrow { + background-color: #ddd; + border: none; + border-left: 1px solid #aaa; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + height: 26px; + position: absolute; + top: 1px; + right: 1px; + width: 20px; + background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); + background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); + background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } + .select2-container--classic .select2-selection--single .select2-selection__arrow b { + border-color: #888 transparent transparent transparent; + border-style: solid; + border-width: 5px 4px 0 4px; + height: 0; + left: 50%; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; } + +.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; } + +.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { + border: none; + border-right: 1px solid #aaa; + border-radius: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + left: 1px; + right: auto; } + +.select2-container--classic.select2-container--open .select2-selection--single { + border: 1px solid #5897fb; } + .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { + background: transparent; + border: none; } + .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #888 transparent; + border-width: 0 4px 5px 4px; } + +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; + background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); + background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); + background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } + +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); + background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); + background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } + +.select2-container--classic .select2-selection--multiple { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + cursor: text; + outline: 0; } + .select2-container--classic .select2-selection--multiple:focus { + border: 1px solid #5897fb; } + .select2-container--classic .select2-selection--multiple .select2-selection__rendered { + list-style: none; + margin: 0; + padding: 0 5px; } + .select2-container--classic .select2-selection--multiple .select2-selection__clear { + display: none; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice { + background-color: #e4e4e4; + border: 1px solid #aaa; + border-radius: 4px; + cursor: default; + float: left; + margin-right: 5px; + margin-top: 5px; + padding: 0 5px; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { + color: #888; + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 2px; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #555; } + +.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + float: right; + margin-left: 5px; + margin-right: auto; } + +.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; } + +.select2-container--classic.select2-container--open .select2-selection--multiple { + border: 1px solid #5897fb; } + +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--classic .select2-search--dropdown .select2-search__field { + border: 1px solid #aaa; + outline: 0; } + +.select2-container--classic .select2-search--inline .select2-search__field { + outline: 0; + box-shadow: none; } + +.select2-container--classic .select2-dropdown { + background-color: white; + border: 1px solid transparent; } + +.select2-container--classic .select2-dropdown--above { + border-bottom: none; } + +.select2-container--classic .select2-dropdown--below { + border-top: none; } + +.select2-container--classic .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; } + +.select2-container--classic .select2-results__option[role=group] { + padding: 0; } + +.select2-container--classic .select2-results__option[aria-disabled=true] { + color: grey; } + +.select2-container--classic .select2-results__option--highlighted[aria-selected] { + background-color: #3875d7; + color: white; } + +.select2-container--classic .select2-results__group { + cursor: default; + display: block; + padding: 6px; } + +.select2-container--classic.select2-container--open .select2-dropdown { + border-color: #5897fb; } diff --git a/staticfiles/admin/css/vendor/select2/select2.min.css b/staticfiles/admin/css/vendor/select2/select2.min.css new file mode 100644 index 0000000..7c18ad5 --- /dev/null +++ b/staticfiles/admin/css/vendor/select2/select2.min.css @@ -0,0 +1 @@ +.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} diff --git a/staticfiles/admin/css/widgets.css b/staticfiles/admin/css/widgets.css new file mode 100644 index 0000000..1104e8b --- /dev/null +++ b/staticfiles/admin/css/widgets.css @@ -0,0 +1,604 @@ +/* SELECTOR (FILTER INTERFACE) */ + +.selector { + width: 800px; + float: left; + display: flex; +} + +.selector select { + width: 380px; + height: 17.2em; + flex: 1 0 auto; +} + +.selector-available, .selector-chosen { + width: 380px; + text-align: center; + margin-bottom: 5px; + display: flex; + flex-direction: column; +} + +.selector-available h2, .selector-chosen h2 { + border: 1px solid var(--border-color); + border-radius: 4px 4px 0 0; +} + +.selector-chosen .list-footer-display { + border: 1px solid var(--border-color); + border-top: none; + border-radius: 0 0 4px 4px; + margin: 0 0 10px; + padding: 8px; + text-align: center; + background: var(--primary); + color: var(--header-link-color); + cursor: pointer; +} +.selector-chosen .list-footer-display__clear { + color: var(--breadcrumbs-fg); +} + +.selector-chosen h2 { + background: var(--primary); + color: var(--header-link-color); +} + +.selector .selector-available h2 { + background: var(--darkened-bg); + color: var(--body-quiet-color); +} + +.selector .selector-filter { + border: 1px solid var(--border-color); + border-width: 0 1px; + padding: 8px; + color: var(--body-quiet-color); + font-size: 0.625rem; + margin: 0; + text-align: left; +} + +.selector .selector-filter label, +.inline-group .aligned .selector .selector-filter label { + float: left; + margin: 7px 0 0; + width: 18px; + height: 18px; + padding: 0; + overflow: hidden; + line-height: 1; + min-width: auto; +} + +.selector .selector-available input, +.selector .selector-chosen input { + width: 320px; + margin-left: 8px; +} + +.selector ul.selector-chooser { + align-self: center; + width: 22px; + background-color: var(--selected-bg); + border-radius: 10px; + margin: 0 5px; + padding: 0; + transform: translateY(-17px); +} + +.selector-chooser li { + margin: 0; + padding: 3px; + list-style-type: none; +} + +.selector select { + padding: 0 10px; + margin: 0 0 10px; + border-radius: 0 0 4px 4px; +} +.selector .selector-chosen--with-filtered select { + margin: 0; + border-radius: 0; + height: 14em; +} + +.selector .selector-chosen:not(.selector-chosen--with-filtered) .list-footer-display { + display: none; +} + +.selector-add, .selector-remove { + width: 16px; + height: 16px; + display: block; + text-indent: -3000px; + overflow: hidden; + cursor: default; + opacity: 0.55; +} + +.active.selector-add, .active.selector-remove { + opacity: 1; +} + +.active.selector-add:hover, .active.selector-remove:hover { + cursor: pointer; +} + +.selector-add { + background: url(../img/selector-icons.svg) 0 -96px no-repeat; +} + +.active.selector-add:focus, .active.selector-add:hover { + background-position: 0 -112px; +} + +.selector-remove { + background: url(../img/selector-icons.svg) 0 -64px no-repeat; +} + +.active.selector-remove:focus, .active.selector-remove:hover { + background-position: 0 -80px; +} + +a.selector-chooseall, a.selector-clearall { + display: inline-block; + height: 16px; + text-align: left; + margin: 1px auto 3px; + overflow: hidden; + font-weight: bold; + line-height: 16px; + color: var(--body-quiet-color); + text-decoration: none; + opacity: 0.55; +} + +a.active.selector-chooseall:focus, a.active.selector-clearall:focus, +a.active.selector-chooseall:hover, a.active.selector-clearall:hover { + color: var(--link-fg); +} + +a.active.selector-chooseall, a.active.selector-clearall { + opacity: 1; +} + +a.active.selector-chooseall:hover, a.active.selector-clearall:hover { + cursor: pointer; +} + +a.selector-chooseall { + padding: 0 18px 0 0; + background: url(../img/selector-icons.svg) right -160px no-repeat; + cursor: default; +} + +a.active.selector-chooseall:focus, a.active.selector-chooseall:hover { + background-position: 100% -176px; +} + +a.selector-clearall { + padding: 0 0 0 18px; + background: url(../img/selector-icons.svg) 0 -128px no-repeat; + cursor: default; +} + +a.active.selector-clearall:focus, a.active.selector-clearall:hover { + background-position: 0 -144px; +} + +/* STACKED SELECTORS */ + +.stacked { + float: left; + width: 490px; + display: block; +} + +.stacked select { + width: 480px; + height: 10.1em; +} + +.stacked .selector-available, .stacked .selector-chosen { + width: 480px; +} + +.stacked .selector-available { + margin-bottom: 0; +} + +.stacked .selector-available input { + width: 422px; +} + +.stacked ul.selector-chooser { + height: 22px; + width: 50px; + margin: 0 0 10px 40%; + background-color: #eee; + border-radius: 10px; + transform: none; +} + +.stacked .selector-chooser li { + float: left; + padding: 3px 3px 3px 5px; +} + +.stacked .selector-chooseall, .stacked .selector-clearall { + display: none; +} + +.stacked .selector-add { + background: url(../img/selector-icons.svg) 0 -32px no-repeat; + cursor: default; +} + +.stacked .active.selector-add { + background-position: 0 -32px; + cursor: pointer; +} + +.stacked .active.selector-add:focus, .stacked .active.selector-add:hover { + background-position: 0 -48px; + cursor: pointer; +} + +.stacked .selector-remove { + background: url(../img/selector-icons.svg) 0 0 no-repeat; + cursor: default; +} + +.stacked .active.selector-remove { + background-position: 0 0px; + cursor: pointer; +} + +.stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover { + background-position: 0 -16px; + cursor: pointer; +} + +.selector .help-icon { + background: url(../img/icon-unknown.svg) 0 0 no-repeat; + display: inline-block; + vertical-align: middle; + margin: -2px 0 0 2px; + width: 13px; + height: 13px; +} + +.selector .selector-chosen .help-icon { + background: url(../img/icon-unknown-alt.svg) 0 0 no-repeat; +} + +.selector .search-label-icon { + background: url(../img/search.svg) 0 0 no-repeat; + display: inline-block; + height: 1.125rem; + width: 1.125rem; +} + +/* DATE AND TIME */ + +p.datetime { + line-height: 20px; + margin: 0; + padding: 0; + color: var(--body-quiet-color); + font-weight: bold; +} + +.datetime span { + white-space: nowrap; + font-weight: normal; + font-size: 0.6875rem; + color: var(--body-quiet-color); +} + +.datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField { + margin-left: 5px; + margin-bottom: 4px; +} + +table p.datetime { + font-size: 0.6875rem; + margin-left: 0; + padding-left: 0; +} + +.datetimeshortcuts .clock-icon, .datetimeshortcuts .date-icon { + position: relative; + display: inline-block; + vertical-align: middle; + height: 16px; + width: 16px; + overflow: hidden; +} + +.datetimeshortcuts .clock-icon { + background: url(../img/icon-clock.svg) 0 0 no-repeat; +} + +.datetimeshortcuts a:focus .clock-icon, +.datetimeshortcuts a:hover .clock-icon { + background-position: 0 -16px; +} + +.datetimeshortcuts .date-icon { + background: url(../img/icon-calendar.svg) 0 0 no-repeat; + top: -1px; +} + +.datetimeshortcuts a:focus .date-icon, +.datetimeshortcuts a:hover .date-icon { + background-position: 0 -16px; +} + +.timezonewarning { + font-size: 0.6875rem; + color: var(--body-quiet-color); +} + +/* URL */ + +p.url { + line-height: 20px; + margin: 0; + padding: 0; + color: var(--body-quiet-color); + font-size: 0.6875rem; + font-weight: bold; +} + +.url a { + font-weight: normal; +} + +/* FILE UPLOADS */ + +p.file-upload { + line-height: 20px; + margin: 0; + padding: 0; + color: var(--body-quiet-color); + font-size: 0.6875rem; + font-weight: bold; +} + +.file-upload a { + font-weight: normal; +} + +.file-upload .deletelink { + margin-left: 5px; +} + +span.clearable-file-input label { + color: var(--body-fg); + font-size: 0.6875rem; + display: inline; + float: none; +} + +/* CALENDARS & CLOCKS */ + +.calendarbox, .clockbox { + margin: 5px auto; + font-size: 0.75rem; + width: 19em; + text-align: center; + background: var(--body-bg); + color: var(--body-fg); + border: 1px solid var(--hairline-color); + border-radius: 4px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); + overflow: hidden; + position: relative; +} + +.clockbox { + width: auto; +} + +.calendar { + margin: 0; + padding: 0; +} + +.calendar table { + margin: 0; + padding: 0; + border-collapse: collapse; + background: white; + width: 100%; +} + +.calendar caption, .calendarbox h2 { + margin: 0; + text-align: center; + border-top: none; + font-weight: 700; + font-size: 0.75rem; + color: #333; + background: var(--accent); +} + +.calendar th { + padding: 8px 5px; + background: var(--darkened-bg); + border-bottom: 1px solid var(--border-color); + font-weight: 400; + font-size: 0.75rem; + text-align: center; + color: var(--body-quiet-color); +} + +.calendar td { + font-weight: 400; + font-size: 0.75rem; + text-align: center; + padding: 0; + border-top: 1px solid var(--hairline-color); + border-bottom: none; +} + +.calendar td.selected a { + background: var(--primary); + color: var(--button-fg); +} + +.calendar td.nonday { + background: var(--darkened-bg); +} + +.calendar td.today a { + font-weight: 700; +} + +.calendar td a, .timelist a { + display: block; + font-weight: 400; + padding: 6px; + text-decoration: none; + color: var(--body-quiet-color); +} + +.calendar td a:focus, .timelist a:focus, +.calendar td a:hover, .timelist a:hover { + background: var(--primary); + color: white; +} + +.calendar td a:active, .timelist a:active { + background: var(--header-bg); + color: white; +} + +.calendarnav { + font-size: 0.625rem; + text-align: center; + color: #ccc; + margin: 0; + padding: 1px 3px; +} + +.calendarnav a:link, #calendarnav a:visited, +#calendarnav a:focus, #calendarnav a:hover { + color: var(--body-quiet-color); +} + +.calendar-shortcuts { + background: var(--body-bg); + color: var(--body-quiet-color); + font-size: 0.6875rem; + line-height: 0.6875rem; + border-top: 1px solid var(--hairline-color); + padding: 8px 0; +} + +.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { + display: block; + position: absolute; + top: 8px; + width: 15px; + height: 15px; + text-indent: -9999px; + padding: 0; +} + +.calendarnav-previous { + left: 10px; + background: url(../img/calendar-icons.svg) 0 0 no-repeat; +} + +.calendarbox .calendarnav-previous:focus, +.calendarbox .calendarnav-previous:hover { + background-position: 0 -15px; +} + +.calendarnav-next { + right: 10px; + background: url(../img/calendar-icons.svg) 0 -30px no-repeat; +} + +.calendarbox .calendarnav-next:focus, +.calendarbox .calendarnav-next:hover { + background-position: 0 -45px; +} + +.calendar-cancel { + margin: 0; + padding: 4px 0; + font-size: 0.75rem; + background: #eee; + border-top: 1px solid var(--border-color); + color: var(--body-fg); +} + +.calendar-cancel:focus, .calendar-cancel:hover { + background: #ddd; +} + +.calendar-cancel a { + color: black; + display: block; +} + +ul.timelist, .timelist li { + list-style-type: none; + margin: 0; + padding: 0; +} + +.timelist a { + padding: 2px; +} + +/* EDIT INLINE */ + +.inline-deletelink { + float: right; + text-indent: -9999px; + background: url(../img/inline-delete.svg) 0 0 no-repeat; + width: 16px; + height: 16px; + border: 0px none; +} + +.inline-deletelink:focus, .inline-deletelink:hover { + cursor: pointer; +} + +/* RELATED WIDGET WRAPPER */ +.related-widget-wrapper { + float: left; /* display properly in form rows with multiple fields */ + overflow: hidden; /* clear floated contents */ +} + +.related-widget-wrapper-link { + opacity: 0.3; +} + +.related-widget-wrapper-link:link { + opacity: .8; +} + +.related-widget-wrapper-link:link:focus, +.related-widget-wrapper-link:link:hover { + opacity: 1; +} + +select + .related-widget-wrapper-link, +.related-widget-wrapper-link + .related-widget-wrapper-link { + margin-left: 7px; +} + +/* GIS MAPS */ +.dj_map { + width: 600px; + height: 400px; +} diff --git a/staticfiles/admin/img/LICENSE b/staticfiles/admin/img/LICENSE new file mode 100644 index 0000000..a4faaa1 --- /dev/null +++ b/staticfiles/admin/img/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Code Charm Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/staticfiles/admin/img/README.txt b/staticfiles/admin/img/README.txt new file mode 100644 index 0000000..4eb2e49 --- /dev/null +++ b/staticfiles/admin/img/README.txt @@ -0,0 +1,7 @@ +All icons are taken from Font Awesome (http://fontawesome.io/) project. +The Font Awesome font is licensed under the SIL OFL 1.1: +- https://scripts.sil.org/OFL + +SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG +Font-Awesome-SVG-PNG is licensed under the MIT license (see file license +in current folder). diff --git a/staticfiles/admin/img/calendar-icons.svg b/staticfiles/admin/img/calendar-icons.svg new file mode 100644 index 0000000..dbf21c3 --- /dev/null +++ b/staticfiles/admin/img/calendar-icons.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/staticfiles/admin/img/gis/move_vertex_off.svg b/staticfiles/admin/img/gis/move_vertex_off.svg new file mode 100644 index 0000000..228854f --- /dev/null +++ b/staticfiles/admin/img/gis/move_vertex_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staticfiles/admin/img/gis/move_vertex_on.svg b/staticfiles/admin/img/gis/move_vertex_on.svg new file mode 100644 index 0000000..96b87fd --- /dev/null +++ b/staticfiles/admin/img/gis/move_vertex_on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/staticfiles/admin/img/icon-addlink.svg b/staticfiles/admin/img/icon-addlink.svg new file mode 100644 index 0000000..e004fb1 --- /dev/null +++ b/staticfiles/admin/img/icon-addlink.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/icon-alert.svg b/staticfiles/admin/img/icon-alert.svg new file mode 100644 index 0000000..e51ea83 --- /dev/null +++ b/staticfiles/admin/img/icon-alert.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/icon-calendar.svg b/staticfiles/admin/img/icon-calendar.svg new file mode 100644 index 0000000..97910a9 --- /dev/null +++ b/staticfiles/admin/img/icon-calendar.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/staticfiles/admin/img/icon-changelink.svg b/staticfiles/admin/img/icon-changelink.svg new file mode 100644 index 0000000..bbb137a --- /dev/null +++ b/staticfiles/admin/img/icon-changelink.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/icon-clock.svg b/staticfiles/admin/img/icon-clock.svg new file mode 100644 index 0000000..bf9985d --- /dev/null +++ b/staticfiles/admin/img/icon-clock.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/staticfiles/admin/img/icon-deletelink.svg b/staticfiles/admin/img/icon-deletelink.svg new file mode 100644 index 0000000..4059b15 --- /dev/null +++ b/staticfiles/admin/img/icon-deletelink.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/icon-no.svg b/staticfiles/admin/img/icon-no.svg new file mode 100644 index 0000000..2e0d383 --- /dev/null +++ b/staticfiles/admin/img/icon-no.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/icon-unknown-alt.svg b/staticfiles/admin/img/icon-unknown-alt.svg new file mode 100644 index 0000000..1c6b99f --- /dev/null +++ b/staticfiles/admin/img/icon-unknown-alt.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/icon-unknown.svg b/staticfiles/admin/img/icon-unknown.svg new file mode 100644 index 0000000..50b4f97 --- /dev/null +++ b/staticfiles/admin/img/icon-unknown.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/icon-viewlink.svg b/staticfiles/admin/img/icon-viewlink.svg new file mode 100644 index 0000000..a1ca1d3 --- /dev/null +++ b/staticfiles/admin/img/icon-viewlink.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/icon-yes.svg b/staticfiles/admin/img/icon-yes.svg new file mode 100644 index 0000000..5883d87 --- /dev/null +++ b/staticfiles/admin/img/icon-yes.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/inline-delete.svg b/staticfiles/admin/img/inline-delete.svg new file mode 100644 index 0000000..17d1ad6 --- /dev/null +++ b/staticfiles/admin/img/inline-delete.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/search.svg b/staticfiles/admin/img/search.svg new file mode 100644 index 0000000..c8c69b2 --- /dev/null +++ b/staticfiles/admin/img/search.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/selector-icons.svg b/staticfiles/admin/img/selector-icons.svg new file mode 100644 index 0000000..926b8e2 --- /dev/null +++ b/staticfiles/admin/img/selector-icons.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/staticfiles/admin/img/sorting-icons.svg b/staticfiles/admin/img/sorting-icons.svg new file mode 100644 index 0000000..7c31ec9 --- /dev/null +++ b/staticfiles/admin/img/sorting-icons.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/staticfiles/admin/img/tooltag-add.svg b/staticfiles/admin/img/tooltag-add.svg new file mode 100644 index 0000000..1ca64ae --- /dev/null +++ b/staticfiles/admin/img/tooltag-add.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/img/tooltag-arrowright.svg b/staticfiles/admin/img/tooltag-arrowright.svg new file mode 100644 index 0000000..b664d61 --- /dev/null +++ b/staticfiles/admin/img/tooltag-arrowright.svg @@ -0,0 +1,3 @@ + + + diff --git a/staticfiles/admin/js/SelectBox.js b/staticfiles/admin/js/SelectBox.js new file mode 100644 index 0000000..3db4ec7 --- /dev/null +++ b/staticfiles/admin/js/SelectBox.js @@ -0,0 +1,116 @@ +'use strict'; +{ + const SelectBox = { + cache: {}, + init: function(id) { + const box = document.getElementById(id); + SelectBox.cache[id] = []; + const cache = SelectBox.cache[id]; + for (const node of box.options) { + cache.push({value: node.value, text: node.text, displayed: 1}); + } + }, + redisplay: function(id) { + // Repopulate HTML select box from cache + const box = document.getElementById(id); + const scroll_value_from_top = box.scrollTop; + box.innerHTML = ''; + for (const node of SelectBox.cache[id]) { + if (node.displayed) { + const new_option = new Option(node.text, node.value, false, false); + // Shows a tooltip when hovering over the option + new_option.title = node.text; + box.appendChild(new_option); + } + } + box.scrollTop = scroll_value_from_top; + }, + filter: function(id, text) { + // Redisplay the HTML select box, displaying only the choices containing ALL + // the words in text. (It's an AND search.) + const tokens = text.toLowerCase().split(/\s+/); + for (const node of SelectBox.cache[id]) { + node.displayed = 1; + const node_text = node.text.toLowerCase(); + for (const token of tokens) { + if (!node_text.includes(token)) { + node.displayed = 0; + break; // Once the first token isn't found we're done + } + } + } + SelectBox.redisplay(id); + }, + get_hidden_node_count(id) { + const cache = SelectBox.cache[id] || []; + return cache.filter(node => node.displayed === 0).length; + }, + delete_from_cache: function(id, value) { + let delete_index = null; + const cache = SelectBox.cache[id]; + for (const [i, node] of cache.entries()) { + if (node.value === value) { + delete_index = i; + break; + } + } + cache.splice(delete_index, 1); + }, + add_to_cache: function(id, option) { + SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); + }, + cache_contains: function(id, value) { + // Check if an item is contained in the cache + for (const node of SelectBox.cache[id]) { + if (node.value === value) { + return true; + } + } + return false; + }, + move: function(from, to) { + const from_box = document.getElementById(from); + for (const option of from_box.options) { + const option_value = option.value; + if (option.selected && SelectBox.cache_contains(from, option_value)) { + SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); + SelectBox.delete_from_cache(from, option_value); + } + } + SelectBox.redisplay(from); + SelectBox.redisplay(to); + }, + move_all: function(from, to) { + const from_box = document.getElementById(from); + for (const option of from_box.options) { + const option_value = option.value; + if (SelectBox.cache_contains(from, option_value)) { + SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); + SelectBox.delete_from_cache(from, option_value); + } + } + SelectBox.redisplay(from); + SelectBox.redisplay(to); + }, + sort: function(id) { + SelectBox.cache[id].sort(function(a, b) { + a = a.text.toLowerCase(); + b = b.text.toLowerCase(); + if (a > b) { + return 1; + } + if (a < b) { + return -1; + } + return 0; + } ); + }, + select_all: function(id) { + const box = document.getElementById(id); + for (const option of box.options) { + option.selected = true; + } + } + }; + window.SelectBox = SelectBox; +} diff --git a/staticfiles/admin/js/SelectFilter2.js b/staticfiles/admin/js/SelectFilter2.js new file mode 100644 index 0000000..9a4e0a3 --- /dev/null +++ b/staticfiles/admin/js/SelectFilter2.js @@ -0,0 +1,283 @@ +/*global SelectBox, gettext, interpolate, quickElement, SelectFilter*/ +/* +SelectFilter2 - Turns a multiple-select box into a filter interface. + +Requires core.js and SelectBox.js. +*/ +'use strict'; +{ + window.SelectFilter = { + init: function(field_id, field_name, is_stacked) { + if (field_id.match(/__prefix__/)) { + // Don't initialize on empty forms. + return; + } + const from_box = document.getElementById(field_id); + from_box.id += '_from'; // change its ID + from_box.className = 'filtered'; + + for (const p of from_box.parentNode.getElementsByTagName('p')) { + if (p.classList.contains("info")) { + // Remove

, because it just gets in the way. + from_box.parentNode.removeChild(p); + } else if (p.classList.contains("help")) { + // Move help text up to the top so it isn't below the select + // boxes or wrapped off on the side to the right of the add + // button: + from_box.parentNode.insertBefore(p, from_box.parentNode.firstChild); + } + } + + //

or
+ const selector_div = quickElement('div', from_box.parentNode); + selector_div.className = is_stacked ? 'selector stacked' : 'selector'; + + //
+ const selector_available = quickElement('div', selector_div); + selector_available.className = 'selector-available'; + const title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); + quickElement( + 'span', title_available, '', + 'class', 'help help-tooltip help-icon', + 'title', interpolate( + gettext( + 'This is the list of available %s. You may choose some by ' + + 'selecting them in the box below and then clicking the ' + + '"Choose" arrow between the two boxes.' + ), + [field_name] + ) + ); + + const filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); + filter_p.className = 'selector-filter'; + + const search_filter_label = quickElement('label', filter_p, '', 'for', field_id + '_input'); + + quickElement( + 'span', search_filter_label, '', + 'class', 'help-tooltip search-label-icon', + 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name]) + ); + + filter_p.appendChild(document.createTextNode(' ')); + + const filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); + filter_input.id = field_id + '_input'; + + selector_available.appendChild(from_box); + const choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_add_all_link'); + choose_all.className = 'selector-chooseall'; + + //
    + const selector_chooser = quickElement('ul', selector_div); + selector_chooser.className = 'selector-chooser'; + const add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', '#', 'id', field_id + '_add_link'); + add_link.className = 'selector-add'; + const remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', '#', 'id', field_id + '_remove_link'); + remove_link.className = 'selector-remove'; + + //
    + const selector_chosen = quickElement('div', selector_div, '', 'id', field_id + '_selector_chosen'); + selector_chosen.className = 'selector-chosen'; + const title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); + quickElement( + 'span', title_chosen, '', + 'class', 'help help-tooltip help-icon', + 'title', interpolate( + gettext( + 'This is the list of chosen %s. You may remove some by ' + + 'selecting them in the box below and then clicking the ' + + '"Remove" arrow between the two boxes.' + ), + [field_name] + ) + ); + + const filter_selected_p = quickElement('p', selector_chosen, '', 'id', field_id + '_filter_selected'); + filter_selected_p.className = 'selector-filter'; + + const search_filter_selected_label = quickElement('label', filter_selected_p, '', 'for', field_id + '_selected_input'); + + quickElement( + 'span', search_filter_selected_label, '', + 'class', 'help-tooltip search-label-icon', + 'title', interpolate(gettext("Type into this box to filter down the list of selected %s."), [field_name]) + ); + + filter_selected_p.appendChild(document.createTextNode(' ')); + + const filter_selected_input = quickElement('input', filter_selected_p, '', 'type', 'text', 'placeholder', gettext("Filter")); + filter_selected_input.id = field_id + '_selected_input'; + + const to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', '', 'size', from_box.size, 'name', from_box.name); + to_box.className = 'filtered'; + + const warning_footer = quickElement('div', selector_chosen, '', 'class', 'list-footer-display'); + quickElement('span', warning_footer, '', 'id', field_id + '_list-footer-display-text'); + quickElement('span', warning_footer, ' (click to clear)', 'class', 'list-footer-display__clear'); + + const clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_remove_all_link'); + clear_all.className = 'selector-clearall'; + + from_box.name = from_box.name + '_old'; + + // Set up the JavaScript event handlers for the select box filter interface + const move_selection = function(e, elem, move_func, from, to) { + if (elem.classList.contains('active')) { + move_func(from, to); + SelectFilter.refresh_icons(field_id); + SelectFilter.refresh_filtered_selects(field_id); + SelectFilter.refresh_filtered_warning(field_id); + } + e.preventDefault(); + }; + choose_all.addEventListener('click', function(e) { + move_selection(e, this, SelectBox.move_all, field_id + '_from', field_id + '_to'); + }); + add_link.addEventListener('click', function(e) { + move_selection(e, this, SelectBox.move, field_id + '_from', field_id + '_to'); + }); + remove_link.addEventListener('click', function(e) { + move_selection(e, this, SelectBox.move, field_id + '_to', field_id + '_from'); + }); + clear_all.addEventListener('click', function(e) { + move_selection(e, this, SelectBox.move_all, field_id + '_to', field_id + '_from'); + }); + warning_footer.addEventListener('click', function(e) { + filter_selected_input.value = ''; + SelectBox.filter(field_id + '_to', ''); + SelectFilter.refresh_filtered_warning(field_id); + SelectFilter.refresh_icons(field_id); + }); + filter_input.addEventListener('keypress', function(e) { + SelectFilter.filter_key_press(e, field_id, '_from', '_to'); + }); + filter_input.addEventListener('keyup', function(e) { + SelectFilter.filter_key_up(e, field_id, '_from'); + }); + filter_input.addEventListener('keydown', function(e) { + SelectFilter.filter_key_down(e, field_id, '_from', '_to'); + }); + filter_selected_input.addEventListener('keypress', function(e) { + SelectFilter.filter_key_press(e, field_id, '_to', '_from'); + }); + filter_selected_input.addEventListener('keyup', function(e) { + SelectFilter.filter_key_up(e, field_id, '_to', '_selected_input'); + }); + filter_selected_input.addEventListener('keydown', function(e) { + SelectFilter.filter_key_down(e, field_id, '_to', '_from'); + }); + selector_div.addEventListener('change', function(e) { + if (e.target.tagName === 'SELECT') { + SelectFilter.refresh_icons(field_id); + } + }); + selector_div.addEventListener('dblclick', function(e) { + if (e.target.tagName === 'OPTION') { + if (e.target.closest('select').id === field_id + '_to') { + SelectBox.move(field_id + '_to', field_id + '_from'); + } else { + SelectBox.move(field_id + '_from', field_id + '_to'); + } + SelectFilter.refresh_icons(field_id); + } + }); + from_box.closest('form').addEventListener('submit', function() { + SelectBox.filter(field_id + '_to', ''); + SelectBox.select_all(field_id + '_to'); + }); + SelectBox.init(field_id + '_from'); + SelectBox.init(field_id + '_to'); + // Move selected from_box options to to_box + SelectBox.move(field_id + '_from', field_id + '_to'); + + // Initial icon refresh + SelectFilter.refresh_icons(field_id); + }, + any_selected: function(field) { + // Temporarily add the required attribute and check validity. + field.required = true; + const any_selected = field.checkValidity(); + field.required = false; + return any_selected; + }, + refresh_filtered_warning: function(field_id) { + const count = SelectBox.get_hidden_node_count(field_id + '_to'); + const selector = document.getElementById(field_id + '_selector_chosen'); + const warning = document.getElementById(field_id + '_list-footer-display-text'); + selector.className = selector.className.replace('selector-chosen--with-filtered', ''); + warning.textContent = interpolate(ngettext( + '%s selected option not visible', + '%s selected options not visible', + count + ), [count]); + if(count > 0) { + selector.className += ' selector-chosen--with-filtered'; + } + }, + refresh_filtered_selects: function(field_id) { + SelectBox.filter(field_id + '_from', document.getElementById(field_id + "_input").value); + SelectBox.filter(field_id + '_to', document.getElementById(field_id + "_selected_input").value); + }, + refresh_icons: function(field_id) { + const from = document.getElementById(field_id + '_from'); + const to = document.getElementById(field_id + '_to'); + // Active if at least one item is selected + document.getElementById(field_id + '_add_link').classList.toggle('active', SelectFilter.any_selected(from)); + document.getElementById(field_id + '_remove_link').classList.toggle('active', SelectFilter.any_selected(to)); + // Active if the corresponding box isn't empty + document.getElementById(field_id + '_add_all_link').classList.toggle('active', from.querySelector('option')); + document.getElementById(field_id + '_remove_all_link').classList.toggle('active', to.querySelector('option')); + SelectFilter.refresh_filtered_warning(field_id); + }, + filter_key_press: function(event, field_id, source, target) { + const source_box = document.getElementById(field_id + source); + // don't submit form if user pressed Enter + if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) { + source_box.selectedIndex = 0; + SelectBox.move(field_id + source, field_id + target); + source_box.selectedIndex = 0; + event.preventDefault(); + } + }, + filter_key_up: function(event, field_id, source, filter_input) { + const input = filter_input || '_input'; + const source_box = document.getElementById(field_id + source); + const temp = source_box.selectedIndex; + SelectBox.filter(field_id + source, document.getElementById(field_id + input).value); + source_box.selectedIndex = temp; + SelectFilter.refresh_filtered_warning(field_id); + SelectFilter.refresh_icons(field_id); + }, + filter_key_down: function(event, field_id, source, target) { + const source_box = document.getElementById(field_id + source); + // right key (39) or left key (37) + const direction = source === '_from' ? 39 : 37; + // right arrow -- move across + if ((event.which && event.which === direction) || (event.keyCode && event.keyCode === direction)) { + const old_index = source_box.selectedIndex; + SelectBox.move(field_id + source, field_id + target); + SelectFilter.refresh_filtered_selects(field_id); + SelectFilter.refresh_filtered_warning(field_id); + source_box.selectedIndex = (old_index === source_box.length) ? source_box.length - 1 : old_index; + return; + } + // down arrow -- wrap around + if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) { + source_box.selectedIndex = (source_box.length === source_box.selectedIndex + 1) ? 0 : source_box.selectedIndex + 1; + } + // up arrow -- wrap around + if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) { + source_box.selectedIndex = (source_box.selectedIndex === 0) ? source_box.length - 1 : source_box.selectedIndex - 1; + } + } + }; + + window.addEventListener('load', function(e) { + document.querySelectorAll('select.selectfilter, select.selectfilterstacked').forEach(function(el) { + const data = el.dataset; + SelectFilter.init(el.id, data.fieldName, parseInt(data.isStacked, 10)); + }); + }); +} diff --git a/staticfiles/admin/js/actions.js b/staticfiles/admin/js/actions.js new file mode 100644 index 0000000..20a5c14 --- /dev/null +++ b/staticfiles/admin/js/actions.js @@ -0,0 +1,201 @@ +/*global gettext, interpolate, ngettext*/ +'use strict'; +{ + function show(selector) { + document.querySelectorAll(selector).forEach(function(el) { + el.classList.remove('hidden'); + }); + } + + function hide(selector) { + document.querySelectorAll(selector).forEach(function(el) { + el.classList.add('hidden'); + }); + } + + function showQuestion(options) { + hide(options.acrossClears); + show(options.acrossQuestions); + hide(options.allContainer); + } + + function showClear(options) { + show(options.acrossClears); + hide(options.acrossQuestions); + document.querySelector(options.actionContainer).classList.remove(options.selectedClass); + show(options.allContainer); + hide(options.counterContainer); + } + + function reset(options) { + hide(options.acrossClears); + hide(options.acrossQuestions); + hide(options.allContainer); + show(options.counterContainer); + } + + function clearAcross(options) { + reset(options); + const acrossInputs = document.querySelectorAll(options.acrossInput); + acrossInputs.forEach(function(acrossInput) { + acrossInput.value = 0; + }); + document.querySelector(options.actionContainer).classList.remove(options.selectedClass); + } + + function checker(actionCheckboxes, options, checked) { + if (checked) { + showQuestion(options); + } else { + reset(options); + } + actionCheckboxes.forEach(function(el) { + el.checked = checked; + el.closest('tr').classList.toggle(options.selectedClass, checked); + }); + } + + function updateCounter(actionCheckboxes, options) { + const sel = Array.from(actionCheckboxes).filter(function(el) { + return el.checked; + }).length; + const counter = document.querySelector(options.counterContainer); + // data-actions-icnt is defined in the generated HTML + // and contains the total amount of objects in the queryset + const actions_icnt = Number(counter.dataset.actionsIcnt); + counter.textContent = interpolate( + ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { + sel: sel, + cnt: actions_icnt + }, true); + const allToggle = document.getElementById(options.allToggleId); + allToggle.checked = sel === actionCheckboxes.length; + if (allToggle.checked) { + showQuestion(options); + } else { + clearAcross(options); + } + } + + const defaults = { + actionContainer: "div.actions", + counterContainer: "span.action-counter", + allContainer: "div.actions span.all", + acrossInput: "div.actions input.select-across", + acrossQuestions: "div.actions span.question", + acrossClears: "div.actions span.clear", + allToggleId: "action-toggle", + selectedClass: "selected" + }; + + window.Actions = function(actionCheckboxes, options) { + options = Object.assign({}, defaults, options); + let list_editable_changed = false; + let lastChecked = null; + let shiftPressed = false; + + document.addEventListener('keydown', (event) => { + shiftPressed = event.shiftKey; + }); + + document.addEventListener('keyup', (event) => { + shiftPressed = event.shiftKey; + }); + + document.getElementById(options.allToggleId).addEventListener('click', function(event) { + checker(actionCheckboxes, options, this.checked); + updateCounter(actionCheckboxes, options); + }); + + document.querySelectorAll(options.acrossQuestions + " a").forEach(function(el) { + el.addEventListener('click', function(event) { + event.preventDefault(); + const acrossInputs = document.querySelectorAll(options.acrossInput); + acrossInputs.forEach(function(acrossInput) { + acrossInput.value = 1; + }); + showClear(options); + }); + }); + + document.querySelectorAll(options.acrossClears + " a").forEach(function(el) { + el.addEventListener('click', function(event) { + event.preventDefault(); + document.getElementById(options.allToggleId).checked = false; + clearAcross(options); + checker(actionCheckboxes, options, false); + updateCounter(actionCheckboxes, options); + }); + }); + + function affectedCheckboxes(target, withModifier) { + const multiSelect = (lastChecked && withModifier && lastChecked !== target); + if (!multiSelect) { + return [target]; + } + const checkboxes = Array.from(actionCheckboxes); + const targetIndex = checkboxes.findIndex(el => el === target); + const lastCheckedIndex = checkboxes.findIndex(el => el === lastChecked); + const startIndex = Math.min(targetIndex, lastCheckedIndex); + const endIndex = Math.max(targetIndex, lastCheckedIndex); + const filtered = checkboxes.filter((el, index) => (startIndex <= index) && (index <= endIndex)); + return filtered; + }; + + Array.from(document.getElementById('result_list').tBodies).forEach(function(el) { + el.addEventListener('change', function(event) { + const target = event.target; + if (target.classList.contains('action-select')) { + const checkboxes = affectedCheckboxes(target, shiftPressed); + checker(checkboxes, options, target.checked); + updateCounter(actionCheckboxes, options); + lastChecked = target; + } else { + list_editable_changed = true; + } + }); + }); + + document.querySelector('#changelist-form button[name=index]').addEventListener('click', function(event) { + if (list_editable_changed) { + const confirmed = confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); + if (!confirmed) { + event.preventDefault(); + } + } + }); + + const el = document.querySelector('#changelist-form input[name=_save]'); + // The button does not exist if no fields are editable. + if (el) { + el.addEventListener('click', function(event) { + if (document.querySelector('[name=action]').value) { + const text = list_editable_changed + ? gettext("You have selected an action, but you haven’t saved your changes to individual fields yet. Please click OK to save. You’ll need to re-run the action.") + : gettext("You have selected an action, and you haven’t made any changes on individual fields. You’re probably looking for the Go button rather than the Save button."); + if (!confirm(text)) { + event.preventDefault(); + } + } + }); + } + }; + + // Call function fn when the DOM is loaded and ready. If it is already + // loaded, call the function now. + // http://youmightnotneedjquery.com/#ready + function ready(fn) { + if (document.readyState !== 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); + } + } + + ready(function() { + const actionsEls = document.querySelectorAll('tr input.action-select'); + if (actionsEls.length > 0) { + Actions(actionsEls); + } + }); +} diff --git a/staticfiles/admin/js/admin/DateTimeShortcuts.js b/staticfiles/admin/js/admin/DateTimeShortcuts.js new file mode 100644 index 0000000..aa1cae9 --- /dev/null +++ b/staticfiles/admin/js/admin/DateTimeShortcuts.js @@ -0,0 +1,408 @@ +/*global Calendar, findPosX, findPosY, get_format, gettext, gettext_noop, interpolate, ngettext, quickElement*/ +// Inserts shortcut buttons after all of the following: +// +// +'use strict'; +{ + const DateTimeShortcuts = { + calendars: [], + calendarInputs: [], + clockInputs: [], + clockHours: { + default_: [ + [gettext_noop('Now'), -1], + [gettext_noop('Midnight'), 0], + [gettext_noop('6 a.m.'), 6], + [gettext_noop('Noon'), 12], + [gettext_noop('6 p.m.'), 18] + ] + }, + dismissClockFunc: [], + dismissCalendarFunc: [], + calendarDivName1: 'calendarbox', // name of calendar
    that gets toggled + calendarDivName2: 'calendarin', // name of
    that contains calendar + calendarLinkName: 'calendarlink', // name of the link that is used to toggle + clockDivName: 'clockbox', // name of clock
    that gets toggled + clockLinkName: 'clocklink', // name of the link that is used to toggle + shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts + timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch + timezoneOffset: 0, + init: function() { + const serverOffset = document.body.dataset.adminUtcOffset; + if (serverOffset) { + const localOffset = new Date().getTimezoneOffset() * -60; + DateTimeShortcuts.timezoneOffset = localOffset - serverOffset; + } + + for (const inp of document.getElementsByTagName('input')) { + if (inp.type === 'text' && inp.classList.contains('vTimeField')) { + DateTimeShortcuts.addClock(inp); + DateTimeShortcuts.addTimezoneWarning(inp); + } + else if (inp.type === 'text' && inp.classList.contains('vDateField')) { + DateTimeShortcuts.addCalendar(inp); + DateTimeShortcuts.addTimezoneWarning(inp); + } + } + }, + // Return the current time while accounting for the server timezone. + now: function() { + const serverOffset = document.body.dataset.adminUtcOffset; + if (serverOffset) { + const localNow = new Date(); + const localOffset = localNow.getTimezoneOffset() * -60; + localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset)); + return localNow; + } else { + return new Date(); + } + }, + // Add a warning when the time zone in the browser and backend do not match. + addTimezoneWarning: function(inp) { + const warningClass = DateTimeShortcuts.timezoneWarningClass; + let timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600; + + // Only warn if there is a time zone mismatch. + if (!timezoneOffset) { + return; + } + + // Check if warning is already there. + if (inp.parentNode.querySelectorAll('.' + warningClass).length) { + return; + } + + let message; + if (timezoneOffset > 0) { + message = ngettext( + 'Note: You are %s hour ahead of server time.', + 'Note: You are %s hours ahead of server time.', + timezoneOffset + ); + } + else { + timezoneOffset *= -1; + message = ngettext( + 'Note: You are %s hour behind server time.', + 'Note: You are %s hours behind server time.', + timezoneOffset + ); + } + message = interpolate(message, [timezoneOffset]); + + const warning = document.createElement('div'); + warning.classList.add('help', warningClass); + warning.textContent = message; + inp.parentNode.appendChild(warning); + }, + // Add clock widget to a given field + addClock: function(inp) { + const num = DateTimeShortcuts.clockInputs.length; + DateTimeShortcuts.clockInputs[num] = inp; + DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; }; + + // Shortcut links (clock icon and "Now" link) + const shortcuts_span = document.createElement('span'); + shortcuts_span.className = DateTimeShortcuts.shortCutsClass; + inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); + const now_link = document.createElement('a'); + now_link.href = "#"; + now_link.textContent = gettext('Now'); + now_link.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.handleClockQuicklink(num, -1); + }); + const clock_link = document.createElement('a'); + clock_link.href = '#'; + clock_link.id = DateTimeShortcuts.clockLinkName + num; + clock_link.addEventListener('click', function(e) { + e.preventDefault(); + // avoid triggering the document click handler to dismiss the clock + e.stopPropagation(); + DateTimeShortcuts.openClock(num); + }); + + quickElement( + 'span', clock_link, '', + 'class', 'clock-icon', + 'title', gettext('Choose a Time') + ); + shortcuts_span.appendChild(document.createTextNode('\u00A0')); + shortcuts_span.appendChild(now_link); + shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); + shortcuts_span.appendChild(clock_link); + + // Create clock link div + // + // Markup looks like: + //
    + //

    Choose a time

    + // + //

    Cancel

    + //
    + + const clock_box = document.createElement('div'); + clock_box.style.display = 'none'; + clock_box.style.position = 'absolute'; + clock_box.className = 'clockbox module'; + clock_box.id = DateTimeShortcuts.clockDivName + num; + document.body.appendChild(clock_box); + clock_box.addEventListener('click', function(e) { e.stopPropagation(); }); + + quickElement('h2', clock_box, gettext('Choose a time')); + const time_list = quickElement('ul', clock_box); + time_list.className = 'timelist'; + // The list of choices can be overridden in JavaScript like this: + // DateTimeShortcuts.clockHours.name = [['3 a.m.', 3]]; + // where name is the name attribute of the . + const name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name; + DateTimeShortcuts.clockHours[name].forEach(function(element) { + const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'href', '#'); + time_link.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.handleClockQuicklink(num, element[1]); + }); + }); + + const cancel_p = quickElement('p', clock_box); + cancel_p.className = 'calendar-cancel'; + const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#'); + cancel_link.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.dismissClock(num); + }); + + document.addEventListener('keyup', function(event) { + if (event.which === 27) { + // ESC key closes popup + DateTimeShortcuts.dismissClock(num); + event.preventDefault(); + } + }); + }, + openClock: function(num) { + const clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num); + const clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num); + + // Recalculate the clockbox position + // is it left-to-right or right-to-left layout ? + if (window.getComputedStyle(document.body).direction !== 'rtl') { + clock_box.style.left = findPosX(clock_link) + 17 + 'px'; + } + else { + // since style's width is in em, it'd be tough to calculate + // px value of it. let's use an estimated px for now + clock_box.style.left = findPosX(clock_link) - 110 + 'px'; + } + clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px'; + + // Show the clock box + clock_box.style.display = 'block'; + document.addEventListener('click', DateTimeShortcuts.dismissClockFunc[num]); + }, + dismissClock: function(num) { + document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none'; + document.removeEventListener('click', DateTimeShortcuts.dismissClockFunc[num]); + }, + handleClockQuicklink: function(num, val) { + let d; + if (val === -1) { + d = DateTimeShortcuts.now(); + } + else { + d = new Date(1970, 1, 1, val, 0, 0, 0); + } + DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]); + DateTimeShortcuts.clockInputs[num].focus(); + DateTimeShortcuts.dismissClock(num); + }, + // Add calendar widget to a given field. + addCalendar: function(inp) { + const num = DateTimeShortcuts.calendars.length; + + DateTimeShortcuts.calendarInputs[num] = inp; + DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; }; + + // Shortcut links (calendar icon and "Today" link) + const shortcuts_span = document.createElement('span'); + shortcuts_span.className = DateTimeShortcuts.shortCutsClass; + inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); + const today_link = document.createElement('a'); + today_link.href = '#'; + today_link.appendChild(document.createTextNode(gettext('Today'))); + today_link.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.handleCalendarQuickLink(num, 0); + }); + const cal_link = document.createElement('a'); + cal_link.href = '#'; + cal_link.id = DateTimeShortcuts.calendarLinkName + num; + cal_link.addEventListener('click', function(e) { + e.preventDefault(); + // avoid triggering the document click handler to dismiss the calendar + e.stopPropagation(); + DateTimeShortcuts.openCalendar(num); + }); + quickElement( + 'span', cal_link, '', + 'class', 'date-icon', + 'title', gettext('Choose a Date') + ); + shortcuts_span.appendChild(document.createTextNode('\u00A0')); + shortcuts_span.appendChild(today_link); + shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0')); + shortcuts_span.appendChild(cal_link); + + // Create calendarbox div. + // + // Markup looks like: + // + //
    + //

    + // + // February 2003 + //

    + //
    + // + //
    + //
    + // Yesterday | Today | Tomorrow + //
    + //

    Cancel

    + //
    + const cal_box = document.createElement('div'); + cal_box.style.display = 'none'; + cal_box.style.position = 'absolute'; + cal_box.className = 'calendarbox module'; + cal_box.id = DateTimeShortcuts.calendarDivName1 + num; + document.body.appendChild(cal_box); + cal_box.addEventListener('click', function(e) { e.stopPropagation(); }); + + // next-prev links + const cal_nav = quickElement('div', cal_box); + const cal_nav_prev = quickElement('a', cal_nav, '<', 'href', '#'); + cal_nav_prev.className = 'calendarnav-previous'; + cal_nav_prev.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.drawPrev(num); + }); + + const cal_nav_next = quickElement('a', cal_nav, '>', 'href', '#'); + cal_nav_next.className = 'calendarnav-next'; + cal_nav_next.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.drawNext(num); + }); + + // main box + const cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num); + cal_main.className = 'calendar'; + DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num)); + DateTimeShortcuts.calendars[num].drawCurrent(); + + // calendar shortcuts + const shortcuts = quickElement('div', cal_box); + shortcuts.className = 'calendar-shortcuts'; + let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'href', '#'); + day_link.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.handleCalendarQuickLink(num, -1); + }); + shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); + day_link = quickElement('a', shortcuts, gettext('Today'), 'href', '#'); + day_link.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.handleCalendarQuickLink(num, 0); + }); + shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); + day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'href', '#'); + day_link.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.handleCalendarQuickLink(num, +1); + }); + + // cancel bar + const cancel_p = quickElement('p', cal_box); + cancel_p.className = 'calendar-cancel'; + const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#'); + cancel_link.addEventListener('click', function(e) { + e.preventDefault(); + DateTimeShortcuts.dismissCalendar(num); + }); + document.addEventListener('keyup', function(event) { + if (event.which === 27) { + // ESC key closes popup + DateTimeShortcuts.dismissCalendar(num); + event.preventDefault(); + } + }); + }, + openCalendar: function(num) { + const cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num); + const cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num); + const inp = DateTimeShortcuts.calendarInputs[num]; + + // Determine if the current value in the input has a valid date. + // If so, draw the calendar with that date's year and month. + if (inp.value) { + const format = get_format('DATE_INPUT_FORMATS')[0]; + const selected = inp.value.strptime(format); + const year = selected.getUTCFullYear(); + const month = selected.getUTCMonth() + 1; + const re = /\d{4}/; + if (re.test(year.toString()) && month >= 1 && month <= 12) { + DateTimeShortcuts.calendars[num].drawDate(month, year, selected); + } + } + + // Recalculate the clockbox position + // is it left-to-right or right-to-left layout ? + if (window.getComputedStyle(document.body).direction !== 'rtl') { + cal_box.style.left = findPosX(cal_link) + 17 + 'px'; + } + else { + // since style's width is in em, it'd be tough to calculate + // px value of it. let's use an estimated px for now + cal_box.style.left = findPosX(cal_link) - 180 + 'px'; + } + cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px'; + + cal_box.style.display = 'block'; + document.addEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]); + }, + dismissCalendar: function(num) { + document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none'; + document.removeEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]); + }, + drawPrev: function(num) { + DateTimeShortcuts.calendars[num].drawPreviousMonth(); + }, + drawNext: function(num) { + DateTimeShortcuts.calendars[num].drawNextMonth(); + }, + handleCalendarCallback: function(num) { + const format = get_format('DATE_INPUT_FORMATS')[0]; + return function(y, m, d) { + DateTimeShortcuts.calendarInputs[num].value = new Date(y, m - 1, d).strftime(format); + DateTimeShortcuts.calendarInputs[num].focus(); + document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none'; + }; + }, + handleCalendarQuickLink: function(num, offset) { + const d = DateTimeShortcuts.now(); + d.setDate(d.getDate() + offset); + DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]); + DateTimeShortcuts.calendarInputs[num].focus(); + DateTimeShortcuts.dismissCalendar(num); + } + }; + + window.addEventListener('load', DateTimeShortcuts.init); + window.DateTimeShortcuts = DateTimeShortcuts; +} diff --git a/staticfiles/admin/js/admin/RelatedObjectLookups.js b/staticfiles/admin/js/admin/RelatedObjectLookups.js new file mode 100644 index 0000000..afb6b66 --- /dev/null +++ b/staticfiles/admin/js/admin/RelatedObjectLookups.js @@ -0,0 +1,238 @@ +/*global SelectBox, interpolate*/ +// Handles related-objects functionality: lookup link for raw_id_fields +// and Add Another links. +'use strict'; +{ + const $ = django.jQuery; + let popupIndex = 0; + const relatedWindows = []; + + function dismissChildPopups() { + relatedWindows.forEach(function(win) { + if(!win.closed) { + win.dismissChildPopups(); + win.close(); + } + }); + } + + function setPopupIndex() { + if(document.getElementsByName("_popup").length > 0) { + const index = window.name.lastIndexOf("__") + 2; + popupIndex = parseInt(window.name.substring(index)); + } else { + popupIndex = 0; + } + } + + function addPopupIndex(name) { + return name + "__" + (popupIndex + 1); + } + + function removePopupIndex(name) { + return name.replace(new RegExp("__" + (popupIndex + 1) + "$"), ''); + } + + function showAdminPopup(triggeringLink, name_regexp, add_popup) { + const name = addPopupIndex(triggeringLink.id.replace(name_regexp, '')); + const href = new URL(triggeringLink.href); + if (add_popup) { + href.searchParams.set('_popup', 1); + } + const win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); + relatedWindows.push(win); + win.focus(); + return false; + } + + function showRelatedObjectLookupPopup(triggeringLink) { + return showAdminPopup(triggeringLink, /^lookup_/, true); + } + + function dismissRelatedLookupPopup(win, chosenId) { + const name = removePopupIndex(win.name); + const elem = document.getElementById(name); + if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) { + elem.value += ',' + chosenId; + } else { + document.getElementById(name).value = chosenId; + } + const index = relatedWindows.indexOf(win); + if (index > -1) { + relatedWindows.splice(index, 1); + } + win.close(); + } + + function showRelatedObjectPopup(triggeringLink) { + return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false); + } + + function updateRelatedObjectLinks(triggeringLink) { + const $this = $(triggeringLink); + const siblings = $this.nextAll('.view-related, .change-related, .delete-related'); + if (!siblings.length) { + return; + } + const value = $this.val(); + if (value) { + siblings.each(function() { + const elm = $(this); + elm.attr('href', elm.attr('data-href-template').replace('__fk__', value)); + }); + } else { + siblings.removeAttr('href'); + } + } + + function updateRelatedSelectsOptions(currentSelect, win, objId, newRepr, newId) { + // After create/edit a model from the options next to the current + // select (+ or :pencil:) update ForeignKey PK of the rest of selects + // in the page. + + const path = win.location.pathname; + // Extract the model from the popup url '...//add/' or + // '...///change/' depending the action (add or change). + const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)]; + // Exclude autocomplete selects. + const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] select:not(.admin-autocomplete)`); + + selectsRelated.forEach(function(select) { + if (currentSelect === select) { + return; + } + + let option = select.querySelector(`option[value="${objId}"]`); + + if (!option) { + option = new Option(newRepr, newId); + select.options.add(option); + return; + } + + option.textContent = newRepr; + option.value = newId; + }); + } + + function dismissAddRelatedObjectPopup(win, newId, newRepr) { + const name = removePopupIndex(win.name); + const elem = document.getElementById(name); + if (elem) { + const elemName = elem.nodeName.toUpperCase(); + if (elemName === 'SELECT') { + elem.options[elem.options.length] = new Option(newRepr, newId, true, true); + updateRelatedSelectsOptions(elem, win, null, newRepr, newId); + } else if (elemName === 'INPUT') { + if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) { + elem.value += ',' + newId; + } else { + elem.value = newId; + } + } + // Trigger a change event to update related links if required. + $(elem).trigger('change'); + } else { + const toId = name + "_to"; + const o = new Option(newRepr, newId); + SelectBox.add_to_cache(toId, o); + SelectBox.redisplay(toId); + } + const index = relatedWindows.indexOf(win); + if (index > -1) { + relatedWindows.splice(index, 1); + } + win.close(); + } + + function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) { + const id = removePopupIndex(win.name.replace(/^edit_/, '')); + const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); + const selects = $(selectsSelector); + selects.find('option').each(function() { + if (this.value === objId) { + this.textContent = newRepr; + this.value = newId; + } + }).trigger('change'); + updateRelatedSelectsOptions(selects[0], win, objId, newRepr, newId); + selects.next().find('.select2-selection__rendered').each(function() { + // The element can have a clear button as a child. + // Use the lastChild to modify only the displayed value. + this.lastChild.textContent = newRepr; + this.title = newRepr; + }); + const index = relatedWindows.indexOf(win); + if (index > -1) { + relatedWindows.splice(index, 1); + } + win.close(); + } + + function dismissDeleteRelatedObjectPopup(win, objId) { + const id = removePopupIndex(win.name.replace(/^delete_/, '')); + const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]); + const selects = $(selectsSelector); + selects.find('option').each(function() { + if (this.value === objId) { + $(this).remove(); + } + }).trigger('change'); + const index = relatedWindows.indexOf(win); + if (index > -1) { + relatedWindows.splice(index, 1); + } + win.close(); + } + + window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup; + window.dismissRelatedLookupPopup = dismissRelatedLookupPopup; + window.showRelatedObjectPopup = showRelatedObjectPopup; + window.updateRelatedObjectLinks = updateRelatedObjectLinks; + window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup; + window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup; + window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup; + window.dismissChildPopups = dismissChildPopups; + + // Kept for backward compatibility + window.showAddAnotherPopup = showRelatedObjectPopup; + window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup; + + window.addEventListener('unload', function(evt) { + window.dismissChildPopups(); + }); + + $(document).ready(function() { + setPopupIndex(); + $("a[data-popup-opener]").on('click', function(event) { + event.preventDefault(); + opener.dismissRelatedLookupPopup(window, $(this).data("popup-opener")); + }); + $('body').on('click', '.related-widget-wrapper-link[data-popup="yes"]', function(e) { + e.preventDefault(); + if (this.href) { + const event = $.Event('django:show-related', {href: this.href}); + $(this).trigger(event); + if (!event.isDefaultPrevented()) { + showRelatedObjectPopup(this); + } + } + }); + $('body').on('change', '.related-widget-wrapper select', function(e) { + const event = $.Event('django:update-related'); + $(this).trigger(event); + if (!event.isDefaultPrevented()) { + updateRelatedObjectLinks(this); + } + }); + $('.related-widget-wrapper select').trigger('change'); + $('body').on('click', '.related-lookup', function(e) { + e.preventDefault(); + const event = $.Event('django:lookup-related'); + $(this).trigger(event); + if (!event.isDefaultPrevented()) { + showRelatedObjectLookupPopup(this); + } + }); + }); +} diff --git a/staticfiles/admin/js/autocomplete.js b/staticfiles/admin/js/autocomplete.js new file mode 100644 index 0000000..d3daeab --- /dev/null +++ b/staticfiles/admin/js/autocomplete.js @@ -0,0 +1,33 @@ +'use strict'; +{ + const $ = django.jQuery; + + $.fn.djangoAdminSelect2 = function() { + $.each(this, function(i, element) { + $(element).select2({ + ajax: { + data: (params) => { + return { + term: params.term, + page: params.page, + app_label: element.dataset.appLabel, + model_name: element.dataset.modelName, + field_name: element.dataset.fieldName + }; + } + } + }); + }); + return this; + }; + + $(function() { + // Initialize all autocomplete widgets except the one in the template + // form used when a new formset is added. + $('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2(); + }); + + document.addEventListener('formset:added', (event) => { + $(event.target).find('.admin-autocomplete').djangoAdminSelect2(); + }); +} diff --git a/staticfiles/admin/js/calendar.js b/staticfiles/admin/js/calendar.js new file mode 100644 index 0000000..a62d10a --- /dev/null +++ b/staticfiles/admin/js/calendar.js @@ -0,0 +1,221 @@ +/*global gettext, pgettext, get_format, quickElement, removeChildren*/ +/* +calendar.js - Calendar functions by Adrian Holovaty +depends on core.js for utility functions like removeChildren or quickElement +*/ +'use strict'; +{ + // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions + const CalendarNamespace = { + monthsOfYear: [ + gettext('January'), + gettext('February'), + gettext('March'), + gettext('April'), + gettext('May'), + gettext('June'), + gettext('July'), + gettext('August'), + gettext('September'), + gettext('October'), + gettext('November'), + gettext('December') + ], + monthsOfYearAbbrev: [ + pgettext('abbrev. month January', 'Jan'), + pgettext('abbrev. month February', 'Feb'), + pgettext('abbrev. month March', 'Mar'), + pgettext('abbrev. month April', 'Apr'), + pgettext('abbrev. month May', 'May'), + pgettext('abbrev. month June', 'Jun'), + pgettext('abbrev. month July', 'Jul'), + pgettext('abbrev. month August', 'Aug'), + pgettext('abbrev. month September', 'Sep'), + pgettext('abbrev. month October', 'Oct'), + pgettext('abbrev. month November', 'Nov'), + pgettext('abbrev. month December', 'Dec') + ], + daysOfWeek: [ + pgettext('one letter Sunday', 'S'), + pgettext('one letter Monday', 'M'), + pgettext('one letter Tuesday', 'T'), + pgettext('one letter Wednesday', 'W'), + pgettext('one letter Thursday', 'T'), + pgettext('one letter Friday', 'F'), + pgettext('one letter Saturday', 'S') + ], + firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')), + isLeapYear: function(year) { + return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0)); + }, + getDaysInMonth: function(month, year) { + let days; + if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) { + days = 31; + } + else if (month === 4 || month === 6 || month === 9 || month === 11) { + days = 30; + } + else if (month === 2 && CalendarNamespace.isLeapYear(year)) { + days = 29; + } + else { + days = 28; + } + return days; + }, + draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999 + const today = new Date(); + const todayDay = today.getDate(); + const todayMonth = today.getMonth() + 1; + const todayYear = today.getFullYear(); + let todayClass = ''; + + // Use UTC functions here because the date field does not contain time + // and using the UTC function variants prevent the local time offset + // from altering the date, specifically the day field. For example: + // + // ``` + // var x = new Date('2013-10-02'); + // var day = x.getDate(); + // ``` + // + // The day variable above will be 1 instead of 2 in, say, US Pacific time + // zone. + let isSelectedMonth = false; + if (typeof selected !== 'undefined') { + isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month); + } + + month = parseInt(month); + year = parseInt(year); + const calDiv = document.getElementById(div_id); + removeChildren(calDiv); + const calTable = document.createElement('table'); + quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year); + const tableBody = quickElement('tbody', calTable); + + // Draw days-of-week header + let tableRow = quickElement('tr', tableBody); + for (let i = 0; i < 7; i++) { + quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]); + } + + const startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); + const days = CalendarNamespace.getDaysInMonth(month, year); + + let nonDayCell; + + // Draw blanks before first of month + tableRow = quickElement('tr', tableBody); + for (let i = 0; i < startingPos; i++) { + nonDayCell = quickElement('td', tableRow, ' '); + nonDayCell.className = "nonday"; + } + + function calendarMonth(y, m) { + function onClick(e) { + e.preventDefault(); + callback(y, m, this.textContent); + } + return onClick; + } + + // Draw days of month + let currentDay = 1; + for (let i = startingPos; currentDay <= days; i++) { + if (i % 7 === 0 && currentDay !== 1) { + tableRow = quickElement('tr', tableBody); + } + if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) { + todayClass = 'today'; + } else { + todayClass = ''; + } + + // use UTC function; see above for explanation. + if (isSelectedMonth && currentDay === selected.getUTCDate()) { + if (todayClass !== '') { + todayClass += " "; + } + todayClass += "selected"; + } + + const cell = quickElement('td', tableRow, '', 'class', todayClass); + const link = quickElement('a', cell, currentDay, 'href', '#'); + link.addEventListener('click', calendarMonth(year, month)); + currentDay++; + } + + // Draw blanks after end of month (optional, but makes for valid code) + while (tableRow.childNodes.length < 7) { + nonDayCell = quickElement('td', tableRow, ' '); + nonDayCell.className = "nonday"; + } + + calDiv.appendChild(calTable); + } + }; + + // Calendar -- A calendar instance + function Calendar(div_id, callback, selected) { + // div_id (string) is the ID of the element in which the calendar will + // be displayed + // callback (string) is the name of a JavaScript function that will be + // called with the parameters (year, month, day) when a day in the + // calendar is clicked + this.div_id = div_id; + this.callback = callback; + this.today = new Date(); + this.currentMonth = this.today.getMonth() + 1; + this.currentYear = this.today.getFullYear(); + if (typeof selected !== 'undefined') { + this.selected = selected; + } + } + Calendar.prototype = { + drawCurrent: function() { + CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected); + }, + drawDate: function(month, year, selected) { + this.currentMonth = month; + this.currentYear = year; + + if(selected) { + this.selected = selected; + } + + this.drawCurrent(); + }, + drawPreviousMonth: function() { + if (this.currentMonth === 1) { + this.currentMonth = 12; + this.currentYear--; + } + else { + this.currentMonth--; + } + this.drawCurrent(); + }, + drawNextMonth: function() { + if (this.currentMonth === 12) { + this.currentMonth = 1; + this.currentYear++; + } + else { + this.currentMonth++; + } + this.drawCurrent(); + }, + drawPreviousYear: function() { + this.currentYear--; + this.drawCurrent(); + }, + drawNextYear: function() { + this.currentYear++; + this.drawCurrent(); + } + }; + window.Calendar = Calendar; + window.CalendarNamespace = CalendarNamespace; +} diff --git a/staticfiles/admin/js/cancel.js b/staticfiles/admin/js/cancel.js new file mode 100644 index 0000000..3069c6f --- /dev/null +++ b/staticfiles/admin/js/cancel.js @@ -0,0 +1,29 @@ +'use strict'; +{ + // Call function fn when the DOM is loaded and ready. If it is already + // loaded, call the function now. + // http://youmightnotneedjquery.com/#ready + function ready(fn) { + if (document.readyState !== 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); + } + } + + ready(function() { + function handleClick(event) { + event.preventDefault(); + const params = new URLSearchParams(window.location.search); + if (params.has('_popup')) { + window.close(); // Close the popup. + } else { + window.history.back(); // Otherwise, go back. + } + } + + document.querySelectorAll('.cancel-link').forEach(function(el) { + el.addEventListener('click', handleClick); + }); + }); +} diff --git a/staticfiles/admin/js/change_form.js b/staticfiles/admin/js/change_form.js new file mode 100644 index 0000000..96a4c62 --- /dev/null +++ b/staticfiles/admin/js/change_form.js @@ -0,0 +1,16 @@ +'use strict'; +{ + const inputTags = ['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA']; + const modelName = document.getElementById('django-admin-form-add-constants').dataset.modelName; + if (modelName) { + const form = document.getElementById(modelName + '_form'); + for (const element of form.elements) { + // HTMLElement.offsetParent returns null when the element is not + // rendered. + if (inputTags.includes(element.tagName) && !element.disabled && element.offsetParent) { + element.focus(); + break; + } + } + } +} diff --git a/staticfiles/admin/js/collapse.js b/staticfiles/admin/js/collapse.js new file mode 100644 index 0000000..c6c7b0f --- /dev/null +++ b/staticfiles/admin/js/collapse.js @@ -0,0 +1,43 @@ +/*global gettext*/ +'use strict'; +{ + window.addEventListener('load', function() { + // Add anchor tag for Show/Hide link + const fieldsets = document.querySelectorAll('fieldset.collapse'); + for (const [i, elem] of fieldsets.entries()) { + // Don't hide if fields in this fieldset have errors + if (elem.querySelectorAll('div.errors, ul.errorlist').length === 0) { + elem.classList.add('collapsed'); + const h2 = elem.querySelector('h2'); + const link = document.createElement('a'); + link.id = 'fieldsetcollapser' + i; + link.className = 'collapse-toggle'; + link.href = '#'; + link.textContent = gettext('Show'); + h2.appendChild(document.createTextNode(' (')); + h2.appendChild(link); + h2.appendChild(document.createTextNode(')')); + } + } + // Add toggle to hide/show anchor tag + const toggleFunc = function(ev) { + if (ev.target.matches('.collapse-toggle')) { + ev.preventDefault(); + ev.stopPropagation(); + const fieldset = ev.target.closest('fieldset'); + if (fieldset.classList.contains('collapsed')) { + // Show + ev.target.textContent = gettext('Hide'); + fieldset.classList.remove('collapsed'); + } else { + // Hide + ev.target.textContent = gettext('Show'); + fieldset.classList.add('collapsed'); + } + } + }; + document.querySelectorAll('fieldset.module').forEach(function(el) { + el.addEventListener('click', toggleFunc); + }); + }); +} diff --git a/staticfiles/admin/js/core.js b/staticfiles/admin/js/core.js new file mode 100644 index 0000000..0344a13 --- /dev/null +++ b/staticfiles/admin/js/core.js @@ -0,0 +1,170 @@ +// Core JavaScript helper functions +'use strict'; + +// quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); +function quickElement() { + const obj = document.createElement(arguments[0]); + if (arguments[2]) { + const textNode = document.createTextNode(arguments[2]); + obj.appendChild(textNode); + } + const len = arguments.length; + for (let i = 3; i < len; i += 2) { + obj.setAttribute(arguments[i], arguments[i + 1]); + } + arguments[1].appendChild(obj); + return obj; +} + +// "a" is reference to an object +function removeChildren(a) { + while (a.hasChildNodes()) { + a.removeChild(a.lastChild); + } +} + +// ---------------------------------------------------------------------------- +// Find-position functions by PPK +// See https://www.quirksmode.org/js/findpos.html +// ---------------------------------------------------------------------------- +function findPosX(obj) { + let curleft = 0; + if (obj.offsetParent) { + while (obj.offsetParent) { + curleft += obj.offsetLeft - obj.scrollLeft; + obj = obj.offsetParent; + } + } else if (obj.x) { + curleft += obj.x; + } + return curleft; +} + +function findPosY(obj) { + let curtop = 0; + if (obj.offsetParent) { + while (obj.offsetParent) { + curtop += obj.offsetTop - obj.scrollTop; + obj = obj.offsetParent; + } + } else if (obj.y) { + curtop += obj.y; + } + return curtop; +} + +//----------------------------------------------------------------------------- +// Date object extensions +// ---------------------------------------------------------------------------- +{ + Date.prototype.getTwelveHours = function() { + return this.getHours() % 12 || 12; + }; + + Date.prototype.getTwoDigitMonth = function() { + return (this.getMonth() < 9) ? '0' + (this.getMonth() + 1) : (this.getMonth() + 1); + }; + + Date.prototype.getTwoDigitDate = function() { + return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); + }; + + Date.prototype.getTwoDigitTwelveHour = function() { + return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); + }; + + Date.prototype.getTwoDigitHour = function() { + return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); + }; + + Date.prototype.getTwoDigitMinute = function() { + return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); + }; + + Date.prototype.getTwoDigitSecond = function() { + return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); + }; + + Date.prototype.getAbbrevMonthName = function() { + return typeof window.CalendarNamespace === "undefined" + ? this.getTwoDigitMonth() + : window.CalendarNamespace.monthsOfYearAbbrev[this.getMonth()]; + }; + + Date.prototype.getFullMonthName = function() { + return typeof window.CalendarNamespace === "undefined" + ? this.getTwoDigitMonth() + : window.CalendarNamespace.monthsOfYear[this.getMonth()]; + }; + + Date.prototype.strftime = function(format) { + const fields = { + b: this.getAbbrevMonthName(), + B: this.getFullMonthName(), + c: this.toString(), + d: this.getTwoDigitDate(), + H: this.getTwoDigitHour(), + I: this.getTwoDigitTwelveHour(), + m: this.getTwoDigitMonth(), + M: this.getTwoDigitMinute(), + p: (this.getHours() >= 12) ? 'PM' : 'AM', + S: this.getTwoDigitSecond(), + w: '0' + this.getDay(), + x: this.toLocaleDateString(), + X: this.toLocaleTimeString(), + y: ('' + this.getFullYear()).substr(2, 4), + Y: '' + this.getFullYear(), + '%': '%' + }; + let result = '', i = 0; + while (i < format.length) { + if (format.charAt(i) === '%') { + result += fields[format.charAt(i + 1)]; + ++i; + } + else { + result += format.charAt(i); + } + ++i; + } + return result; + }; + + // ---------------------------------------------------------------------------- + // String object extensions + // ---------------------------------------------------------------------------- + String.prototype.strptime = function(format) { + const split_format = format.split(/[.\-/]/); + const date = this.split(/[.\-/]/); + let i = 0; + let day, month, year; + while (i < split_format.length) { + switch (split_format[i]) { + case "%d": + day = date[i]; + break; + case "%m": + month = date[i] - 1; + break; + case "%Y": + year = date[i]; + break; + case "%y": + // A %y value in the range of [00, 68] is in the current + // century, while [69, 99] is in the previous century, + // according to the Open Group Specification. + if (parseInt(date[i], 10) >= 69) { + year = date[i]; + } else { + year = (new Date(Date.UTC(date[i], 0))).getUTCFullYear() + 100; + } + break; + } + ++i; + } + // Create Date object from UTC since the parsed value is supposed to be + // in UTC, not local time. Also, the calendar uses UTC functions for + // date extraction. + return new Date(Date.UTC(year, month, day)); + }; +} diff --git a/staticfiles/admin/js/filters.js b/staticfiles/admin/js/filters.js new file mode 100644 index 0000000..f5536eb --- /dev/null +++ b/staticfiles/admin/js/filters.js @@ -0,0 +1,30 @@ +/** + * Persist changelist filters state (collapsed/expanded). + */ +'use strict'; +{ + // Init filters. + let filters = JSON.parse(sessionStorage.getItem('django.admin.filtersState')); + + if (!filters) { + filters = {}; + } + + Object.entries(filters).forEach(([key, value]) => { + const detailElement = document.querySelector(`[data-filter-title='${CSS.escape(key)}']`); + + // Check if the filter is present, it could be from other view. + if (detailElement) { + value ? detailElement.setAttribute('open', '') : detailElement.removeAttribute('open'); + } + }); + + // Save filter state when clicks. + const details = document.querySelectorAll('details'); + details.forEach(detail => { + detail.addEventListener('toggle', event => { + filters[`${event.target.dataset.filterTitle}`] = detail.open; + sessionStorage.setItem('django.admin.filtersState', JSON.stringify(filters)); + }); + }); +} diff --git a/staticfiles/admin/js/inlines.js b/staticfiles/admin/js/inlines.js new file mode 100644 index 0000000..e9a1dfe --- /dev/null +++ b/staticfiles/admin/js/inlines.js @@ -0,0 +1,359 @@ +/*global DateTimeShortcuts, SelectFilter*/ +/** + * Django admin inlines + * + * Based on jQuery Formset 1.1 + * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com) + * @requires jQuery 1.2.6 or later + * + * Copyright (c) 2009, Stanislaus Madueke + * All rights reserved. + * + * Spiced up with Code from Zain Memon's GSoC project 2009 + * and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip. + * + * Licensed under the New BSD License + * See: https://opensource.org/licenses/bsd-license.php + */ +'use strict'; +{ + const $ = django.jQuery; + $.fn.formset = function(opts) { + const options = $.extend({}, $.fn.formset.defaults, opts); + const $this = $(this); + const $parent = $this.parent(); + const updateElementIndex = function(el, prefix, ndx) { + const id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))"); + const replacement = prefix + "-" + ndx; + if ($(el).prop("for")) { + $(el).prop("for", $(el).prop("for").replace(id_regex, replacement)); + } + if (el.id) { + el.id = el.id.replace(id_regex, replacement); + } + if (el.name) { + el.name = el.name.replace(id_regex, replacement); + } + }; + const totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off"); + let nextIndex = parseInt(totalForms.val(), 10); + const maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off"); + const minForms = $("#id_" + options.prefix + "-MIN_NUM_FORMS").prop("autocomplete", "off"); + let addButton; + + /** + * The "Add another MyModel" button below the inline forms. + */ + const addInlineAddButton = function() { + if (addButton === null) { + if ($this.prop("tagName") === "TR") { + // If forms are laid out as table rows, insert the + // "add" button in a new table row: + const numCols = $this.eq(-1).children().length; + $parent.append('' + options.addText + ""); + addButton = $parent.find("tr:last a"); + } else { + // Otherwise, insert it immediately after the last form: + $this.filter(":last").after('"); + addButton = $this.filter(":last").next().find("a"); + } + } + addButton.on('click', addInlineClickHandler); + }; + + const addInlineClickHandler = function(e) { + e.preventDefault(); + const template = $("#" + options.prefix + "-empty"); + const row = template.clone(true); + row.removeClass(options.emptyCssClass) + .addClass(options.formCssClass) + .attr("id", options.prefix + "-" + nextIndex); + addInlineDeleteButton(row); + row.find("*").each(function() { + updateElementIndex(this, options.prefix, totalForms.val()); + }); + // Insert the new form when it has been fully edited. + row.insertBefore($(template)); + // Update number of total forms. + $(totalForms).val(parseInt(totalForms.val(), 10) + 1); + nextIndex += 1; + // Hide the add button if there's a limit and it's been reached. + if ((maxForms.val() !== '') && (maxForms.val() - totalForms.val()) <= 0) { + addButton.parent().hide(); + } + // Show the remove buttons if there are more than min_num. + toggleDeleteButtonVisibility(row.closest('.inline-group')); + + // Pass the new form to the post-add callback, if provided. + if (options.added) { + options.added(row); + } + row.get(0).dispatchEvent(new CustomEvent("formset:added", { + bubbles: true, + detail: { + formsetName: options.prefix + } + })); + }; + + /** + * The "X" button that is part of every unsaved inline. + * (When saved, it is replaced with a "Delete" checkbox.) + */ + const addInlineDeleteButton = function(row) { + if (row.is("tr")) { + // If the forms are laid out in table rows, insert + // the remove button into the last table cell: + row.children(":last").append('"); + } else if (row.is("ul") || row.is("ol")) { + // If they're laid out as an ordered/unordered list, + // insert an
  • after the last list item: + row.append('
  • ' + options.deleteText + "
  • "); + } else { + // Otherwise, just insert the remove button as the + // last child element of the form's container: + row.children(":first").append('' + options.deleteText + ""); + } + // Add delete handler for each row. + row.find("a." + options.deleteCssClass).on('click', inlineDeleteHandler.bind(this)); + }; + + const inlineDeleteHandler = function(e1) { + e1.preventDefault(); + const deleteButton = $(e1.target); + const row = deleteButton.closest('.' + options.formCssClass); + const inlineGroup = row.closest('.inline-group'); + // Remove the parent form containing this button, + // and also remove the relevant row with non-field errors: + const prevRow = row.prev(); + if (prevRow.length && prevRow.hasClass('row-form-errors')) { + prevRow.remove(); + } + row.remove(); + nextIndex -= 1; + // Pass the deleted form to the post-delete callback, if provided. + if (options.removed) { + options.removed(row); + } + document.dispatchEvent(new CustomEvent("formset:removed", { + detail: { + formsetName: options.prefix + } + })); + // Update the TOTAL_FORMS form count. + const forms = $("." + options.formCssClass); + $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length); + // Show add button again once below maximum number. + if ((maxForms.val() === '') || (maxForms.val() - forms.length) > 0) { + addButton.parent().show(); + } + // Hide the remove buttons if at min_num. + toggleDeleteButtonVisibility(inlineGroup); + // Also, update names and ids for all remaining form controls so + // they remain in sequence: + let i, formCount; + const updateElementCallback = function() { + updateElementIndex(this, options.prefix, i); + }; + for (i = 0, formCount = forms.length; i < formCount; i++) { + updateElementIndex($(forms).get(i), options.prefix, i); + $(forms.get(i)).find("*").each(updateElementCallback); + } + }; + + const toggleDeleteButtonVisibility = function(inlineGroup) { + if ((minForms.val() !== '') && (minForms.val() - totalForms.val()) >= 0) { + inlineGroup.find('.inline-deletelink').hide(); + } else { + inlineGroup.find('.inline-deletelink').show(); + } + }; + + $this.each(function(i) { + $(this).not("." + options.emptyCssClass).addClass(options.formCssClass); + }); + + // Create the delete buttons for all unsaved inlines: + $this.filter('.' + options.formCssClass + ':not(.has_original):not(.' + options.emptyCssClass + ')').each(function() { + addInlineDeleteButton($(this)); + }); + toggleDeleteButtonVisibility($this); + + // Create the add button, initially hidden. + addButton = options.addButton; + addInlineAddButton(); + + // Show the add button if allowed to add more items. + // Note that max_num = None translates to a blank string. + const showAddButton = maxForms.val() === '' || (maxForms.val() - totalForms.val()) > 0; + if ($this.length && showAddButton) { + addButton.parent().show(); + } else { + addButton.parent().hide(); + } + + return this; + }; + + /* Setup plugin defaults */ + $.fn.formset.defaults = { + prefix: "form", // The form prefix for your django formset + addText: "add another", // Text for the add link + deleteText: "remove", // Text for the delete link + addCssClass: "add-row", // CSS class applied to the add link + deleteCssClass: "delete-row", // CSS class applied to the delete link + emptyCssClass: "empty-row", // CSS class applied to the empty row + formCssClass: "dynamic-form", // CSS class applied to each form in a formset + added: null, // Function called each time a new form is added + removed: null, // Function called each time a form is deleted + addButton: null // Existing add button to use + }; + + + // Tabular inlines --------------------------------------------------------- + $.fn.tabularFormset = function(selector, options) { + const $rows = $(this); + + const reinitDateTimeShortCuts = function() { + // Reinitialize the calendar and clock widgets by force + if (typeof DateTimeShortcuts !== "undefined") { + $(".datetimeshortcuts").remove(); + DateTimeShortcuts.init(); + } + }; + + const updateSelectFilter = function() { + // If any SelectFilter widgets are a part of the new form, + // instantiate a new SelectFilter instance for it. + if (typeof SelectFilter !== 'undefined') { + $('.selectfilter').each(function(index, value) { + SelectFilter.init(value.id, this.dataset.fieldName, false); + }); + $('.selectfilterstacked').each(function(index, value) { + SelectFilter.init(value.id, this.dataset.fieldName, true); + }); + } + }; + + const initPrepopulatedFields = function(row) { + row.find('.prepopulated_field').each(function() { + const field = $(this), + input = field.find('input, select, textarea'), + dependency_list = input.data('dependency_list') || [], + dependencies = []; + $.each(dependency_list, function(i, field_name) { + dependencies.push('#' + row.find('.field-' + field_name).find('input, select, textarea').attr('id')); + }); + if (dependencies.length) { + input.prepopulate(dependencies, input.attr('maxlength')); + } + }); + }; + + $rows.formset({ + prefix: options.prefix, + addText: options.addText, + formCssClass: "dynamic-" + options.prefix, + deleteCssClass: "inline-deletelink", + deleteText: options.deleteText, + emptyCssClass: "empty-form", + added: function(row) { + initPrepopulatedFields(row); + reinitDateTimeShortCuts(); + updateSelectFilter(); + }, + addButton: options.addButton + }); + + return $rows; + }; + + // Stacked inlines --------------------------------------------------------- + $.fn.stackedFormset = function(selector, options) { + const $rows = $(this); + const updateInlineLabel = function(row) { + $(selector).find(".inline_label").each(function(i) { + const count = i + 1; + $(this).html($(this).html().replace(/(#\d+)/g, "#" + count)); + }); + }; + + const reinitDateTimeShortCuts = function() { + // Reinitialize the calendar and clock widgets by force, yuck. + if (typeof DateTimeShortcuts !== "undefined") { + $(".datetimeshortcuts").remove(); + DateTimeShortcuts.init(); + } + }; + + const updateSelectFilter = function() { + // If any SelectFilter widgets were added, instantiate a new instance. + if (typeof SelectFilter !== "undefined") { + $(".selectfilter").each(function(index, value) { + SelectFilter.init(value.id, this.dataset.fieldName, false); + }); + $(".selectfilterstacked").each(function(index, value) { + SelectFilter.init(value.id, this.dataset.fieldName, true); + }); + } + }; + + const initPrepopulatedFields = function(row) { + row.find('.prepopulated_field').each(function() { + const field = $(this), + input = field.find('input, select, textarea'), + dependency_list = input.data('dependency_list') || [], + dependencies = []; + $.each(dependency_list, function(i, field_name) { + // Dependency in a fieldset. + let field_element = row.find('.form-row .field-' + field_name); + // Dependency without a fieldset. + if (!field_element.length) { + field_element = row.find('.form-row.field-' + field_name); + } + dependencies.push('#' + field_element.find('input, select, textarea').attr('id')); + }); + if (dependencies.length) { + input.prepopulate(dependencies, input.attr('maxlength')); + } + }); + }; + + $rows.formset({ + prefix: options.prefix, + addText: options.addText, + formCssClass: "dynamic-" + options.prefix, + deleteCssClass: "inline-deletelink", + deleteText: options.deleteText, + emptyCssClass: "empty-form", + removed: updateInlineLabel, + added: function(row) { + initPrepopulatedFields(row); + reinitDateTimeShortCuts(); + updateSelectFilter(); + updateInlineLabel(row); + }, + addButton: options.addButton + }); + + return $rows; + }; + + $(document).ready(function() { + $(".js-inline-admin-formset").each(function() { + const data = $(this).data(), + inlineOptions = data.inlineFormset; + let selector; + switch(data.inlineType) { + case "stacked": + selector = inlineOptions.name + "-group .inline-related"; + $(selector).stackedFormset(selector, inlineOptions.options); + break; + case "tabular": + selector = inlineOptions.name + "-group .tabular.inline-related tbody:first > tr.form-row"; + $(selector).tabularFormset(selector, inlineOptions.options); + break; + } + }); + }); +} diff --git a/staticfiles/admin/js/jquery.init.js b/staticfiles/admin/js/jquery.init.js new file mode 100644 index 0000000..f40b27f --- /dev/null +++ b/staticfiles/admin/js/jquery.init.js @@ -0,0 +1,8 @@ +/*global jQuery:false*/ +'use strict'; +/* Puts the included jQuery into our own namespace using noConflict and passing + * it 'true'. This ensures that the included jQuery doesn't pollute the global + * namespace (i.e. this preserves pre-existing values for both window.$ and + * window.jQuery). + */ +window.django = {jQuery: jQuery.noConflict(true)}; diff --git a/staticfiles/admin/js/nav_sidebar.js b/staticfiles/admin/js/nav_sidebar.js new file mode 100644 index 0000000..7e735db --- /dev/null +++ b/staticfiles/admin/js/nav_sidebar.js @@ -0,0 +1,79 @@ +'use strict'; +{ + const toggleNavSidebar = document.getElementById('toggle-nav-sidebar'); + if (toggleNavSidebar !== null) { + const navSidebar = document.getElementById('nav-sidebar'); + const main = document.getElementById('main'); + let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen'); + if (navSidebarIsOpen === null) { + navSidebarIsOpen = 'true'; + } + main.classList.toggle('shifted', navSidebarIsOpen === 'true'); + navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); + + toggleNavSidebar.addEventListener('click', function() { + if (navSidebarIsOpen === 'true') { + navSidebarIsOpen = 'false'; + } else { + navSidebarIsOpen = 'true'; + } + localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen); + main.classList.toggle('shifted'); + navSidebar.setAttribute('aria-expanded', navSidebarIsOpen); + }); + } + + function initSidebarQuickFilter() { + const options = []; + const navSidebar = document.getElementById('nav-sidebar'); + if (!navSidebar) { + return; + } + navSidebar.querySelectorAll('th[scope=row] a').forEach((container) => { + options.push({title: container.innerHTML, node: container}); + }); + + function checkValue(event) { + let filterValue = event.target.value; + if (filterValue) { + filterValue = filterValue.toLowerCase(); + } + if (event.key === 'Escape') { + filterValue = ''; + event.target.value = ''; // clear input + } + let matches = false; + for (const o of options) { + let displayValue = ''; + if (filterValue) { + if (o.title.toLowerCase().indexOf(filterValue) === -1) { + displayValue = 'none'; + } else { + matches = true; + } + } + // show/hide parent + o.node.parentNode.parentNode.style.display = displayValue; + } + if (!filterValue || matches) { + event.target.classList.remove('no-results'); + } else { + event.target.classList.add('no-results'); + } + sessionStorage.setItem('django.admin.navSidebarFilterValue', filterValue); + } + + const nav = document.getElementById('nav-filter'); + nav.addEventListener('change', checkValue, false); + nav.addEventListener('input', checkValue, false); + nav.addEventListener('keyup', checkValue, false); + + const storedValue = sessionStorage.getItem('django.admin.navSidebarFilterValue'); + if (storedValue) { + nav.value = storedValue; + checkValue({target: nav, key: ''}); + } + } + window.initSidebarQuickFilter = initSidebarQuickFilter; + initSidebarQuickFilter(); +} diff --git a/staticfiles/admin/js/popup_response.js b/staticfiles/admin/js/popup_response.js new file mode 100644 index 0000000..2b1d3dd --- /dev/null +++ b/staticfiles/admin/js/popup_response.js @@ -0,0 +1,16 @@ +/*global opener */ +'use strict'; +{ + const initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); + switch(initData.action) { + case 'change': + opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value); + break; + case 'delete': + opener.dismissDeleteRelatedObjectPopup(window, initData.value); + break; + default: + opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj); + break; + } +} diff --git a/staticfiles/admin/js/prepopulate.js b/staticfiles/admin/js/prepopulate.js new file mode 100644 index 0000000..89e95ab --- /dev/null +++ b/staticfiles/admin/js/prepopulate.js @@ -0,0 +1,43 @@ +/*global URLify*/ +'use strict'; +{ + const $ = django.jQuery; + $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) { + /* + Depends on urlify.js + Populates a selected field with the values of the dependent fields, + URLifies and shortens the string. + dependencies - array of dependent fields ids + maxLength - maximum length of the URLify'd string + allowUnicode - Unicode support of the URLify'd string + */ + return this.each(function() { + const prepopulatedField = $(this); + + const populate = function() { + // Bail if the field's value has been changed by the user + if (prepopulatedField.data('_changed')) { + return; + } + + const values = []; + $.each(dependencies, function(i, field) { + field = $(field); + if (field.val().length > 0) { + values.push(field.val()); + } + }); + prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode)); + }; + + prepopulatedField.data('_changed', false); + prepopulatedField.on('change', function() { + prepopulatedField.data('_changed', true); + }); + + if (!prepopulatedField.val()) { + $(dependencies.join(',')).on('keyup change focus', populate); + } + }); + }; +} diff --git a/staticfiles/admin/js/prepopulate_init.js b/staticfiles/admin/js/prepopulate_init.js new file mode 100644 index 0000000..a58841f --- /dev/null +++ b/staticfiles/admin/js/prepopulate_init.js @@ -0,0 +1,15 @@ +'use strict'; +{ + const $ = django.jQuery; + const fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields'); + $.each(fields, function(index, field) { + $( + '.empty-form .form-row .field-' + field.name + + ', .empty-form.form-row .field-' + field.name + + ', .empty-form .form-row.field-' + field.name + ).addClass('prepopulated_field'); + $(field.id).data('dependency_list', field.dependency_list).prepopulate( + field.dependency_ids, field.maxLength, field.allowUnicode + ); + }); +} diff --git a/staticfiles/admin/js/theme.js b/staticfiles/admin/js/theme.js new file mode 100644 index 0000000..794cd15 --- /dev/null +++ b/staticfiles/admin/js/theme.js @@ -0,0 +1,56 @@ +'use strict'; +{ + window.addEventListener('load', function(e) { + + function setTheme(mode) { + if (mode !== "light" && mode !== "dark" && mode !== "auto") { + console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`); + mode = "auto"; + } + document.documentElement.dataset.theme = mode; + localStorage.setItem("theme", mode); + } + + function cycleTheme() { + const currentTheme = localStorage.getItem("theme") || "auto"; + const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; + + if (prefersDark) { + // Auto (dark) -> Light -> Dark + if (currentTheme === "auto") { + setTheme("light"); + } else if (currentTheme === "light") { + setTheme("dark"); + } else { + setTheme("auto"); + } + } else { + // Auto (light) -> Dark -> Light + if (currentTheme === "auto") { + setTheme("dark"); + } else if (currentTheme === "dark") { + setTheme("light"); + } else { + setTheme("auto"); + } + } + } + + function initTheme() { + // set theme defined in localStorage if there is one, or fallback to auto mode + const currentTheme = localStorage.getItem("theme"); + currentTheme ? setTheme(currentTheme) : setTheme("auto"); + } + + function setupTheme() { + // Attach event handlers for toggling themes + const buttons = document.getElementsByClassName("theme-toggle"); + Array.from(buttons).forEach((btn) => { + btn.addEventListener("click", cycleTheme); + }); + initTheme(); + } + + setupTheme(); + }); +} diff --git a/staticfiles/admin/js/urlify.js b/staticfiles/admin/js/urlify.js new file mode 100644 index 0000000..9fc0409 --- /dev/null +++ b/staticfiles/admin/js/urlify.js @@ -0,0 +1,169 @@ +/*global XRegExp*/ +'use strict'; +{ + const LATIN_MAP = { + 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', + 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', + 'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', + 'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', + 'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à': 'a', + 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', + 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', + 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', + 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u', + 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y' + }; + const LATIN_SYMBOLS_MAP = { + '©': '(c)' + }; + const GREEK_MAP = { + 'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h', + 'θ': '8', 'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3', + 'ο': 'o', 'π': 'p', 'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f', + 'χ': 'x', 'ψ': 'ps', 'ω': 'w', 'ά': 'a', 'έ': 'e', 'ί': 'i', 'ό': 'o', + 'ύ': 'y', 'ή': 'h', 'ώ': 'w', 'ς': 's', 'ϊ': 'i', 'ΰ': 'y', 'ϋ': 'y', + 'ΐ': 'i', 'Α': 'A', 'Β': 'B', 'Γ': 'G', 'Δ': 'D', 'Ε': 'E', 'Ζ': 'Z', + 'Η': 'H', 'Θ': '8', 'Ι': 'I', 'Κ': 'K', 'Λ': 'L', 'Μ': 'M', 'Ν': 'N', + 'Ξ': '3', 'Ο': 'O', 'Π': 'P', 'Ρ': 'R', 'Σ': 'S', 'Τ': 'T', 'Υ': 'Y', + 'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W', 'Ά': 'A', 'Έ': 'E', 'Ί': 'I', + 'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I', 'Ϋ': 'Y' + }; + const TURKISH_MAP = { + 'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u', + 'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G' + }; + const ROMANIAN_MAP = { + 'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a', + 'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A' + }; + const RUSSIAN_MAP = { + 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo', + 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm', + 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u', + 'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh', 'щ': 'sh', 'ъ': '', + 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya', + 'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'E', 'Ё': 'Yo', + 'Ж': 'Zh', 'З': 'Z', 'И': 'I', 'Й': 'J', 'К': 'K', 'Л': 'L', 'М': 'M', + 'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U', + 'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '', + 'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya' + }; + const UKRAINIAN_MAP = { + 'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i', + 'ї': 'yi', 'ґ': 'g' + }; + const CZECH_MAP = { + 'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't', + 'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R', + 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z' + }; + const SLOVAK_MAP = { + 'á': 'a', 'ä': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'í': 'i', 'ľ': 'l', + 'ĺ': 'l', 'ň': 'n', 'ó': 'o', 'ô': 'o', 'ŕ': 'r', 'š': 's', 'ť': 't', + 'ú': 'u', 'ý': 'y', 'ž': 'z', + 'Á': 'a', 'Ä': 'A', 'Č': 'C', 'Ď': 'D', 'É': 'E', 'Í': 'I', 'Ľ': 'L', + 'Ĺ': 'L', 'Ň': 'N', 'Ó': 'O', 'Ô': 'O', 'Ŕ': 'R', 'Š': 'S', 'Ť': 'T', + 'Ú': 'U', 'Ý': 'Y', 'Ž': 'Z' + }; + const POLISH_MAP = { + 'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's', + 'ź': 'z', 'ż': 'z', + 'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S', + 'Ź': 'Z', 'Ż': 'Z' + }; + const LATVIAN_MAP = { + 'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l', + 'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z', + 'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L', + 'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z' + }; + const ARABIC_MAP = { + 'أ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'g', 'ح': 'h', 'خ': 'kh', 'د': 'd', + 'ذ': 'th', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': 't', + 'ظ': 'th', 'ع': 'aa', 'غ': 'gh', 'ف': 'f', 'ق': 'k', 'ك': 'k', 'ل': 'l', 'م': 'm', + 'ن': 'n', 'ه': 'h', 'و': 'o', 'ي': 'y' + }; + const LITHUANIAN_MAP = { + 'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u', + 'ū': 'u', 'ž': 'z', + 'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U', + 'Ū': 'U', 'Ž': 'Z' + }; + const SERBIAN_MAP = { + 'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz', + 'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C', + 'Џ': 'Dz', 'Đ': 'Dj' + }; + const AZERBAIJANI_MAP = { + 'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u', + 'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U' + }; + const GEORGIAN_MAP = { + 'ა': 'a', 'ბ': 'b', 'გ': 'g', 'დ': 'd', 'ე': 'e', 'ვ': 'v', 'ზ': 'z', + 'თ': 't', 'ი': 'i', 'კ': 'k', 'ლ': 'l', 'მ': 'm', 'ნ': 'n', 'ო': 'o', + 'პ': 'p', 'ჟ': 'j', 'რ': 'r', 'ს': 's', 'ტ': 't', 'უ': 'u', 'ფ': 'f', + 'ქ': 'q', 'ღ': 'g', 'ყ': 'y', 'შ': 'sh', 'ჩ': 'ch', 'ც': 'c', 'ძ': 'dz', + 'წ': 'w', 'ჭ': 'ch', 'ხ': 'x', 'ჯ': 'j', 'ჰ': 'h' + }; + + const ALL_DOWNCODE_MAPS = [ + LATIN_MAP, + LATIN_SYMBOLS_MAP, + GREEK_MAP, + TURKISH_MAP, + ROMANIAN_MAP, + RUSSIAN_MAP, + UKRAINIAN_MAP, + CZECH_MAP, + SLOVAK_MAP, + POLISH_MAP, + LATVIAN_MAP, + ARABIC_MAP, + LITHUANIAN_MAP, + SERBIAN_MAP, + AZERBAIJANI_MAP, + GEORGIAN_MAP + ]; + + const Downcoder = { + 'Initialize': function() { + if (Downcoder.map) { // already made + return; + } + Downcoder.map = {}; + for (const lookup of ALL_DOWNCODE_MAPS) { + Object.assign(Downcoder.map, lookup); + } + Downcoder.regex = new RegExp(Object.keys(Downcoder.map).join('|'), 'g'); + } + }; + + function downcode(slug) { + Downcoder.Initialize(); + return slug.replace(Downcoder.regex, function(m) { + return Downcoder.map[m]; + }); + } + + + function URLify(s, num_chars, allowUnicode) { + // changes, e.g., "Petty theft" to "petty-theft" + if (!allowUnicode) { + s = downcode(s); + } + s = s.toLowerCase(); // convert to lowercase + // if downcode doesn't hit, the char will be stripped here + if (allowUnicode) { + // Keep Unicode letters including both lowercase and uppercase + // characters, whitespace, and dash; remove other characters. + s = XRegExp.replace(s, XRegExp('[^-_\\p{L}\\p{N}\\s]', 'g'), ''); + } else { + s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars + } + s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces + s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens + s = s.substring(0, num_chars); // trim to first num_chars chars + return s.replace(/-+$/g, ''); // trim any trailing hyphens + } + window.URLify = URLify; +} diff --git a/staticfiles/admin/js/vendor/jquery/LICENSE.txt b/staticfiles/admin/js/vendor/jquery/LICENSE.txt new file mode 100644 index 0000000..f642c3f --- /dev/null +++ b/staticfiles/admin/js/vendor/jquery/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright OpenJS Foundation and other contributors, https://openjsf.org/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/staticfiles/admin/js/vendor/jquery/jquery.js b/staticfiles/admin/js/vendor/jquery/jquery.js new file mode 100644 index 0000000..7f35c11 --- /dev/null +++ b/staticfiles/admin/js/vendor/jquery/jquery.js @@ -0,0 +1,10965 @@ +/*! + * jQuery JavaScript Library v3.6.4 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2023-03-08T15:28Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket trac-14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.6.4", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.10 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2023-02-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ + // Make sure the the `:has()` argument is parsed unforgivingly. + // We include `*` in the test to detect buggy implementations that are + // _selectively_ forgiving (specifically when the list includes at least + // one valid selector). + // Note that we treat complete lack of support for `:has()` as if it were + // spec-compliant support, which is fine because use of `:has()` in such + // environments will fail in the qSA path and fall back to jQuery traversal + // anyway. + support.cssHas = assert( function() { + try { + document.querySelector( ":has(*,:jqfake)" ); + return false; + } catch ( e ) { + return true; + } + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + if ( !support.cssHas ) { + + // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ + // Our regular `try-catch` mechanism fails to detect natively-unsupported + // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) + // in browsers that parse the `:has()` argument as a forgiving selector list. + // https://drafts.csswg.org/selectors/#relational now requires the argument + // to be parsed unforgivingly, but browsers have not yet fully adjusted. + rbuggyQSA.push( ":has" ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + + // Support: IE <9 only + // IE doesn't have `contains` on `document` so we need to check for + // `documentElement` presence. + // We need to fall back to `a` when `documentElement` is missing + // as `ownerDocument` of elements within `