diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..26f3c9bf --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,36 @@ +name: Run Python Tests + +on: + pull_request: + types: + - opened + branches: + - PB + +jobs: + test: + runs-on: ubuntu-latest + if: ${{ !startsWith(github.event.pull_request.title, 'Docs:') }} + defaults: + run: + working-directory: '3 - PB/MVP' + + strategy: + matrix: + python-version: [3.12] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r src/backend/requirements.txt + + - name: Run tests + run: | + python -m pytest -v tests \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..2cd0d687 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "python.testing.unittestArgs": [ + "-v", + "-s", + "./3 - PB", + "-p", + "*_test.py" + ], + "python.testing.pytestEnabled": false, + "python.testing.unittestEnabled": true, + "python.testing.pytestArgs": [ + "3 - PB" + ] +} \ No newline at end of file diff --git a/3 - PB/Lettera di presentazione.pdf b/3 - PB/Lettera di presentazione.pdf new file mode 100644 index 00000000..439f5a94 Binary files /dev/null and b/3 - PB/Lettera di presentazione.pdf differ diff --git a/3 - PB/MVP/.gitignore b/3 - PB/MVP/.gitignore new file mode 100644 index 00000000..dcf09b6b --- /dev/null +++ b/3 - PB/MVP/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +.vscode +.idea +__pycache__ +.pytest_cache +secrets +__init__.py +*.pyc +chroma_db \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/ask_chatbot_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/ask_chatbot_controller.py new file mode 100644 index 00000000..9ea1f8c9 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/ask_chatbot_controller.py @@ -0,0 +1,35 @@ +from application.port._in.ask_chatbot_use_case import AskChatbotUseCase +from domain.chat.message_response import MessageResponse + +from domain.chat.message import Message, MessageSender +from domain.chat.chat_id import ChatId +from datetime import datetime, timezone + +""" +This class is the controller for the use case AskChatbotUseCase. It receives the user's message and the chatId and returns a MessageResponse. +Attributes: + useCase (AskChatbotUseCase): The use case for asking the chatbot. +""" +class AskChatbotController: + def __init__(self, askChatbotUseCase: AskChatbotUseCase): + self.askChatbotUseCase = askChatbotUseCase + + def askChatbot(self, message: str, chatId: int = None) -> MessageResponse: + """ + Receives the user's message and the chatId and returns a MessageResponse. + Args: + message (str): The user's message. + chatId (int): The chat's id. + Returns: + MessageResponse: the response of the operation. + """ + userMessage = Message( + message, + datetime.now(timezone.utc), + None, + MessageSender.USER + ) + + chatId = ChatId(chatId) if chatId is not None else None + + return self.askChatbotUseCase.askChatbot(userMessage, chatId) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/change_configuration_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/change_configuration_controller.py new file mode 100644 index 00000000..ab4b145c --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/change_configuration_controller.py @@ -0,0 +1,28 @@ +from typing import List +from application.port._in.change_configuration_use_case import ChangeConfigurationUseCase +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +from domain.configuration.llm_model_configuration import LLMModelType + +""" +This class is the controller for the use case ChangeConfigurationUseCase. It receives the new LLM model and returns a ConfigurationOperationResponse. +Attributes: + useCase (ChangeConfigurationUseCase): The use case for changing the configuration. +""" + +class ChangeConfigurationController: + def __init__(self, changeConfigurationUseCase: ChangeConfigurationUseCase): + self.useCase = changeConfigurationUseCase + + def changeLLMModel(self, LLModel: str) -> ConfigurationOperationResponse: + """ + Receives the new LLM model and returns a ConfigurationOperationResponse. + Args: + LLModel (str): The new LLM model. + Returns: + ConfigurationOperationResponse: the response of the operation. + """ + try: + LLMModelChoice = LLMModelType[LLModel.upper()] + return self.useCase.changeLLMModel(LLMModelChoice) + except KeyError: + return None \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/conceal_documents_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/conceal_documents_controller.py new file mode 100644 index 00000000..307d6c7a --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/conceal_documents_controller.py @@ -0,0 +1,23 @@ +from typing import List +from application.port._in.conceal_documents_use_case import ConcealDocumentsUseCase +from domain.document.document_operation_response import DocumentOperationResponse +from domain.document.document_id import DocumentId + +""" +This class is the controller for the use case ConcealDocumentsUseCase. It receives the documents' ids and returns a list of DocumentOperationResponse. +Attributes: + useCase (ConcealDocumentsUseCase): The use case for concealing documents. +""" +class ConcealDocumentsController: + def __init__(self, concealDocumentsUseCase: ConcealDocumentsUseCase): + self.useCase = concealDocumentsUseCase + + def concealDocuments(self, documentsIds: List[str]) -> List[DocumentOperationResponse]: + """ + Receives the documents' ids and returns a list of DocumentOperationResponse. + Args: + documentsIds (List[str]): The documents' ids. + Returns: + List[DocumentOperationResponse]: the response of the operation. + """ + return self.useCase.concealDocuments([DocumentId(documentId) for documentId in documentsIds]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/delete_chats_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/delete_chats_controller.py new file mode 100644 index 00000000..d73cb755 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/delete_chats_controller.py @@ -0,0 +1,23 @@ +from application.port._in.delete_chats_use_case import DeleteChatsUseCase +from domain.chat.chat_operation_response import ChatOperationResponse +from typing import List +from domain.chat.chat_id import ChatId + +""" +This class is the controller for the use case DeleteChatsUseCase. It receives the chats' ids and returns a list of ChatOperationResponse. +Attributes: + useCase (DeleteChatsUseCase): The use case for deleting chats. +""" +class DeleteChatsController: + def __init__(self, deleteChatUseCase: DeleteChatsUseCase): + self.useCase = deleteChatUseCase + + def deleteChats(self, chatsIdsList: List[int]) -> List[ChatOperationResponse]: + """ + Receives the chats' ids and returns a list of ChatOperationResponse. + Args: + chatsIdsList (List[int]): The chats' ids. + Returns: + List[ChatOperationResponse]: the response of the operation. + """ + return self.useCase.deleteChats([ChatId(chatId) for chatId in chatsIdsList]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/delete_documents_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/delete_documents_controller.py new file mode 100644 index 00000000..e74af31b --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/delete_documents_controller.py @@ -0,0 +1,30 @@ +from typing import List +from application.port._in.delete_documents_use_case import DeleteDocumentsUseCase +from domain.document.document_operation_response import DocumentOperationResponse +from domain.document.document_id import DocumentId + +from domain.exception.exception import ElaborationException +from api_exceptions import APIElaborationException + +""" +This class is the controller for the use case DeleteDocumentsUseCase. It receives the documents' ids and returns a list of DocumentOperationResponse. +Attributes: + useCase (DeleteDocumentsUseCase): The use case for deleting documents. +""" +class DeleteDocumentsController: + def __init__(self, deleteDocumentsUseCase: DeleteDocumentsUseCase): + self.useCase = deleteDocumentsUseCase + + + def deleteDocuments(self, documentsIds: List[str]) -> List[DocumentOperationResponse]: + """ + Receives the documents' ids and returns a list of DocumentOperationResponse. + Args: + documentsIds (List[str]): The documents' ids. + Returns: + List[DocumentOperationResponse]: the response of the operation. + """ + try: + return self.useCase.deleteDocuments([DocumentId(documentId) for documentId in documentsIds]) + except ElaborationException as e: + raise APIElaborationException(str(e)) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/embed_documents_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/embed_documents_controller.py new file mode 100644 index 00000000..2f59f3e2 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/embed_documents_controller.py @@ -0,0 +1,30 @@ +from typing import List + +from application.port._in.embed_documents_use_case import EmbedDocumentsUseCase +from domain.document.document_operation_response import DocumentOperationResponse +from domain.document.document_id import DocumentId + +from domain.exception.exception import ElaborationException +from api_exceptions import APIElaborationException + +""" +This class is the controller for the use case EmbedDocumentsUseCase. It receives the documents' ids and returns a list of DocumentOperationResponse. +Attributes: + useCase (EmbedDocumentsUseCase): The use case for embedding documents. +""" +class EmbedDocumentsController: + def __init__(self, embedDocumentsUseCase: EmbedDocumentsUseCase): + self.useCase = embedDocumentsUseCase + + def embedDocuments(self, documentsIds: List[str]) -> List[DocumentOperationResponse]: + """ + Receives the documents' ids and returns a list of DocumentOperationResponse. + Args: + documentsIds (List[str]): The documents' ids. + Returns: + List[DocumentOperationResponse]: the response of the operation. + """ + try: + return self.useCase.embedDocuments([DocumentId(documentId) for documentId in documentsIds]) + except ElaborationException as e: + raise APIElaborationException(str(e)) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/enable_documents_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/enable_documents_controller.py new file mode 100644 index 00000000..bda9b0cd --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/enable_documents_controller.py @@ -0,0 +1,23 @@ +from typing import List +from application.port._in.enable_documents_use_case import EnableDocumentsUseCase +from domain.document.document_operation_response import DocumentOperationResponse +from domain.document.document_id import DocumentId + +""" +This class is the controller for the use case EnableDocumentsUseCase. It receives the documents' ids and returns a list of DocumentOperationResponse. +Attributes: + useCase (EnableDocumentsUseCase): The use case for enabling documents. +""" +class EnableDocumentsController: + def __init__(self, enableDocumentsUseCase: EnableDocumentsUseCase): + self.useCase = enableDocumentsUseCase + + def enableDocuments(self, documentsIds: List[str]) -> List[DocumentOperationResponse]: + """ + Receives the documents' ids and returns a list of DocumentOperationResponse. + Args: + documentsIds (List[str]): The documents' ids. + Returns: + List[DocumentOperationResponse]: the response of the operation. + """ + return self.useCase.enableDocuments([DocumentId(documentId) for documentId in documentsIds]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/get_chat_messages_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/get_chat_messages_controller.py new file mode 100644 index 00000000..5bce950f --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/get_chat_messages_controller.py @@ -0,0 +1,22 @@ +from application.port._in.get_chat_messages_use_case import GetChatMessagesUseCase +from domain.chat.chat import Chat +from domain.chat.chat_id import ChatId + +""" +This class is the controller for the use case GetChatMessagesUseCase. It receives the chat's id and returns the chat's messages. +Attributes: + useCase (GetChatMessagesUseCase): The use case for getting the chat's messages. +""" +class GetChatMessagesController: + def __init__(self, getChatMessagesUseCase: GetChatMessagesUseCase): + self.useCase = getChatMessagesUseCase + + def getChatMessages(self, chatId: int) -> Chat: + """ + Receives the chat's id and returns the chat's messages. + Args: + chatId (int): The chat's id. + Returns: + Chat: the chat containing the messages required. + """ + return self.useCase.getChatMessages(ChatId(chatId)) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/get_chats_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/get_chats_controller.py new file mode 100644 index 00000000..1f39da6a --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/get_chats_controller.py @@ -0,0 +1,25 @@ +from typing import List + +from application.port._in.get_chats_use_case import GetChatsUseCase +from domain.chat.chat_filter import ChatFilter +from domain.chat.chat_preview import ChatPreview + +""" +This class is the controller for the use case GetChatsUseCase. It receives the search filter and returns a list of ChatPreview. +Attributes: + useCase (GetChatsUseCase): The use case for getting chats. +""" +class GetChatsController: + def __init__(self, getChatsUseCase: GetChatsUseCase): + self.useCase = getChatsUseCase + + def getChats(self, searchFilter:str)-> List[ChatPreview]: + """ + Receives the search filter and returns a list of ChatPreview. + Args: + searchFilter (str): The search filter. + Returns: + List[ChatPreview]: the list of ChatPreview that match the search filter. + """ + filter = ChatFilter(searchFilter) + return self.useCase.getChats(filter) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/get_configuration_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/get_configuration_controller.py new file mode 100644 index 00000000..5db1394c --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/get_configuration_controller.py @@ -0,0 +1,20 @@ +from typing import List +from application.port._in.get_configuration_use_case import GetConfigurationUseCase +from domain.configuration.configuration import Configuration + +""" +This class is the controller for the use case GetConfigurationUseCase. It returns the current configuration. +Attributes: + useCase (GetConfigurationUseCase): The use case for getting the configuration. +""" +class GetConfigurationController: + def __init__(self, getConfigurationUseCase: GetConfigurationUseCase): + self.useCase = getConfigurationUseCase + + def getConfiguration(self) -> Configuration: + """ + Returns the current configuration. + Returns: + Configuration: the current configuration. + """ + return self.useCase.getConfiguration() \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/get_configuration_options_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/get_configuration_options_controller.py new file mode 100644 index 00000000..2548047f --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/get_configuration_options_controller.py @@ -0,0 +1,20 @@ +from typing import List +from application.port._in.get_configuration_options_use_case import GetConfigurationOptionsUseCase +from domain.configuration.configuration_options import ConfigurationOptions + +""" +This class is the controller for the use case GetConfigurationOptionsUseCase. It returns the current configuration options. +Attributes: + useCase (GetConfigurationOptionsUseCase): The use case for getting the configuration options. +""" +class GetConfigurationOptionsController: + def __init__(self, getConfigurationOptionsUseCase: GetConfigurationOptionsUseCase): + self.useCase = getConfigurationOptionsUseCase + + def getConfigurationOptions(self) -> ConfigurationOptions: + """ + Returns the current configuration options. + Returns: + ConfigurationOptions: the current configuration options. + """ + return self.useCase.getConfigurationOptions() \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/get_document_content_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/get_document_content_controller.py new file mode 100644 index 00000000..75abd4bd --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/get_document_content_controller.py @@ -0,0 +1,30 @@ +from application.port._in.get_documents_content_use_case import GetDocumentsContentUseCase +from domain.document.document import Document +from domain.document.document_id import DocumentId + +from domain.exception.exception import ElaborationException +from api_exceptions import APIElaborationException + +""" +This class is the controller for the use case GetDocumentsContentUseCase. It receives the document's id and returns the document's content. +Attributes: + useCase (GetDocumentsContentUseCase): The use case for getting the document's content. +""" +class GetDocumentContentController: + def __init__(self, getDocumentContentUseCase: GetDocumentsContentUseCase): + self.useCase = getDocumentContentUseCase + + def getDocumentContent(self, documentId: str) -> Document: + """ + Receives the document's id and returns the document's content. + Args: + documentId (str): The document's id. + Returns: + Document: the Document containg the relative content. + """ + try: + document = self.useCase.getDocumentsContent([DocumentId(documentId)]) + return document[0] if document is not None else None + except ElaborationException as e: + raise APIElaborationException(str(e)) + \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/get_documents_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/get_documents_controller.py new file mode 100644 index 00000000..99ec1242 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/get_documents_controller.py @@ -0,0 +1,29 @@ +from typing import List + +from application.port._in.get_documents_use_case import GetDocumentsUseCase +from domain.document.document_filter import DocumentFilter +from domain.document.light_document import LightDocument +from domain.exception.exception import ElaborationException +from api_exceptions import APIElaborationException + +""" +This class is the controller for the use case GetDocumentsUseCase. It receives the search filter and returns a list of LightDocument. +Attributes: + useCase (GetDocumentsUseCase): The use case for getting documents. +""" +class GetDocumentsController: + def __init__(self, getDocumentsUseCase: GetDocumentsUseCase): + self.useCase = getDocumentsUseCase + + def getDocuments(self, searchFilter: str) -> List[LightDocument]: + """ + Receives the search filter and returns a list of LightDocument. + Args: + searchFilter (str): The search filter. It can be empty in order to get all the documents. + Returns: + List[LightDocument]: the list of LightDocument that match the search filter. + """ + try: + return self.useCase.getDocuments(DocumentFilter(searchFilter)) + except ElaborationException as e: + raise APIElaborationException(str(e)) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/presentation_domain/new_document.py b/3 - PB/MVP/src/backend/adapter/_in/web/presentation_domain/new_document.py new file mode 100644 index 00000000..5098d92e --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/presentation_domain/new_document.py @@ -0,0 +1,47 @@ +from dataclasses import dataclass +from datetime import datetime, timezone + +from domain.document.document import Document +from domain.document.document_content import DocumentContent +from domain.document.document_id import DocumentId +from domain.document.document_metadata import DocumentMetadata +from domain.document.document_metadata import DocumentType +from domain.document.document_status import DocumentStatus +from domain.document.document_status import Status +from domain.document.plain_document import PlainDocument + + +""" +This module contains the NewDocument dataclass, which represents a new document to be uploaded to the system. +Attributes: + documentId (str): The document's id. + type (str): The document's type. + size (float): The document's size. + content (bytes): The document's content. +""" +@dataclass +class NewDocument: + documentId: str + type: str + size: float + content: bytes + + def toDocument(self) -> Document: + """ + Converts the NewDocument to a Document. + Returns: + Document: The Document object. + """ + documentType = DocumentType.PDF if self.type.upper() == "PDF" else DocumentType.DOCX + return Document( + DocumentStatus(Status.ENABLED), + PlainDocument( + DocumentMetadata( + DocumentId(self.documentId), + documentType, + self.size, + datetime.now(timezone.utc) + ), + DocumentContent(self.content) + ) + ) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/rename_chat_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/rename_chat_controller.py new file mode 100644 index 00000000..c24823ef --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/rename_chat_controller.py @@ -0,0 +1,23 @@ +from domain.chat.chat_id import ChatId +from domain.chat.chat_operation_response import ChatOperationResponse +from application.port._in.rename_chat_use_case import RenameChatUseCase + +""" +This class is the controller for the use case RenameChatUseCase. It receives the chat's id and the new title and returns a ChatOperationResponse. +Attributes: + useCase (RenameChatUseCase): The use case for renaming a chat. +""" +class RenameChatController: + def __init__(self, renameChatUseCase: RenameChatUseCase): + self.useCase = renameChatUseCase + + def renameChat(self, chatId: int, title: str) -> ChatOperationResponse: + """ + Receives the chat's id and the new title and returns a ChatOperationResponse. + Args: + chatId (int): The chat's id. + title (str): The new title. + Returns: + ChatOperationResponse: the response of the operation. + """ + return self.useCase.renameChat(ChatId(chatId), title) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/set_configuration_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/set_configuration_controller.py new file mode 100644 index 00000000..cd39f433 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/set_configuration_controller.py @@ -0,0 +1,40 @@ +from typing import List +from application.port._in.set_configuration_use_case import SetConfigurationUseCase +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +from domain.configuration.llm_model_configuration import LLMModelType +from domain.configuration.document_store_configuration import DocumentStoreType +from domain.configuration.vector_store_configuration import VectorStoreType +from domain.configuration.embedding_model_configuration import EmbeddingModelType + +""" +This class is the controller for the use case SetConfigurationUseCase. It receives the LLM model, the Document Store, +the Vector Store and the Embedding Model to set as the configuration that will be used while the application is running, +and returns a ConfigurationOperationResponse. +Attributes: + useCase (ChangeConfigurationUseCase): The use case for changing the configuration. +""" + +class SetConfigurationController: + def __init__(self, setConfigurationUseCase: SetConfigurationUseCase): + self.useCase = setConfigurationUseCase + + def setConfiguration(self, LLModel: str, DocumentStore: str, VectorStore: str, EmbeddingModel: str) -> ConfigurationOperationResponse: + """ + Receives the LLM model, the DocumentStore, the VectoreStore and the EmbeddingModel to set as the active configuration + and returns a ConfigurationOperationResponse. + Args: + LLModel (str): The LLM model. + DocumentStore (str): The Document Store. + VectorStore (str): The Vector Store. + EmbeddingModel (str): The Embedding Model. + Returns: + ConfigurationOperationResponse: the response of the operation. + """ + try: + LLMModelChoice = LLMModelType[LLModel.upper()] + DocumentStoreChoice = DocumentStoreType[DocumentStore.upper()] + VectorStoreChoice = VectorStoreType[VectorStore.upper()] + EmbeddingModelChoice = EmbeddingModelType[EmbeddingModel.upper()] + return self.useCase.setConfiguration(LLMModelChoice, DocumentStoreChoice, VectorStoreChoice, EmbeddingModelChoice) + except KeyError: + return None \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/_in/web/upload_documents_controller.py b/3 - PB/MVP/src/backend/adapter/_in/web/upload_documents_controller.py new file mode 100644 index 00000000..606578c4 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/_in/web/upload_documents_controller.py @@ -0,0 +1,34 @@ +from typing import List + +from adapter._in.web.presentation_domain.new_document import NewDocument +from application.port._in.upload_documents_use_case import UploadDocumentsUseCase +from domain.document.document_operation_response import DocumentOperationResponse + +from domain.exception.exception import ElaborationException +from api_exceptions import APIElaborationException + +""" +This class is the controller for the upload documents use case. It receives the new documents and converts them to the domain model. +It also receives the force upload parameter and sends the documents to the use case. + Attributes: + useCase (UploadDocumentsUseCase): The use case for uploading documents. +""" +class UploadDocumentsController: + def __init__(self, uploadDocumentsUseCase: UploadDocumentsUseCase): + self.useCase = uploadDocumentsUseCase + + def uploadDocuments(self, newDocuments: List[NewDocument], forceUpload: bool = False) -> List[DocumentOperationResponse]: + """ + Receives the new documents and the force upload parameter and sends them to the use case. + Args: + newDocuments (List[NewDocument]): The new documents. + forceUpload (bool): The force upload parameter. + Returns: + List[DocumentOperationResponse]: the response of the operation. + """ + try: + documents = [newDocument.toDocument() for newDocument in newDocuments] + return self.useCase.uploadDocuments(documents, forceUpload) + except ElaborationException as e: + raise APIElaborationException(str(e)) + diff --git a/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/ask_chatbot_langchain.py b/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/ask_chatbot_langchain.py new file mode 100644 index 00000000..414d78a2 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/ask_chatbot_langchain.py @@ -0,0 +1,62 @@ +from langchain.chains.base import Chain + +from domain.chat.message_response import MessageResponse +from domain.chat.message import Message +from domain.chat.chat_id import ChatId +from domain.chat.message import MessageSender +from domain.document.document_id import DocumentId + +from application.port.out.ask_chatbot_port import AskChatbotPort + +from datetime import datetime, timezone + +from adapter.out.persistence.postgres.chat_history_manager import ChatHistoryManager + +""" +This class is the implementation of the AskChatbotPort interface. It uses the Langchain library to ask the chatbot. + Attributes: + chain (Chain): The chain to use to ask the chatbot. + chatHistoryManager (ChatHistoryManager): The chat history manager to use to get the chat history. +""" +class AskChatbotLangchain(AskChatbotPort): + def __init__(self, chain: Chain, chatHistoryManager: ChatHistoryManager): + self.chain = chain + self.chatHistoryManager = chatHistoryManager + + def askChatbot(self, message: Message, chatId: ChatId) -> MessageResponse: + """ + Asks the chatbot the message and returns the response. + Args: + message (Message): The message to ask the chatbot. + chatId (ChatId): The chat id. + Returns: + MessageResponse: The response of the chatbot. + """ + chatbotAnswer = "" + try: + if chatId is not None: + chatHistory = self.chatHistoryManager.getChatHistory(chatId.id) + if len(chatHistory.messages) == 0: + return MessageResponse(status=False, messageResponse=None, chatId=chatId) + else: + answer = self.chain.invoke({"question": message.content, "chat_history": (chatHistory.messages[-6:])}) + else: + answer = self.chain.invoke({"question": message.content, "chat_history": []}) + + chatbotAnswer = ' '.join(answer.get("answer", "").split()) + + if chatbotAnswer.strip() == "": + return MessageResponse(status=False, messageResponse=None, chatId=chatId) + else: + return MessageResponse( + status=True, + messageResponse=Message( + chatbotAnswer, + datetime.now(timezone.utc), + list(set(DocumentId(relevantDocumentId.metadata.get("source")) for relevantDocumentId in answer.get("source_documents", []))), + MessageSender.CHATBOT + ), + chatId=chatId + ) + except Exception as e: + return MessageResponse(status=False, messageResponse=None, chatId=chatId) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/postgres_persist_chat.py b/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/postgres_persist_chat.py new file mode 100644 index 00000000..91f55684 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/ask_chatbot/postgres_persist_chat.py @@ -0,0 +1,38 @@ +from typing import List + +from domain.chat.message import Message, MessageSender +from domain.chat.chat_id import ChatId +from domain.chat.chat_operation_response import ChatOperationResponse +from adapter.out.persistence.postgres.postgres_message import PostgresMessage, PostgresMessageSenderType + +from application.port.out.persist_chat_port import PersistChatPort +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM + +""" +This class is the implementation of the PersistChatPort interface. It uses the PostgresChatORM to persist the chat. + Attributes: + postgresChatORM (PostgresChatORM): The PostgresChatORM to use to persist the chat. +""" +class PostgresPersistChat(PersistChatPort): + def __init__(self, postgresChatORM: PostgresChatORM): + self.postgresChatORM = postgresChatORM + + """ + Persists the chat and returns the response. + Args: + messages (List[Message]): The messages to persist. + chatId (ChatId): The chat id. + Returns: + ChatOperationResponse: The response of the operation. + """ + def persistChat(self, messages: List[Message], chatId: ChatId) -> ChatOperationResponse: + postgresChatOperationResponse = self.postgresChatORM.persistChat([self.toPostgresMessageFrom(message) for message in messages], chatId.id if chatId else None) + return postgresChatOperationResponse.toChatOperationResponse() + + def toPostgresMessageFrom(self, message: Message) -> PostgresMessage: + return PostgresMessage( + content=message.content, + timestamp=message.timestamp, + relevantDocuments=[relevantDocumentId.id for relevantDocumentId in message.relevantDocuments] if message.relevantDocuments else None, + sender=PostgresMessageSenderType.human if message.sender.value == MessageSender.USER.value else PostgresMessageSenderType.ai + ) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/change_configuration/change_configuration_postgres.py b/3 - PB/MVP/src/backend/adapter/out/change_configuration/change_configuration_postgres.py new file mode 100644 index 00000000..098c99a4 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/change_configuration/change_configuration_postgres.py @@ -0,0 +1,40 @@ +import os +from application.port.out.change_configuration_port import ChangeConfigurationPort +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +from domain.configuration.llm_model_configuration import LLMModelType +from adapter.out.persistence.postgres.configuration_models import PostgresLLMModelType +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM + +""" +This class is the implementation of the ChangeConfigurationPort interface. It uses the PostgresConfigurationORM to change the configuration. + Attributes: + postgresConfigurationORM (PostgresConfigurationORM): The PostgresConfigurationORM to use to change the configuration. +""" +class ChangeConfigurationPostgres(ChangeConfigurationPort): + def __init__(self, postgresConfigurationORM: PostgresConfigurationORM): + self.postgresConfigurationORM = postgresConfigurationORM + + """ + Changes the LLM model and returns the response. + Args: + LLModel (LLMModelType): The LLM model to change. + Returns: + ConfigurationOperationResponse: The response of the operation. + """ + def changeLLMModel(self, LLModel: LLMModelType) -> ConfigurationOperationResponse: + LLMModelChoice = self.toPostgresLLMModelTypeFrom(LLModel) + userId = os.environ.get('USER_ID') + + postgresConfigurationOperationResponse = self.postgresConfigurationORM.changeLLMModel(userId, LLMModelChoice) + return postgresConfigurationOperationResponse.toConfigurationOperationResponse() + + """ + Converts the LLMModelType to the PostgresLLMModelType. + Args: + LLMModel (LLMModelType): The LLM model to convert. + Returns: + PostgresLLMModelType: The converted LLM model. + """ + def toPostgresLLMModelTypeFrom(self, LLMModel: LLMModelType) -> PostgresLLMModelType: + return PostgresLLMModelType[LLMModel.name] + \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/conceal_documents/conceal_documents_vector_store.py b/3 - PB/MVP/src/backend/adapter/out/conceal_documents/conceal_documents_vector_store.py new file mode 100644 index 00000000..f6ea91b9 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/conceal_documents/conceal_documents_vector_store.py @@ -0,0 +1,32 @@ +from adapter.out.persistence.vector_store.vector_store_manager import VectorStoreManager +from typing import List +from application.port.out.conceal_documents_port import ConcealDocumentsPort +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This class is the implementation of the ConcealDocumentsPort interface. It uses the VectorStoreManager to conceal the documents. + Attributes: + vectorStoreManager (VectorStoreManager): The VectorStoreManager to use to conceal the documents. +""" +class ConcealDocumentsVectorStore(ConcealDocumentsPort): + def __init__(self, vectorStoreManager: VectorStoreManager): + self.vectorStoreManager = vectorStoreManager + + """ + Conceals the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to conceal. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def concealDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + #adaptee because vectorStoreManger needs a List of string + documentsIdsString = [documentId.id for documentId in documentsIds] + vectorStoreDocumentOperationResponseList = self.vectorStoreManager.concealDocuments(documentsIdsString) + #return DocumentOperationResponse therefore we adaptee the response + documentOperationResponseList = [] + for vectorOperationResponse in vectorStoreDocumentOperationResponseList: + documentOperationResponseList.append(vectorOperationResponse.toDocumentOperationResponse()) + return documentOperationResponseList + \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/configuration_manager.py b/3 - PB/MVP/src/backend/adapter/out/configuration_manager.py new file mode 100644 index 00000000..ee4ac5e8 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/configuration_manager.py @@ -0,0 +1,277 @@ +import os + +from langchain.chains import ConversationalRetrievalChain +from langchain_community.llms import HuggingFaceEndpoint +from langchain.prompts import PromptTemplate +from langchain_openai import OpenAI + +from application.port.out.documents_uploader_port import DocumentsUploaderPort +from application.port.out.embeddings_uploader_port import EmbeddingsUploaderPort +from application.port.out.delete_documents_port import DeleteDocumentsPort +from application.port.out.delete_embeddings_port import DeleteEmbeddingsPort +from application.port.out.conceal_documents_port import ConcealDocumentsPort +from application.port.out.enable_documents_port import EnableDocumentsPort +from application.port.out.get_documents_metadata_port import GetDocumentsMetadataPort +from application.port.out.get_documents_status_port import GetDocumentsStatusPort +from application.port.out.get_documents_content_port import GetDocumentsContentPort +from application.port.out.ask_chatbot_port import AskChatbotPort + +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.persistence.postgres.configuration_models import PostgresDocumentStoreType, PostgresVectorStoreType, PostgresLLMModelType, PostgresEmbeddingModelType +from adapter.out.persistence.vector_store.vector_store_chromaDB_manager import VectorStoreChromaDBManager +from adapter.out.persistence.vector_store.vector_store_pinecone_manager import VectorStorePineconeManager +from adapter.out.upload_documents.huggingface_embedding_model import HuggingFaceEmbeddingModel +from adapter.out.upload_documents.openai_embedding_model import OpenAIEmbeddingModel + +from adapter.out.persistence.aws.AWS_manager import AWSS3Manager +from adapter.out.conceal_documents.conceal_documents_vector_store import ConcealDocumentsVectorStore +from adapter.out.delete_documents.delete_documents_AWSS3 import DeleteDocumentsAWSS3 +from adapter.out.delete_documents.delete_embeddings_vector_store import DeleteEmbeddingsVectorStore +from adapter.out.upload_documents.embeddings_creator import EmbeddingsCreator +from adapter.out.upload_documents.embeddings_uploader_facade_langchain import EmbeddingsUploaderFacadeLangchain +from adapter.out.upload_documents.embeddings_uploader_vector_store import EmbeddingsUploaderVectorStore +from adapter.out.enable_documents.enable_documents_vector_store import EnableDocumentsVectorStore +from adapter.out.get_documents.get_documents_list_awss3 import GetDocumentsListAWSS3 +from adapter.out.get_documents.get_documents_status_vector_store import GetDocumentsStatusVectorStore +from adapter.out.upload_documents.chunkerizer import Chunkerizer +from adapter.out.upload_documents.documents_uploader_AWSS3 import DocumentsUploaderAWSS3 +from adapter.out.get_documents.get_documents_content_awss3 import GetDocumentsContentAWSS3 +from adapter.out.ask_chatbot.ask_chatbot_langchain import AskChatbotLangchain +from adapter.out.persistence.postgres.chat_history_manager import ChatHistoryManager + + + +class ConfigurationException(Exception): + pass + +""" +This class is the implementation of the ConfigurationManager interface. It uses the PostgresConfigurationORM to get the configuration and the other adapters to get the ports. + Attributes: + postgresConfigurationORM (PostgresConfigurationORM): The PostgresConfigurationORM to use to get the configuration. +""" +class ConfigurationManager: + def __init__(self, postgresConfigurationORM: PostgresConfigurationORM): + self.postgresConfigurationORM = postgresConfigurationORM + + + """ + Gets the DocumentsUploaderPort. + Returns: + DocumentsUploaderPort: The DocumentsUploaderPort. + """ + def getDocumentsUploaderPort(self) -> DocumentsUploaderPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.documentStore == PostgresDocumentStoreType.AWS: + configuredDocumentStore = DocumentsUploaderAWSS3( + AWSS3Manager() + ) + else: + raise ConfigurationException('Document store non configurato.') + + return configuredDocumentStore + + + """ + Gets the EmbeddingsUploaderPort. + Returns: + EmbeddingsUploaderPort: The EmbeddingsUploaderPort. + """ + def getEmbeddingsUploaderPort(self) -> EmbeddingsUploaderPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.vectorStore == PostgresVectorStoreType.PINECONE: + configuredVectorStore = VectorStorePineconeManager() + elif configuration.vectorStore == PostgresVectorStoreType.CHROMA_DB: + configuredVectorStore = VectorStoreChromaDBManager() + else: + raise ConfigurationException('Vector store non configurato.') + + if configuration.embeddingModel == PostgresEmbeddingModelType.HUGGINGFACE: + configuredEmbeddingModel = HuggingFaceEmbeddingModel() + elif configuration.embeddingModel == PostgresEmbeddingModelType.OPENAI: + configuredEmbeddingModel = OpenAIEmbeddingModel() + else: + raise ConfigurationException('Embeddings model non configurato.') + + return EmbeddingsUploaderFacadeLangchain( + Chunkerizer(), + EmbeddingsCreator(configuredEmbeddingModel), + EmbeddingsUploaderVectorStore(configuredVectorStore) + ) + + + """ + Gets the GetDocumentsStatusPort. + Returns: + GetDocumentsStatusPort: The GetDocumentsStatusPort. + """ + def getGetDocumentsStatusPort(self) -> GetDocumentsStatusPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.vectorStore == PostgresVectorStoreType.PINECONE: + configuredVectorStore = VectorStorePineconeManager() + elif configuration.vectorStore == PostgresVectorStoreType.CHROMA_DB: + configuredVectorStore = VectorStoreChromaDBManager() + else: + raise ConfigurationException('Vector store non configurato.') + + return GetDocumentsStatusVectorStore(configuredVectorStore) + + + """ + Gets the GetDocumentsMetadataPort. + Returns: + GetDocumentsMetadataPort: The GetDocumentsMetadataPort. + """ + def getGetDocumentsMetadataPort(self) -> GetDocumentsMetadataPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.documentStore == PostgresDocumentStoreType.AWS: + configuredDocumentStore = GetDocumentsListAWSS3( + AWSS3Manager() + ) + else: + raise ConfigurationException('Document store non configurato.') + + return configuredDocumentStore + + + """ + Gets the DeleteDocumentsPort. + Returns: + DeleteDocumentsPort: The DeleteDocumentsPort. + """ + def getDeleteDocumentsPort(self) -> DeleteDocumentsPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.documentStore == PostgresDocumentStoreType.AWS: + configuredDocumentStore = DeleteDocumentsAWSS3( + AWSS3Manager() + ) + else: + raise ConfigurationException('Document store non configurato.') + + return configuredDocumentStore + + + """ + Gets the DeleteEmbeddingsPort. + Returns: + DeleteEmbeddingsPort: The DeleteEmbeddingsPort. + """ + def getDeleteEmbeddingsPort(self) -> DeleteEmbeddingsPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.vectorStore == PostgresVectorStoreType.PINECONE: + configuredVectorStore = VectorStorePineconeManager() + elif configuration.vectorStore == PostgresVectorStoreType.CHROMA_DB: + configuredVectorStore = VectorStoreChromaDBManager() + else: + raise ConfigurationException('Vector store non configurato.') + + return DeleteEmbeddingsVectorStore(configuredVectorStore) + + + """ + Gets the ConcealDocumentsPort. + Returns: + ConcealDocumentsPort: The ConcealDocumentsPort. + """ + def getConcealDocumentsPort(self) -> ConcealDocumentsPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.vectorStore == PostgresVectorStoreType.PINECONE: + configuredVectorStore = VectorStorePineconeManager() + elif configuration.vectorStore == PostgresVectorStoreType.CHROMA_DB: + configuredVectorStore = VectorStoreChromaDBManager() + else: + raise ConfigurationException('Vector store non configurato.') + + return ConcealDocumentsVectorStore(configuredVectorStore) + + + """ + Gets the EnableDocumentsPort. + Returns: + EnableDocumentsPort: The EnableDocumentsPort. + """ + def getEnableDocumentsPort(self) -> EnableDocumentsPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.vectorStore == PostgresVectorStoreType.PINECONE: + configuredVectorStore = VectorStorePineconeManager() + elif configuration.vectorStore == PostgresVectorStoreType.CHROMA_DB: + configuredVectorStore = VectorStoreChromaDBManager() + else: + raise ConfigurationException('Vector store non configurato.') + + return EnableDocumentsVectorStore(configuredVectorStore) + + + """ + Gets the GetDocumentsContentPort. + Returns: + GetDocumentsContentPort: The GetDocumentsContentPort. + """ + def getGetDocumentsContentPort(self) -> GetDocumentsContentPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.documentStore == PostgresDocumentStoreType.AWS: + configuredDocumentStore = GetDocumentsContentAWSS3( + AWSS3Manager() + ) + else: + raise ConfigurationException('Document store non configurato.') + + return configuredDocumentStore + + + """ + Gets the AskChatbotPort. + Returns: + AskChatbotPort: The AskChatbotPort. + """ + def getAskChatbotPort(self) -> AskChatbotPort: + configuration = self.postgresConfigurationORM.getConfigurationChoices(os.environ.get('USER_ID')) + if configuration.vectorStore == PostgresVectorStoreType.PINECONE: + configuredVectorStore = VectorStorePineconeManager() + elif configuration.vectorStore == PostgresVectorStoreType.CHROMA_DB: + configuredVectorStore = VectorStoreChromaDBManager() + else: + raise ConfigurationException('Vector store non configurato.') + + if configuration.embeddingModel == PostgresEmbeddingModelType.HUGGINGFACE: + configuredEmbeddingModel = HuggingFaceEmbeddingModel() + elif configuration.embeddingModel == PostgresEmbeddingModelType.OPENAI: + configuredEmbeddingModel = OpenAIEmbeddingModel() + else: + raise ConfigurationException('Embedding model non configurato.') + + if configuration.LLMModel == PostgresLLMModelType.OPENAI: + with open('/run/secrets/openai_key', 'r') as file: + openai_key = file.read() + configuredLLMModel = OpenAI(openai_api_key=openai_key, model_name="gpt-3.5-turbo-instruct", temperature=0.3,) + elif configuration.LLMModel == PostgresLLMModelType.HUGGINGFACE: + with open('/run/secrets/huggingface_key', 'r') as file: + hugging_face = file.read() + configuredLLMModel = HuggingFaceEndpoint(repo_id="google/flan-t5-xxl", temperature=0.3, huggingfacehub_api_token=hugging_face) + else: + raise ConfigurationException('LLM model non configurato.') + + prompt = PromptTemplate( + input_variables=["chat_history", "context", "question"], + template="""Answer the question in your own words as truthfully as possible from the context given to you.\n +If you don't know the answer, just say that you don't know, don't try to make up an answer.\n +If questions are asked without relevant context, kindly request for questions pertinent to the documents and +don't give suggestions that are not based on the context given to you.\n +If the answer you provide includes some specific informations, don't invent this information and instead just say that you don't know and kindly +request for questions pertinent to the documents.\n +Always answer in Italian. +Chat History: +{chat_history} +Context: +{context} +Human: {question} +Assistant:""" + ) + + chain = ConversationalRetrievalChain.from_llm( + llm=configuredLLMModel, + retriever=configuredVectorStore.getRetriever(configuredEmbeddingModel), + return_source_documents=True, + combine_docs_chain_kwargs={'prompt': prompt}, + verbose = True + ) + return AskChatbotLangchain(chain=chain, chatHistoryManager=ChatHistoryManager()) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/delete_chats/delete_chats_postgres.py b/3 - PB/MVP/src/backend/adapter/out/delete_chats/delete_chats_postgres.py new file mode 100644 index 00000000..a5e35169 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/delete_chats/delete_chats_postgres.py @@ -0,0 +1,25 @@ +from typing import List +from domain.chat.chat_operation_response import ChatOperationResponse +from domain.chat.chat_id import ChatId +from application.port.out.delete_chats_port import DeleteChatsPort +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM + +""" +This class is the implementation of the DeleteChatsPort interface. It uses the PostgresChatORM to delete the chats. + Attributes: + postgresChatORM (PostgresChatORM): The PostgresChatORM to use to delete the chats. +""" +class DeleteChatsPostgres(DeleteChatsPort): + def __init__(self, postgresChatORM: PostgresChatORM): + self.postgresORM = postgresChatORM + + """ + Deletes the chats and returns the response. + Args: + chatsIdsList (List[ChatId]): The chats to delete. + Returns: + List[ChatOperationResponse]: The response of the operation. + """ + def deleteChats(self, chatsIdsList: List[ChatId]) -> List[ChatOperationResponse]: + postgresOperationResponseList = self.postgresORM.deleteChats([chatId.id for chatId in chatsIdsList]) + return [postgresChatOperationResponse.toChatOperationResponse() for postgresChatOperationResponse in postgresOperationResponseList] \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/delete_documents/delete_documents_AWSS3.py b/3 - PB/MVP/src/backend/adapter/out/delete_documents/delete_documents_AWSS3.py new file mode 100644 index 00000000..89427ec8 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/delete_documents/delete_documents_AWSS3.py @@ -0,0 +1,32 @@ +from typing import List + +from adapter.out.persistence.aws.AWS_manager import AWSS3Manager +from application.port.out.delete_documents_port import DeleteDocumentsPort +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This class is the implementation of the DeleteDocumentsPort interface. It uses the AWSS3Manager to delete the documents. + Attributes: + awss3manager (AWSS3Manager): The AWSS3Manager to use to delete the documents. +""" +class DeleteDocumentsAWSS3(DeleteDocumentsPort): + def __init__(self, awss3manager: AWSS3Manager): + self.awss3manager = awss3manager + + """ + Deletes the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to delete. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def deleteDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + #adaptee because awss3manager needs a List of string + documentsIdsString = [documentId.id for documentId in documentsIds] + awsDocumentOperationResponseList = self.awss3manager.deleteDocuments(documentsIdsString) + #return DocumentOperationResponse therefore we adaptee the response + documentOperationResponseList = [] + for awsDocumentOperationResponse in awsDocumentOperationResponseList: + documentOperationResponseList.append(awsDocumentOperationResponse.toDocumentOperationResponse()) + return documentOperationResponseList \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/delete_documents/delete_embeddings_vector_store.py b/3 - PB/MVP/src/backend/adapter/out/delete_documents/delete_embeddings_vector_store.py new file mode 100644 index 00000000..3a565469 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/delete_documents/delete_embeddings_vector_store.py @@ -0,0 +1,32 @@ +from typing import List + +from adapter.out.persistence.vector_store.vector_store_manager import VectorStoreManager +from application.port.out.delete_embeddings_port import DeleteEmbeddingsPort +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This class is the implementation of the DeleteEmbeddingsPort interface. It uses the VectorStoreManager to delete the documents embeddings. + Attributes: + vectorStoreManager (VectorStoreManager): The VectorStoreManager to use to delete the documents embeddings. +""" +class DeleteEmbeddingsVectorStore(DeleteEmbeddingsPort): + def __init__(self, vectorStoreManager: VectorStoreManager): + self.vectorStoreManager = vectorStoreManager + + """ + Deletes the documents embeddings and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to delete the embeddings. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def deleteDocumentsEmbeddings(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + #adaptee because vectorStoreManager needs a List of string + documentsIdsString = [documentId.id for documentId in documentsIds] + VectoreStoreDocumentOperationResponseList = self.vectorStoreManager.deleteDocumentsEmbeddings(documentsIdsString) + #return vectorStoreDocumentOperationResponse therefore we adapt the response + documentOperationResponseList = [] + for vectorStoreDocumentOperationResponse in VectoreStoreDocumentOperationResponseList: + documentOperationResponseList.append(vectorStoreDocumentOperationResponse.toDocumentOperationResponse()) + return documentOperationResponseList \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/enable_documents/enable_documents_vector_store.py b/3 - PB/MVP/src/backend/adapter/out/enable_documents/enable_documents_vector_store.py new file mode 100644 index 00000000..c94d5ffc --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/enable_documents/enable_documents_vector_store.py @@ -0,0 +1,32 @@ +from typing import List + +from adapter.out.persistence.vector_store.vector_store_manager import VectorStoreManager +from application.port.out.enable_documents_port import EnableDocumentsPort +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This class is the implementation of the EnableDocumentsPort interface. It uses the VectorStoreManager to enable the documents. + Attributes: + vectorStoreManager (VectorStoreManager): The VectorStoreManager to use to enable the documents. +""" +class EnableDocumentsVectorStore(EnableDocumentsPort): + def __init__(self, vectorStoreManager: VectorStoreManager): + self.vectorStoreManager = vectorStoreManager + + """ + Enables the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to enable. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def enableDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + #adaptee because vectorStoreManager needs a List of string + documentsIdsString = [documentId.id for documentId in documentsIds] + vectorStoreDocumentOperationResponseList = self.vectorStoreManager.enableDocuments(documentsIdsString) + #return DocumentOperationResponse therefore we adaptee the response + documentOperationResponseList = [] + for vectorStoreDocumentOperationResponse in vectorStoreDocumentOperationResponseList: + documentOperationResponseList.append(vectorStoreDocumentOperationResponse.toDocumentOperationResponse()) + return documentOperationResponseList \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/get_chat_messages/get_chat_messages_postgres.py b/3 - PB/MVP/src/backend/adapter/out/get_chat_messages/get_chat_messages_postgres.py new file mode 100644 index 00000000..ed41a3fc --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/get_chat_messages/get_chat_messages_postgres.py @@ -0,0 +1,24 @@ +from application.port.out.get_chat_messages_port import GetChatMessagesPort +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM +from domain.chat.chat import Chat +from domain.chat.chat_id import ChatId + +""" +This class is the implementation of the GetChatMessagesPort interface. It uses the PostgresChatORM to get the chat messages. + Attributes: + postgresORM (PostgresChatORM): The PostgresChatORM to use to get the chat messages. +""" +class GetChatMessagesPostgres(GetChatMessagesPort): + def __init__(self, postgresORM: PostgresChatORM): + self.postgresORM = postgresORM + + """ + Gets the chat messages and returns the chat. + Args: + chatId (ChatId): The chat id. + Returns: + Chat: The chat. + """ + def getChatMessages(self, chatId: ChatId) -> Chat: + chatMessages = self.postgresORM.getChatMessages(chatId.id) + return chatMessages.toChat() if chatMessages is not None else None \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/get_chats/get_chats_postgres.py b/3 - PB/MVP/src/backend/adapter/out/get_chats/get_chats_postgres.py new file mode 100644 index 00000000..cac30650 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/get_chats/get_chats_postgres.py @@ -0,0 +1,33 @@ +from typing import List + +from application.port.out.get_chats_port import GetChatsPort +from domain.chat.chat_filter import ChatFilter +from domain.chat.chat_preview import ChatPreview +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM + +""" +This class is the implementation of the GetChatsPort interface. It uses the PostgresChatORM to get the chats. + Attributes: + postgresORM (PostgresChatORM): The PostgresChatORM to use to get the chats. +""" +class GetChatsPostgres(GetChatsPort): + def __init__(self, postgresORM: PostgresChatORM): + self.postgresORM = postgresORM + + """ + Gets the chats and returns the chat previews. + Args: + chatFilter (ChatFilter): The chat filter. + Returns: + List[ChatPreview]: The chat previews. + """ + def getChats(self, chatFilter: ChatFilter) -> List[ChatPreview]: + listOfChatPreview = self.postgresORM.getChats(chatFilter.searchFilter) + if listOfChatPreview is not None: + chatsPreview = [] + for chatPreview in listOfChatPreview: + previewOfChat = chatPreview.toChatPreview() + chatsPreview.append(previewOfChat) + return chatsPreview + else: + return None \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/get_configuration/get_configuration_options_postgres.py b/3 - PB/MVP/src/backend/adapter/out/get_configuration/get_configuration_options_postgres.py new file mode 100644 index 00000000..f10b7eac --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/get_configuration/get_configuration_options_postgres.py @@ -0,0 +1,29 @@ +import os +from application.port.out.get_configuration_options_port import GetConfigurationOptionsPort +from domain.configuration.configuration_options import ConfigurationOptions +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM + +""" +This class is the implementation of the GetConfigurationOptionsPort interface. It uses the PostgresConfigurationORM to get the configuration options. +""" +class GetConfigurationOptionsPostgres(GetConfigurationOptionsPort): + def __init__(self, postgresConfigurationORM: PostgresConfigurationORM): + self.postgresConfigurationORM = postgresConfigurationORM + + """ + Gets the configuration options and returns them. + Returns: + ConfigurationOptions: The configuration options. + """ + def getConfigurationOptions(self) -> ConfigurationOptions: + postgresConfigurationVectorStoreOptions = self.postgresConfigurationORM.getVectorStoreOptions() + postgresConfigurationEmbeddingModelOptions = self.postgresConfigurationORM.getEmbeddingModelOptions() + postgresConfigurationLLMModelOptions = self.postgresConfigurationORM.getLLMModelOptions() + postgresConfigurationDocumentStoreOptions = self.postgresConfigurationORM.getDocumentStoreOptions() + + return ConfigurationOptions( + vectorStoreOptions=[option.toVectorStoreConfiguration() for option in postgresConfigurationVectorStoreOptions], + embeddingModelOptions=[option.toEmbeddingModelConfiguration() for option in postgresConfigurationEmbeddingModelOptions], + LLMModelOptions=[option.toLLMModelConfiguration() for option in postgresConfigurationLLMModelOptions], + documentStoreOptions=[option.toDocumentStoreConfiguration() for option in postgresConfigurationDocumentStoreOptions] + ) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/get_configuration/get_configuration_postgres.py b/3 - PB/MVP/src/backend/adapter/out/get_configuration/get_configuration_postgres.py new file mode 100644 index 00000000..e9e35c6e --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/get_configuration/get_configuration_postgres.py @@ -0,0 +1,27 @@ +import os + +from application.port.out.get_configuration_port import GetConfigurationPort +from domain.configuration.configuration import Configuration +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM + +""" +This class is the implementation of the GetConfigurationPort interface. It uses the PostgresConfigurationORM to get the configuration. + Attributes: + postgresConfigurationORM (PostgresConfigurationORM): The PostgresConfigurationORM to use to get the configuration. +""" +class GetConfigurationPostgres(GetConfigurationPort): + def __init__(self, postgresConfigurationORM: PostgresConfigurationORM): + self.postgresConfigurationORM = postgresConfigurationORM + + """ + Gets the configuration and returns it. + Returns: + Configuration: The configuration. + """ + def getConfiguration(self) -> Configuration: + userId = os.environ.get('USER_ID') + try: + postgresConfiguration = self.postgresConfigurationORM.getConfiguration(userId=userId) + return postgresConfiguration.toConfiguration() + except Exception as e: + return None \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_content_awss3.py b/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_content_awss3.py new file mode 100644 index 00000000..8fab4cab --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_content_awss3.py @@ -0,0 +1,34 @@ +import os +from typing import List + +from domain.document.document_id import DocumentId +from domain.document.plain_document import PlainDocument +from application.port.out.get_documents_content_port import GetDocumentsContentPort +from adapter.out.persistence.aws.AWS_manager import AWSS3Manager + +""" +This class is the implementation of the GetDocumentsContentPort interface. It uses the AWSS3Manager to get the documents content. + Attributes: + awsS3Manager (AWSS3Manager): The AWSS3Manager to use to get the documents content. +""" +class GetDocumentsContentAWSS3(GetDocumentsContentPort): + + def __init__(self, awsS3Manager: AWSS3Manager): + self.awsS3Manager = awsS3Manager + + """ + Gets the documents content and returns the response. + Args: + documentIds (List[DocumentId]): The documents to get the content. + Returns: + List[PlainDocument]: The content of the documents. + """ + def getDocumentsContent(self, documentIds: List[DocumentId]) -> List[PlainDocument]: + documents = [] + for documentId in documentIds: + retrievedDocument = self.awsS3Manager.getDocumentContent(documentId.id) + documents.append(retrievedDocument) + + plainDocuments = [document.toPlainDocument() if document is not None else None for document in documents] + return plainDocuments + diff --git a/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_list_awss3.py b/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_list_awss3.py new file mode 100644 index 00000000..1ac42b15 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_list_awss3.py @@ -0,0 +1,29 @@ +import os +from typing import List + +from adapter.out.persistence.aws.AWS_manager import AWSS3Manager +from domain.document.document_filter import DocumentFilter +from domain.document.document_metadata import DocumentMetadata +from application.port.out.get_documents_metadata_port import GetDocumentsMetadataPort + +""" +This class is the implementation of the GetDocumentsMetadataPort interface. It uses the AWSS3Manager to get the documents metadata. + Attributes: + awsS3Manager (AWSS3Manager): The AWSS3Manager to use to get the documents metadata. +""" +class GetDocumentsListAWSS3(GetDocumentsMetadataPort): + def __init__(self, awsS3Manager: AWSS3Manager): + self.awsS3Manager = awsS3Manager + """ + Gets the documents metadata and returns the response. + Args: + documentFilter (DocumentFilter): The document filter. + Returns: + List[DocumentMetadata]: The metadata of the documents. + """ + def getDocumentsMetadata(self, documentFilter: DocumentFilter) -> List[DocumentMetadata]: + documentsMetadatas = [] + documentsMetadata = self.awsS3Manager.getDocumentsMetadata(documentFilter.searchFilter) + for documentMetadata in documentsMetadata: + documentsMetadatas.append(documentMetadata.toDocumentMetadataFrom()) + return documentsMetadatas \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_status_vector_store.py b/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_status_vector_store.py new file mode 100644 index 00000000..a4318a87 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/get_documents/get_documents_status_vector_store.py @@ -0,0 +1,38 @@ +from typing import List, Dict + +from application.port.out.get_documents_status_port import GetDocumentsStatusPort +from adapter.out.persistence.vector_store.vector_store_manager import VectorStoreManager +from domain.document.document_id import DocumentId +from domain.document.document_status import DocumentStatus, Status + +""" +This class is the implementation of the GetDocumentsStatusPort interface. It uses the VectorStoreManager to get the documents status. + Attributes: + vectorStoreManager (VectorStoreManager): The VectorStoreManager to use to get the documents status. +""" +class GetDocumentsStatusVectorStore(GetDocumentsStatusPort): + def __init__(self, vectorStoreManager: VectorStoreManager): + self.vectorStoreManager = vectorStoreManager + + """ + Gets the documents status and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to get the status. + Returns: + List[DocumentStatus]: The status of the documents. + """ + def getDocumentsStatus(self, documentsIds: List[DocumentId]) -> List[DocumentStatus]: + documentsStatus = [] + statusResponses = self.vectorStoreManager.getDocumentsStatus(documentId.id for documentId in documentsIds) + for statusResponse in statusResponses: + if statusResponse.status.upper() == "CONCEALED": + documentStatus = DocumentStatus(status=Status.CONCEALED) + elif statusResponse.status.upper() == "ENABLED": + documentStatus = DocumentStatus(Status.ENABLED) + elif statusResponse.status.upper() == "INCONSISTENT": + documentStatus = DocumentStatus(Status.INCONSISTENT) + else: + documentStatus = DocumentStatus(Status.NOT_EMBEDDED) + documentsStatus.append(documentStatus) + return documentsStatus + diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_document.py b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_document.py new file mode 100644 index 00000000..ea5edd77 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_document.py @@ -0,0 +1,34 @@ +from datetime import datetime +from dataclasses import dataclass + +from domain.document.document_id import DocumentId +from domain.document.document_metadata import DocumentMetadata, DocumentType +from domain.document.document_content import DocumentContent +from domain.document.plain_document import PlainDocument + +""" + This class is used to represent a document that is stored in the AWS S3 bucket. +""" +@dataclass +class AWSDocument: + id: str + content: bytes + size: float + uploadTime: datetime + + """ + Converts the AWSDocument to a PlainDocument. + Returns: + PlainDocument: The PlainDocument converted from the AWSDocument. + """ + def toPlainDocument(self) -> PlainDocument: + return PlainDocument( + metadata=DocumentMetadata( + id=DocumentId(self.id), + type=DocumentType.PDF if self.id.rsplit(".", 1)[-1].lower() == "pdf" else DocumentType.DOCX, + size=self.size, + uploadTime=self.uploadTime + ), + content=DocumentContent(self.content) + ) + diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_document_metadata.py b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_document_metadata.py new file mode 100644 index 00000000..8f67b067 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_document_metadata.py @@ -0,0 +1,26 @@ +import os +from dataclasses import dataclass +from datetime import datetime + +from domain.document.document_id import DocumentId +from domain.document.document_metadata import DocumentMetadata, DocumentType + +""" +This class is used to store the metadata of a document stored in AWS S3. +""" +@dataclass +class AWSDocumentMetadata: + id: str + size: float + uploadTime: datetime + + """ + Converts the AWSDocumentMetadata to a DocumentMetadata. + Returns: + DocumentMetadata: The DocumentMetadata converted from the AWSDocumentMetadata. + """ + def toDocumentMetadataFrom(self) -> DocumentMetadata: + return DocumentMetadata(id=DocumentId(self.id), + type=DocumentType.PDF if self.id.rsplit(".", 1)[-1].lower() == "pdf" else DocumentType.DOCX, + size=self.size, + uploadTime=self.uploadTime) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_document_operation_response.py b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_document_operation_response.py new file mode 100644 index 00000000..50f4634d --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_document_operation_response.py @@ -0,0 +1,28 @@ +from domain.document.document_operation_response import DocumentOperationResponse +from domain.document.document_id import DocumentId +from dataclasses import dataclass + +""" +This class is used to store the response of a document operation in AWS S3. +""" +@dataclass +class AWSDocumentOperationResponse: + documentId: str + status: bool + message: str + + """ + Converts the AWSDocumentOperationResponse to a DocumentOperationResponse. + Returns: + DocumentOperationResponse: The DocumentOperationResponse converted from the AWSDocumentOperationResponse. + """ + def toDocumentOperationResponse(self) -> DocumentOperationResponse: + return DocumentOperationResponse(DocumentId(self.documentId), self.status, self.message) + + """ + Returns the status of the operation. + Returns: + bool: The status of the operation. + """ + def ok(self) -> bool: + return self.status \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_manager.py b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_manager.py new file mode 100644 index 00000000..3f796705 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/aws/AWS_manager.py @@ -0,0 +1,166 @@ +from typing import List + +import boto3 +from adapter.out.persistence.aws.AWS_document import AWSDocument +from adapter.out.persistence.aws.AWS_document_operation_response import AWSDocumentOperationResponse +from adapter.out.persistence.aws.AWS_document_metadata import AWSDocumentMetadata + +from datetime import datetime + +from botocore.exceptions import ClientError + +""" + This class is responsible for managing the AWS S3 bucket. + Attributes: + s3 (boto3.client): The boto3 client for S3 operations. + bucket_name (str): The name of the S3 bucket. + Methods: + getDocumentById(documentId: str) -> AWSDocument: + Get the document from the S3 bucket by its ID. + uploadDocuments(awsDocuments: List[AWSDocument], forceUpload: bool) -> List[AWSDocumentOperationResponse]: + Upload the documents to the S3 bucket. + deleteDocuments(ListOfDocumentId: List[str]) -> List[AWSDocumentOperationResponse]: + Delete the documents from the S3 bucket. + getDocumentsMetadata(documentFilter: str) -> List[AWSDocumentMetadata]: + Get the metadata of the documents from the S3 bucket. +""" +class AWSS3Manager: + def __init__(self): + with open('/run/secrets/aws_access_key_id', 'r') as file: + aws_access_key_id = file.read() + with open('/run/secrets/aws_secret_access_key', 'r') as file: + aws_secret_access_key = file.read() + with open('/run/secrets/aws_bucket_name', 'r') as file: + awsBucketName = file.read() + self.awsBucketName = awsBucketName + self.s3 = boto3.client( + 's3', + aws_access_key_id=aws_access_key_id, + aws_secret_access_key=aws_secret_access_key, + region_name="eu-west-1" + ) + + """ + Get the document from the S3 bucket by its ID. + Args: + documentId (str): The ID of the document to get. + Returns: + AWSDocument: The document from the S3 bucket. + """ + def getDocumentById(self, documentId: str) -> AWSDocument: + try: + aws = self.s3.get_object(Bucket=self.awsBucketName, Key=documentId) + id = aws.get('Key') + content = aws.get('Body').read() + size = aws.get('ContentLength') + uploadTime = aws.get('LastModified') + except Exception as e: + return None + return AWSDocument( + id=id, + content=content, + size=size, + uploadTime=uploadTime + ) + + """ + Upload the documents to the S3 bucket. + Args: + awsDocuments (List[AWSDocument]): The documents to upload. + forceUpload (bool): The flag to force the upload of the documents. + Returns: + List[AWSDocumentOperationResponse]: The response of the upload operation. + """ + def uploadDocuments(self, awsDocuments: List[AWSDocument], forceUpload: bool) -> List[AWSDocumentOperationResponse]: + AWSDocumentOperationResponses = [] + + if not forceUpload: + for awsDocument in awsDocuments: + try: + self.s3.head_object(Bucket=self.awsBucketName, Key=awsDocument.id) + # The document is already present in the system, so it cannot be uploaded. + AWSDocumentOperationResponses.append(AWSDocumentOperationResponse(awsDocument.id, False, "Il documento è già presente nel sistema.")) + except Exception as e: + # The document is not present in the system, so it can be uploaded. + try: + self.s3.put_object(Bucket=self.awsBucketName, Key=awsDocument.id, Body=awsDocument.content) + AWSDocumentOperationResponses.append(AWSDocumentOperationResponse(awsDocument.id, True, "Caricamento del documento avvenuto con successo.")) + except Exception as e: + # An error occurred during the put_object operation. + AWSDocumentOperationResponses.append(AWSDocumentOperationResponse(awsDocument.id, False, f"Errore durante il caricamento del documento: {e}")) + continue + else: + # The forceUpload flag is set to True, so the documents can be uploaded without checking if they are already present in the system. + for awsDocument in awsDocuments: + try: + self.s3.put_object(Bucket=self.awsBucketName, Key=awsDocument.id, Body=awsDocument.content) + AWSDocumentOperationResponses.append(AWSDocumentOperationResponse(awsDocument.id, True, "Caricamento del documento avvenuto con successo.")) + except Exception as e: + # An error occurred during the put_object operation. + AWSDocumentOperationResponses.append(AWSDocumentOperationResponse(awsDocument.id, False, f"Errore durante il caricamento del documento: {e}")) + continue + + return AWSDocumentOperationResponses + + """ + Delete the documents from the S3 bucket. + Args: + documentsIds (List[str]): The documents to delete. + Returns: + List[AWSDocumentOperationResponse]: The response of the delete operation. + """ + def deleteDocuments(self, documentsIds: List[str]) -> List[AWSDocumentOperationResponse]: + AWSDocumentOperationResponses = [] + + for documentId in documentsIds: + try: + self.s3.delete_object(Bucket=self.awsBucketName, Key=documentId) + AWSDocumentOperationResponses.append(AWSDocumentOperationResponse(documentId, True, "Eliminazione del documento avvenuta con successo.")) + except ClientError as e: + if e.response['Error']['Code'] == 'NoSuchKey': + AWSDocumentOperationResponses.append(AWSDocumentOperationResponse(documentId, False, "Il documento non è presente nel sistema.")) + else: + AWSDocumentOperationResponses.append(AWSDocumentOperationResponse(documentId, False, f"Errore durante l'eliminazione del documento: {e}")) + continue + + return AWSDocumentOperationResponses + + """ + Get the metadata of the documents from the S3 bucket. + Args: + documentFilter (str): The filter to apply to the documents. + Returns: + List[AWSDocumentMetadata]: The metadata of the documents from the S3 bucket. + """ + def getDocumentsMetadata(self, documentFilter: str) -> List[AWSDocumentMetadata]: + awsDocumentsMetadata = [] + documentMetadataResponse = self.s3.list_objects_v2(Bucket=self.awsBucketName, Prefix=documentFilter) + contents = documentMetadataResponse.get('Contents', []) + for content in contents: + awsDocumentsMetadata.append( + AWSDocumentMetadata( + id=content.get('Key'), + size=content.get('Size'), + uploadTime=content.get('LastModified'), + ) + ) + return awsDocumentsMetadata + + """ + Get the document content from the S3 bucket by its ID. + Args: + documentId (str): The ID of the document to get the content. + Returns: + AWSDocument: The document content from the S3 bucket. + """ + def getDocumentContent(self, documentId: str) -> AWSDocument: + try: + documentContentResponse = self.s3.get_object(Bucket=self.awsBucketName, Key=documentId) + return AWSDocument( + id=documentId, + content=documentContentResponse.get('Body').read(), + size=documentContentResponse.get('ContentLength'), + uploadTime=documentContentResponse.get('LastModified') + ) + except Exception as e: + return None diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_history_manager.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_history_manager.py new file mode 100644 index 00000000..ad5efcfe --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_history_manager.py @@ -0,0 +1,32 @@ +from typing import List + +from langchain_community.chat_message_histories import PostgresChatMessageHistory +from langchain_core.messages import BaseMessage +import os + +from domain.chat.chat_id import ChatId +from langchain.memory import ConversationBufferMemory + +""" +This class is the implementation of the ChatHistoryManager interface. It uses the PostgresChatMessageHistory to get the chat history. + Attributes: + None +""" +class ChatHistoryManager: + + """ + Gets the chat history and returns the chat history. + Args: + chatId (int): The chat id. + Returns: + PostgresChatMessageHistory: The chat history. + """ + def getChatHistory(self, chatId: int)-> PostgresChatMessageHistory: + try: + history = PostgresChatMessageHistory( + connection_string=os.environ.get('DATABASE_URL'), + session_id=str(chatId), + ) + return history + except Exception: + return None diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_models.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_models.py new file mode 100644 index 00000000..46cf1302 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/chat_models.py @@ -0,0 +1,91 @@ +from sqlalchemy import Column, Integer, String, Text, JSON, ForeignKey +from sqlalchemy.orm import relationship +from adapter.out.persistence.postgres.database import Base, db_session + +""" +This class is the ORM of the chat table. + Attributes: + id (Column): The id of the chat. + title (Column): The title of the chat. + messages_cascade (relationship): The messages of the chat. +""" +class Chat(Base): + __tablename__ = 'chat' + id = Column('id', Integer, primary_key=True, autoincrement=True) + title = Column('title', Text, unique=True, nullable=False) + + messages_cascade = relationship( + 'MessageStore', + back_populates="messages_cascade_rel", + cascade="all, delete, delete-orphan", + passive_deletes=True + ) + + def __init__(self, title: str) -> None: + self.title = title + + """ + Returns the string representation of the chat. + Returns: + str: The string representation of the chat. + """ + def __repr__(self): + return f'({self.id}, {self.title})' + +""" +This class is the ORM of the message_store table. + Attributes: + id (Column): The id of the message. + sessionId (Column): The session id of the message. + message (Column): The message. + messages_cascade_rel (relationship): The chat of the message. + relevant_documents_cascade (relationship): The relevant documents of the message. +""" +class MessageStore(Base): + __tablename__ = 'message_store' + id = Column('id', Integer, primary_key=True, autoincrement=True) + sessionId = Column('session_id', Integer, ForeignKey('chat.id', ondelete='CASCADE')) + message = Column('message', JSON) + + messages_cascade_rel = relationship("Chat", back_populates="messages_cascade") + relevant_documents_cascade = relationship( + 'MessageRelevantDocuments', + back_populates="relevant_documents_cascade_rel", + cascade="all, delete, delete-orphan", + passive_deletes=True + ) + + def __init__(self, sessionId: str, message: str) -> None: + self.sessionId = sessionId + self.message = message + + def __repr__(self): + return f'({self.id}, {self.session_id}, {self.message})' + +""" +This class is the ORM of the message_relevant_documents table. + Attributes: + id (Column): The id of the message. + documentId (Column): The document id. + relevant_documents_cascade_rel (relationship): The message of the relevant documents. +""" +class MessageRelevantDocuments(Base): + __tablename__ = 'message_relevant_documents' + id = Column('id', Integer, ForeignKey('message_store.id', ondelete='CASCADE'), primary_key=True) + documentId = Column('document_id', Text, primary_key=True) + + relevant_documents_cascade_rel = relationship("MessageStore", back_populates="relevant_documents_cascade") + + def __init__(self, id: str, documentId: str) -> None: + self.id = id + self.documentId = documentId + + def __repr__(self): + return f'({self.id}, {self.documentId})' +""" +Initializes the chat table. +Returns: + None +""" +def initChat(): + Base.metadata.create_all(bind=db_session.bind) diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/configuration_models.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/configuration_models.py new file mode 100644 index 00000000..f65607a3 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/configuration_models.py @@ -0,0 +1,265 @@ +from sqlalchemy import Column, Integer, String, Enum as SQLEnum, ForeignKey +from enum import Enum +from sqlalchemy.orm import relationship + +from domain.configuration.document_store_configuration import DocumentStoreConfiguration, DocumentStoreType +from domain.configuration.embedding_model_configuration import EmbeddingModelConfiguration, EmbeddingModelType +from domain.configuration.llm_model_configuration import LLMModelConfiguration, LLMModelType +from domain.configuration.vector_store_configuration import VectorStoreConfiguration, VectorStoreType + +from adapter.out.persistence.postgres.database import Base, db_session + + +class PostgresDocumentStoreType(Enum): + AWS = 1 + + def toDocumentStoreType(self): + if self == PostgresDocumentStoreType.AWS: + return DocumentStoreType.AWS + +class PostgresVectorStoreType(Enum): + PINECONE = 1 + CHROMA_DB = 2 + + def toVectorStoreType(self): + if self == PostgresVectorStoreType.PINECONE: + return VectorStoreType.PINECONE + elif self == PostgresVectorStoreType.CHROMA_DB: + return VectorStoreType.CHROMA_DB + +class PostgresLLMModelType(Enum): + OPENAI = 1 + HUGGINGFACE = 2 + + def toLLMModelType(self): + if self == PostgresLLMModelType.OPENAI: + return LLMModelType.OPENAI + elif self == PostgresLLMModelType.HUGGINGFACE: + return LLMModelType.HUGGINGFACE + +class PostgresEmbeddingModelType(Enum): + OPENAI = 1 + HUGGINGFACE = 2 + + def toEmbeddingModelType(self): + if self == PostgresEmbeddingModelType.OPENAI: + return EmbeddingModelType.OPENAI + elif self == PostgresEmbeddingModelType.HUGGINGFACE: + return EmbeddingModelType.HUGGINGFACE + +""" +This class is the ORM of the vectorStoreConfiguration table. + Attributes: + name (Column): The name of the vector store. + organization (Column): The organization of the vector store. + description (Column): The description of the vector store. + type (Column): The type of the vector store. + costIndicator (Column): The cost indicator of the vector store. +""" +class PostgresVectorStoreConfiguration(Base): + __tablename__ = 'vectorStoreConfiguration' + name = Column('name', SQLEnum(PostgresVectorStoreType), primary_key=True) + organization = Column('organization', String) + description = Column('description', String) + type = Column('type', String) + costIndicator = Column('costIndicator', String) + + def __init__(self, name: PostgresVectorStoreType, organization: str, description: str, type: str, costIndicator: str): + self.name = name + self.organization = organization + self.description = description + self.type = type + self.costIndicator = costIndicator + + def __repr__(self): + return f'({self.name}, {self.organization}, {self.description}, {self.type}, {self.costIndicator})' + + """ + Converts the vector store configuration to a VectorStoreConfiguration. + Returns: + VectorStoreConfiguration: The vector store configuration. + """ + def toVectorStoreConfiguration(self): + return VectorStoreConfiguration( + self.name.toVectorStoreType(), + self.organization, + self.description, + self.type, + self.costIndicator + ) + +""" +This class is the ORM of the embeddingModelConfiguration table. + Attributes: + name (Column): The name of the embedding model. + organization (Column): The organization of the embedding model. + description (Column): The description of the embedding model. + type (Column): The type of the embedding model. + costIndicator (Column): The cost indicator of the embedding model. +""" +class PostgresEmbeddingModelConfiguration(Base): + __tablename__ = 'embeddingModelConfiguration' + name = Column('name', SQLEnum(PostgresEmbeddingModelType), primary_key=True) + organization = Column('organization', String) + description = Column('description', String) + type = Column('type', String) + costIndicator = Column('costIndicator', String) + + def __init__(self, name: PostgresEmbeddingModelType, organization: str, description: str, type: str, costIndicator: str): + self.name = name + self.organization = organization + self.description = description + self.type = type + self.costIndicator = costIndicator + + def __repr__(self): + return f'({self.name}, {self.organization}, {self.description}, {self.type}, {self.costIndicator})' + + """ + Converts the embedding model configuration to an EmbeddingModelConfiguration. + Returns: + EmbeddingModelConfiguration: The embedding model configuration. + """ + def toEmbeddingModelConfiguration(self): + return EmbeddingModelConfiguration( + self.name.toEmbeddingModelType(), + self.organization, + self.description, + self.type, + self.costIndicator + ) + +""" +This class is the ORM of the LLMModelConfiguration table. + Attributes: + name (Column): The name of the LLM model. + organization (Column): The organization of the LLM model. + description (Column): The description of the LLM model. + type (Column): The type of the LLM model. + costIndicator (Column): The cost indicator of the LLM model. +""" +class PostgresLLMModelConfiguration(Base): + __tablename__ = 'LLMModelConfiguration' + name = Column('name', SQLEnum(PostgresLLMModelType), primary_key=True) + organization = Column('organization', String) + description = Column('description', String) + type = Column('type', String) + costIndicator = Column('costIndicator', String) + + def __init__(self, name: PostgresLLMModelType, organization: str, description: str, type: str, costIndicator: str): + self.name = name + self.organization = organization + self.description = description + self.type = type + self.costIndicator = costIndicator + + def __repr__(self): + return f'({self.name}, {self.organization}, {self.description}, {self.type}, {self.costIndicator})' + + """ + Converts the LLM model configuration to an LLMModelConfiguration. + Returns: + LLMModelConfiguration: The LLM model configuration. + """ + def toLLMModelConfiguration(self): + return LLMModelConfiguration( + self.name.toLLMModelType(), + self.organization, + self.description, + self.type, + self.costIndicator + ) + +""" +This class is the ORM of the documentStoreConfiguration table. + Attributes: + name (Column): The name of the document store. + organization (Column): The organization of the document store. + description (Column): The description of the document store. + type (Column): The type of the document store. + costIndicator (Column): The cost indicator of the document store. +""" +class PostgresDocumentStoreConfiguration(Base): + __tablename__ = 'documentStoreConfiguration' + name = Column('name', SQLEnum(PostgresDocumentStoreType), primary_key=True) + organization = Column('organization', String) + description = Column('description', String) + type = Column('type', String) + costIndicator = Column('costIndicator', String) + + def __init__(self, name: PostgresDocumentStoreType, organization: str, description: str, type: str, costIndicator: str): + self.name = name + self.organization = organization + self.description = description + self.type = type + self.costIndicator = costIndicator + + def __repr__(self): + return f'({self.name}, {self.organization}, {self.description}, {self.type}, {self.costIndicator})' + + """ + Converts the document store configuration to a DocumentStoreConfiguration. + Returns: + DocumentStoreConfiguration: The document store configuration. + """ + def toDocumentStoreConfiguration(self): + return DocumentStoreConfiguration( + self.name.toDocumentStoreType(), + self.organization, + self.description, + self.type, + self.costIndicator + ) + +""" +This class is the ORM of the configuration table. + Attributes: + userId (Column): The user id of the configuration. + vectorStore (Column): The vector store of the configuration. + embeddingModel (Column): The embedding model of the configuration. + LLMModel (Column): The LLM model of the configuration. + documentStore (Column): The document store of the configuration. + vectorStoreConstraint (relationship): The vector store of the configuration. + embeddingModelConstraint (relationship): The embedding model of the configuration. + LLMModelConstraint (relationship): The LLM model of the configuration. + documentStoreConstraint (relationship): The document store of the configuration. +""" +class PostgresConfigurationChoice(Base): + __tablename__ = 'configuration' + userId = Column('userId', Integer, primary_key=True) + vectorStore = Column('vectorStore', SQLEnum(PostgresVectorStoreType), ForeignKey('vectorStoreConfiguration.name')) + embeddingModel = Column('embeddingModel', SQLEnum(PostgresEmbeddingModelType), ForeignKey('embeddingModelConfiguration.name')) + LLMModel = Column('LLMModel', SQLEnum(PostgresLLMModelType), ForeignKey('LLMModelConfiguration.name')) + documentStore = Column('documentStore', SQLEnum(PostgresDocumentStoreType), ForeignKey('documentStoreConfiguration.name')) + + vectorStoreConstraint = relationship(PostgresVectorStoreConfiguration, foreign_keys=[vectorStore]) + embeddingModelConstraint = relationship(PostgresEmbeddingModelConfiguration, foreign_keys=[embeddingModel]) + LLMModelConstraint = relationship(PostgresLLMModelConfiguration, foreign_keys=[LLMModel]) + documentStoreConstraint = relationship(PostgresDocumentStoreConfiguration, foreign_keys=[documentStore]) + + def __init__(self, userId: int, vectorStore: PostgresVectorStoreType, embeddingModel: PostgresEmbeddingModelType, LLMModel: PostgresLLMModelType, documentStore: PostgresDocumentStoreType): + self.userId = userId + self.vectorStore = vectorStore + self.embeddingModel = embeddingModel + self.LLMModel = LLMModel + self.documentStore = documentStore + + def __repr__(self): + return f'({self.userId}, {self.vectorStore}, {self.embeddingModel}, {self.LLMModel}, {self.documentStore})' + +""" +Initializes the configuration. +Returns: + None +""" +def initConfiguration(): + Base.metadata.create_all(bind=db_session.bind) + if len(db_session.query(PostgresDocumentStoreConfiguration).all()) == 0: + db_session.add(PostgresVectorStoreConfiguration(name=PostgresVectorStoreType.CHROMA_DB, organization='Chroma', description='Chroma DB is an open-source vector store.', type='Open-source', costIndicator='Free')) + db_session.add(PostgresVectorStoreConfiguration(name=PostgresVectorStoreType.PINECONE, organization='Pinecone', description='Pinecone is a vector database for building real-time applications.', type='On cloud', costIndicator='Paid')) + db_session.add(PostgresEmbeddingModelConfiguration(name=PostgresEmbeddingModelType.HUGGINGFACE, organization='Hugging Face', description='Hugging Face is a company that provides a large number of pre-trained models for natural language processing.', type='Local', costIndicator='Free')) + db_session.add(PostgresEmbeddingModelConfiguration(name=PostgresEmbeddingModelType.OPENAI, organization='OpenAI', description='OpenAI is an artificial intelligence research laboratory.', type='Commercial', costIndicator='Paid')) + db_session.add(PostgresLLMModelConfiguration(name=PostgresLLMModelType.HUGGINGFACE, organization='Hugging Face', description='Hugging Face is a company that provides a large number of pre-trained models for natural language processing.', type='Local', costIndicator='Free')) + db_session.add(PostgresLLMModelConfiguration(name=PostgresLLMModelType.OPENAI, organization='OpenAI', description='OpenAI is an artificial intelligence research laboratory.', type='Commercial', costIndicator='Paid')) + db_session.add(PostgresDocumentStoreConfiguration(name=PostgresDocumentStoreType.AWS, organization='Amazon', description='Amazon Web Services is a subsidiary of Amazon providing on-demand cloud computing platforms and APIs to individuals.', type='On cloud', costIndicator='Paid')) + db_session.commit() \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/database.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/database.py new file mode 100644 index 00000000..3886c004 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/database.py @@ -0,0 +1,20 @@ +import os + +from sqlalchemy import create_engine +from sqlalchemy.orm import declarative_base, scoped_session, sessionmaker + +Base = declarative_base() + +engine = create_engine(os.environ.get('DATABASE_URL')) +db_session = scoped_session(sessionmaker(bind=engine)) + +""" +Initializes the database. +Returns: + None +""" +def init_db(): + from adapter.out.persistence.postgres.configuration_models import initConfiguration + from adapter.out.persistence.postgres.chat_models import initChat + initConfiguration() + initChat() \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat.py new file mode 100644 index 00000000..0992efbf --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat.py @@ -0,0 +1,26 @@ +from dataclasses import dataclass +from typing import List + +from adapter.out.persistence.postgres.postgres_message import PostgresMessage +from domain.chat.chat import Chat +from domain.chat.chat_id import ChatId + +""" +This class is used to store the chat in Postgres. +""" +@dataclass +class PostgresChat: + id: int + title: str + messages: List[PostgresMessage] + + """ + Converts the PostgresChat to a Chat. + Returns: + Chat: The Chat converted from the PostgresChat. + """ + def toChat(self): + listOfMessages = [] + for message in self.messages: + listOfMessages.append(message.toMessage()) + return Chat(title=self.title, chatId= ChatId(self.id), messages=listOfMessages) diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_operation_response.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_operation_response.py new file mode 100644 index 00000000..41ae3303 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_operation_response.py @@ -0,0 +1,28 @@ +from dataclasses import dataclass +from domain.chat.chat_operation_response import ChatOperationResponse +from domain.chat.chat_id import ChatId + +""" +This class is used to store the response of a chat operation in Postgres. +""" +@dataclass +class PostgresChatOperationResponse: + status: bool + message: str + chatId: int + + """ + Converts the PostgresChatOperationResponse to a ChatOperationResponse. + Returns: + ChatOperationResponse: The ChatOperationResponse converted from the PostgresChatOperationResponse. + """ + def toChatOperationResponse(self): + return ChatOperationResponse(status=self.status, message=self.message, chatId=ChatId(self.chatId)) + + """ + Returns the status of the operation. + Returns: + bool: The status of the operation. + """ + def ok(self) -> bool: + return self.status \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_orm.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_orm.py new file mode 100644 index 00000000..a1eae9f7 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_orm.py @@ -0,0 +1,167 @@ +from datetime import datetime, timezone +from typing import List +from adapter.out.persistence.postgres.chat_models import Chat, MessageStore, MessageRelevantDocuments + +from adapter.out.persistence.postgres.database import db_session + +from adapter.out.persistence.postgres.postgres_chat_operation_response import PostgresChatOperationResponse +from adapter.out.persistence.postgres.postgres_message import PostgresMessage, PostgresMessageSenderType +from adapter.out.persistence.postgres.postgres_chat_preview import PostgresChatPreview +from adapter.out.persistence.postgres.postgres_chat import PostgresChat + +""" +This class is the ORM of the chat table. + Attributes: + id (Column): The id of the chat. + title (Column): The title of the chat. + messages_cascade (relationship): The messages of the chat. +""" +class PostgresChatORM: + def __init__(self) -> None: + pass + + """ + Persists the chat and returns the response. + Args: + messages (List[PostgresMessage]): The messages to persist. + chatId (int): The chat id. + Returns: + PostgresChatOperationResponse: The response of the operation. + """ + def persistChat(self, messages: List[PostgresMessage], chatId: int = None) -> PostgresChatOperationResponse: + if len(messages) == 0: + return PostgresChatOperationResponse(False, "Nessun messaggio da salvare.", None) + + if chatId is None: + newChatResponse = self.createChat() + if not newChatResponse.ok(): + return newChatResponse + return self.saveMessages(messages, newChatResponse.chatId) + else: + return self.saveMessages(messages, chatId) + + """ + Creates a chat and returns the response. + Returns: + PostgresChatOperationResponse: The response of the operation. + """ + def createChat(self) -> PostgresChatOperationResponse: + try: + newChat = Chat(f"Nuova chat {datetime.now(timezone.utc).strftime('%X %d %b %Y')}") + db_session.add(newChat) + db_session.commit() + newChatId = newChat.id + return PostgresChatOperationResponse(True, "Chat creata correttamente.", newChatId) + except Exception as e: + return PostgresChatOperationResponse(False, f"Errore nella creazione della chat: {str(e)}", None) + + """ + Saves the messages and returns the response. + Args: + messages (List[PostgresMessage]): The messages to save. + chatId (int): The chat id. + Returns: + PostgresChatOperationResponse: The response of the operation. + """ + def saveMessages(self, messages: List[PostgresMessage], chatId: int) -> PostgresChatOperationResponse: + try: + newMessages = [MessageStore(chatId, {"type": message.sender.name, "data": {"content": message.content, "timestamp": message.timestamp.isoformat()}}) for message in messages] + db_session.add_all(newMessages) + db_session.commit() + newMessageIds = [newMessage.id for newMessage in newMessages] + + messageRelevantDocuments = [] + for i, message in enumerate(messages): + if message.relevantDocuments is not None: + for document in message.relevantDocuments: + messageRelevantDocuments.append(MessageRelevantDocuments(id=newMessageIds[i], documentId=document)) + db_session.add_all(messageRelevantDocuments) + db_session.commit() + return PostgresChatOperationResponse(True, "Messaggi salvati correttamente.", chatId) + except Exception as e: + return PostgresChatOperationResponse(False, f"Errore nel salvataggio dei messaggi: {str(e)}", chatId) + + """ + Deletes the chats and returns the response. + Args: + chatIds (List[int]): The chat ids. + Returns: + List[PostgresChatOperationResponse]: The response of the operation. + """ + def deleteChats(self, chatIds: List[int]) -> List[PostgresChatOperationResponse]: + try: + db_session.query(Chat).filter(Chat.id.in_(chatIds)).delete(synchronize_session=False) + db_session.commit() + return [PostgresChatOperationResponse(True, "Chat eliminata correttamente.", chatId) for chatId in chatIds] + except Exception as e: + return [PostgresChatOperationResponse(False, f"Errore nella eliminazione della chat: {str(e)}", chatId) for chatId in chatIds] + + """ + Renames the chat and returns the response. + Args: + chatId (int): The chat id. + newName (str): The new name of the chat. + Returns: + PostgresChatOperationResponse: The response of the operation. + """ + def renameChat(self, chatId: int, newName: str) -> PostgresChatOperationResponse: + try: + affectedRows = db_session.query(Chat).filter(Chat.id == chatId).update({"title": newName}) + db_session.commit() + + if affectedRows > 0: + return PostgresChatOperationResponse(True, "Chat rinominata correttamente.", chatId) + else: + return PostgresChatOperationResponse(False, "Nessuna chat trovata con l'ID specificato.", chatId) + except Exception as e: + return PostgresChatOperationResponse(False, f"Errore nella rinomina della chat: {str(e)}", chatId) + + """ + Gets the chats and returns the response. + Args: + chatFilter (str): The filter to apply to the chats. + Returns: + List[PostgresChatPreview]: The response of the operation. + """ + def getChats(self, chatFilter:str) -> List[PostgresChatPreview]: + try: + chats = db_session.query(Chat).filter(Chat.title.like(f"%{chatFilter}%")).all() + chatPreviews : List[PostgresChatPreview] = [] + for chat in chats: + lastMessage = db_session.query(MessageStore).filter(MessageStore.sessionId == chat.id).order_by(MessageStore.id.desc()).first() + if lastMessage is not None: + chatPreviews.append(PostgresChatPreview(chat.id, chat.title, PostgresMessage( + lastMessage.message["data"]["content"], + datetime.fromisoformat(lastMessage.message["data"]["timestamp"]), + [document.documentId for document in db_session.query(MessageRelevantDocuments).filter(MessageRelevantDocuments.id == lastMessage.id).all()], + PostgresMessageSenderType[lastMessage.message["type"]])) + ) + else: + chatPreviews.append(PostgresChatPreview(chat.id, chat.title, None)) + chatPreviews.sort(key=lambda chat: chat.lastMessage.timestamp, reverse=True) + return chatPreviews + except Exception as e: + return None + + """ + Gets the chat messages and returns the response. + Args: + chatId (int): The chat id. + Returns: + PostgresChat: The response of the operation. + """ + def getChatMessages(self, chatId: int) -> PostgresChat: + try: + chat = db_session.query(Chat).filter(Chat.id == chatId).first() + messages = db_session.query(MessageStore).filter(MessageStore.sessionId == chatId).all() + postgresMessages = [ + PostgresMessage( + message.message["data"]["content"], + datetime.fromisoformat(message.message["data"]["timestamp"]), + [document.documentId for document in db_session.query(MessageRelevantDocuments).filter(MessageRelevantDocuments.id == message.id).all()], + PostgresMessageSenderType[message.message["type"]] + ) for message in messages] + + return PostgresChat(chat.id, chat.title, sorted(postgresMessages, key=lambda message: message.timestamp)) + except Exception as e: + return None diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_preview.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_preview.py new file mode 100644 index 00000000..b436e1f0 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_chat_preview.py @@ -0,0 +1,20 @@ +from domain.chat.chat_id import ChatId +from domain.chat.chat_preview import ChatPreview +from adapter.out.persistence.postgres.postgres_message import PostgresMessage + +""" +This class is used to store the chat preview in Postgres. +""" +class PostgresChatPreview: + def __init__(self, id: int, title:str, postgresMessage: PostgresMessage): + self.id = id + self.title = title + self.lastMessage = postgresMessage + + """ + Converts the PostgresChatPreview to a ChatPreview. + Returns: + ChatPreview: The ChatPreview converted from the PostgresChatPreview. + """ + def toChatPreview(self) -> ChatPreview: + return ChatPreview(id=ChatId(self.id), title=self.title, lastMessage=self.lastMessage.toMessage()) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_configuration.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_configuration.py new file mode 100644 index 00000000..45f23b88 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_configuration.py @@ -0,0 +1,37 @@ +from dataclasses import dataclass +from adapter.out.persistence.postgres.configuration_models import PostgresVectorStoreConfiguration, PostgresEmbeddingModelConfiguration, PostgresLLMModelConfiguration, PostgresDocumentStoreConfiguration +from domain.configuration.configuration import Configuration +from domain.configuration.document_store_configuration import DocumentStoreConfiguration +from domain.configuration.embedding_model_configuration import EmbeddingModelConfiguration +from domain.configuration.llm_model_configuration import LLMModelConfiguration +from domain.configuration.vector_store_configuration import VectorStoreConfiguration + +""" +This class is used to store the configuration in Postgres. + attributes: + id: int + documentStore: PostgresDocumentStoreConfiguration + vectorStore: PostgresVectorStoreConfiguration + embeddingModel: PostgresEmbeddingModelConfiguration + LLMModel: PostgresLLMModelConfiguration +""" +@dataclass +class PostgresConfiguration: + id: int + documentStore: PostgresDocumentStoreConfiguration + vectorStore: PostgresVectorStoreConfiguration + embeddingModel: PostgresEmbeddingModelConfiguration + LLMModel: PostgresLLMModelConfiguration + + """ + Converts the PostgresConfiguration to a Configuration. + Returns: + Configuration: The Configuration converted from the PostgresConfiguration. + """ + def toConfiguration(self): + return Configuration( + vectorStore=self.vectorStore.toVectorStoreConfiguration() if self.vectorStore else None, + embeddingModel=self.embeddingModel.toEmbeddingModelConfiguration() if self.embeddingModel else None, + LLMModel=self.LLMModel.toLLMModelConfiguration() if self.LLMModel else None, + documentStore=self.documentStore.toDocumentStoreConfiguration() if self.documentStore else None + ) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_configuration_operation_response.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_configuration_operation_response.py new file mode 100644 index 00000000..c031f1a7 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_configuration_operation_response.py @@ -0,0 +1,27 @@ +from dataclasses import dataclass +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse + +""" +This class is used to store the response of a configuration operation in Postgres. +""" +@dataclass +class PostgresConfigurationOperationResponse: + status: bool + message: str + + """ + Returns the status of the operation. + Returns: + bool: The status of the operation. + """ + + def ok(self) -> bool: + return self.status + + """ + Returns a ConfigurationOperationResponse object with the same status and message. + Returns: + ConfigurationOperationResponse: The ConfigurationOperationResponse object. + """ + def toConfigurationOperationResponse(self): + return ConfigurationOperationResponse(self.ok(), self.message) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_configuration_orm.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_configuration_orm.py new file mode 100644 index 00000000..28f18ed9 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_configuration_orm.py @@ -0,0 +1,125 @@ +from typing import List +from adapter.out.persistence.postgres.configuration_models import PostgresConfigurationChoice, PostgresVectorStoreConfiguration, PostgresEmbeddingModelConfiguration, PostgresLLMModelConfiguration, PostgresDocumentStoreConfiguration, PostgresLLMModelType, PostgresVectorStoreType, PostgresEmbeddingModelType, PostgresDocumentStoreType + +from adapter.out.persistence.postgres.database import db_session + +from adapter.out.persistence.postgres.postgres_configuration_operation_response import PostgresConfigurationOperationResponse +from adapter.out.persistence.postgres.postgres_configuration import PostgresConfiguration + +""" +This class is the ORM of the configuration table. + Attributes: + None +""" +class PostgresConfigurationORM: + + """ + Gets the configuration of the user. + Args: + userId (int): The id of the user. + Returns: + PostgresConfiguration: The configuration of the user. + """ + def getConfiguration(self, userId: int) -> PostgresConfiguration: + userConfiguration = db_session.query(PostgresConfigurationChoice).filter(PostgresConfigurationChoice.userId == userId).first() + if userConfiguration is None: + return PostgresConfiguration(userId, None, None, None, None) + vectorStore = db_session.query(PostgresVectorStoreConfiguration).filter(PostgresVectorStoreConfiguration.name == userConfiguration.vectorStore).first() + embeddingModel = db_session.query(PostgresEmbeddingModelConfiguration).filter(PostgresEmbeddingModelConfiguration.name == userConfiguration.embeddingModel).first() + LLMModel = db_session.query(PostgresLLMModelConfiguration).filter(PostgresLLMModelConfiguration.name == userConfiguration.LLMModel).first() + documentStore = db_session.query(PostgresDocumentStoreConfiguration).filter(PostgresDocumentStoreConfiguration.name == userConfiguration.documentStore).first() + + return PostgresConfiguration(userId, vectorStore=vectorStore, embeddingModel=embeddingModel, LLMModel=LLMModel, documentStore=documentStore) + + """ + Gets the configuration choices of the user. + Args: + userId (int): The id of the user. + Returns: + PostgresConfigurationChoice: The configuration choices of the user. + """ + def getConfigurationChoices(self, userId: int) -> PostgresConfigurationChoice: + return db_session.query(PostgresConfigurationChoice).filter(PostgresConfigurationChoice.userId == userId).first() + + """ + Sets the configuration and returns the response. + Args: + userId (int): The id of the user. + LLMModel (PostgresLLMModelType): The LLM model to set; + DocumentStore (PostgresDocumentStoreType): The Document Store to set; + VectorStore (PostgresVectorStoreType): The Vector Store to set; + EmbeddingModel (PostgresEmbeddingModelType): The Embedding Model to set. + Returns: + PostgresConfigurationOperationResponse: The response of the operation. + """ + def setConfiguration(self, userId: int, LLMModel: PostgresLLMModelType, DocumentStore: PostgresDocumentStoreType, VectorStore: PostgresVectorStoreType, EmbeddingModel: PostgresEmbeddingModelType) -> PostgresConfigurationOperationResponse: + try: + existingConfiguration = self.getConfigurationChoices(userId) + if existingConfiguration is None: + db_session.add(PostgresConfigurationChoice(userId=userId, LLMModel=LLMModel, documentStore=DocumentStore, vectorStore=VectorStore, embeddingModel=EmbeddingModel)) + db_session.commit() + return PostgresConfigurationOperationResponse(True, 'Configurazione aggiornata con successo') + else: + raise Exception('Configurazione già impostata.') + except Exception as e: + db_session.rollback() + return PostgresConfigurationOperationResponse(False, f'Errore nell\'aggiornamento della configurazione: {str(e)}') + """ + Changes the vector store and returns the response. + Args: + userId (int): The id of the user. + vectorStore (PostgresVectorStoreType): The vector store to change. + Returns: + PostgresConfigurationOperationResponse: The response of the operation. + """ + def changeLLMModel(self, userId: int, LLMModel: PostgresLLMModelType) -> PostgresConfigurationOperationResponse: + try: + db_session.query(PostgresConfigurationChoice).filter(PostgresConfigurationChoice.userId == userId).update({PostgresConfigurationChoice.LLMModel: LLMModel}) + db_session.commit() + return PostgresConfigurationOperationResponse(True, 'Modello LLM aggiornato con successo') + except Exception as e: + db_session.rollback() + return PostgresConfigurationOperationResponse(False, f'Errore nell\'aggiornamento del modello LLM: {str(e)}') + + """ + Changes the vector store and returns the response. + Args: + userId (int): The id of the user. + vectorStore (PostgresVectorStoreType): The vector store to change. + Returns: + PostgresConfigurationOperationResponse: The response of the operation. + """ + def getVectorStoreOptions(self) -> List[PostgresVectorStoreConfiguration]: + return db_session.query(PostgresVectorStoreConfiguration).order_by(PostgresVectorStoreConfiguration.name).all() + """ + Changes the vector store and returns the response. + Args: + userId (int): The id of the user. + vectorStore (PostgresVectorStoreType): The vector store to change. + Returns: + PostgresConfigurationOperationResponse: The response of the operation. + """ + def getEmbeddingModelOptions(self) -> List[PostgresEmbeddingModelConfiguration]: + return db_session.query(PostgresEmbeddingModelConfiguration).order_by(PostgresEmbeddingModelConfiguration.name).all() + + """ + Changes the vector store and returns the response. + Args: + userId (int): The id of the user. + vectorStore (PostgresVectorStoreType): The vector store to change. + Returns: + PostgresConfigurationOperationResponse: The response of the operation. + """ + def getLLMModelOptions(self) -> List[PostgresLLMModelConfiguration]: + return db_session.query(PostgresLLMModelConfiguration).order_by(PostgresLLMModelConfiguration.name).all() + + """ + Changes the vector store and returns the response. + Args: + userId (int): The id of the user. + vectorStore (PostgresVectorStoreType): The vector store to change. + Returns: + PostgresConfigurationOperationResponse: The response of the operation. + """ + def getDocumentStoreOptions(self) -> List[PostgresDocumentStoreConfiguration]: + return db_session.query(PostgresDocumentStoreConfiguration).order_by(PostgresDocumentStoreConfiguration.name).all() \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_message.py b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_message.py new file mode 100644 index 00000000..6c91139b --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/postgres/postgres_message.py @@ -0,0 +1,48 @@ +from typing import List +from dataclasses import dataclass +from datetime import datetime +from enum import Enum + +from domain.chat.message import Message, MessageSender +from domain.document.document_id import DocumentId + +""" +This class is used to store the message in Postgres. + attributes: + content: str + timestamp: datetime + relevantDocuments: List[str] + sender: PostgresMessageSenderType +""" +@dataclass +class PostgresMessageSenderType(Enum): + human = 1 + ai = 2 + +""" +This class is used to store the message in Postgres. + attributes: + content: str + timestamp: datetime + relevantDocuments: List[str] + sender: PostgresMessageSenderType +""" +@dataclass +class PostgresMessage: + content: str + timestamp: datetime + relevantDocuments: List[str] + sender: PostgresMessageSenderType + + """ + Converts the PostgresMessage to a Message. + Returns: + Message: The Message converted from the PostgresMessage. + """ + def toMessage(self) -> Message: + return Message( + self.content, + self.timestamp, + [DocumentId(relevantDocument) for relevantDocument in self.relevantDocuments], + MessageSender.USER if self.sender.value == PostgresMessageSenderType.human.value else MessageSender.CHATBOT + ) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/langchain_document.py b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/langchain_document.py new file mode 100644 index 00000000..7aee669f --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/langchain_document.py @@ -0,0 +1,16 @@ +from typing import List +from langchain_core.documents.base import Document as LangchainCoreDocument +from dataclasses import dataclass + +""" +This class is used to store the document in Langchain. + Attributes: + documentId: str + chunks: List[LangchainCoreDocument] + embeddings: List[List[float]] +""" +@dataclass +class LangchainDocument: + documentId: str + chunks: List[LangchainCoreDocument] + embeddings: List[List[float]] diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_chromaDB_manager.py b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_chromaDB_manager.py new file mode 100644 index 00000000..05567774 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_chromaDB_manager.py @@ -0,0 +1,162 @@ +import os +from typing import List +import chromadb +from langchain_core.retrievers import BaseRetriever + +from adapter.out.persistence.vector_store.vector_store_manager import VectorStoreManager +from adapter.out.persistence.vector_store.vector_store_document_operation_response import VectorStoreDocumentOperationResponse +from adapter.out.persistence.vector_store.vector_store_document_status_response import VectorStoreDocumentStatusResponse +from langchain_core.documents.base import Document as LangchainCoreDocument +from langchain_community.vectorstores import Chroma +from adapter.out.upload_documents.langchain_embedding_model import LangchainEmbeddingModel + +""" +This class is the implementation of the VectorStoreManager interface. It uses the ChromaDB to manage the documents embeddings. + Attributes: + chromadb (chromadb.PersistentClient): The ChromaDB to use to manage the documents embeddings. + collection (chromadb.Collection): The collection of the ChromaDB to use to manage the documents embeddings. +""" +class VectorStoreChromaDBManager(VectorStoreManager): + def __init__(self): + self.chromadb = chromadb.PersistentClient(path=os.environ.get("CHROMA_DB_PATH")) + with open('/run/secrets/chromadb_collection', 'r') as file: + chromadbCollection = file.read() + self.collection = self.chromadb.get_or_create_collection(chromadbCollection) + + """ + Gets the status of the documents and returns the response. + Args: + documentsIds (List[str]): The documents to get the status. + Returns: + List[VectorStoreDocumentStatusResponse]: The response of the operation. + """ + + def getDocumentsStatus(self, documentsIds: List[str]) -> List[VectorStoreDocumentStatusResponse]: + vectorStoreDocumentStatusResponses = [] + for documentId in documentsIds: + try: + chunksMetadata = self.collection.get(where={"source": documentId}, include = ["metadatas"]).get('metadatas', []) + + documentStatus = {chunkMetadata.get("status", "") for chunkMetadata in chunksMetadata} + documentStatus.discard("") + + if len(documentStatus) == 0: + vectorStoreDocumentStatusResponses.append(VectorStoreDocumentStatusResponse(documentId, 'NOT_EMBEDDED')) + elif len(documentStatus) == 1: + vectorStoreDocumentStatusResponses.append(VectorStoreDocumentStatusResponse(documentId, documentStatus.pop())) + else: + vectorStoreDocumentStatusResponses.append(VectorStoreDocumentStatusResponse(documentId, 'INCONSISTENT')) + except: + vectorStoreDocumentStatusResponses.append(VectorStoreDocumentStatusResponse(documentId, None)) + continue + + return vectorStoreDocumentStatusResponses + """ + Deletes the documents embeddings and returns the response. + Args: + documentsIds (List[str]): The documents to delete the embeddings. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def deleteDocumentsEmbeddings(self, documentsIds: List[str]) -> List[VectorStoreDocumentOperationResponse]: + vectorStoreDocumentOperationResponses = [] + for documentId in documentsIds: + try: + self.collection.delete(where = {"source": documentId}) + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, True, "Eliminazione embeddings avvenuta con successo.")) + except: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, "Errore nell'eliminazione degli embeddings.")) + continue + + return vectorStoreDocumentOperationResponses + + """ + Conceals the documents and returns the response. + Args: + documentsIds (List[str]): The documents to conceal. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def concealDocuments(self, documentsIds: List[str]) -> List[VectorStoreDocumentOperationResponse]: + vectorStoreDocumentOperationResponses = [] + + for documentId in documentsIds: + try: + embeddingsIds=(self.collection.get(where = {"source" : documentId})).get("ids", None) + self.collection.update( + ids=embeddingsIds, + metadatas=[{"status": "CONCEALED"} for _ in range(len(embeddingsIds))]) + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, True, "Documento occultato con successo.")) + except Exception as e: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, "Errore nell'occultamento del documento.")) + continue + + return vectorStoreDocumentOperationResponses + """ + Disables the documents and returns the response. + Args: + documentsIds (List[str]): The documents to disable. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def enableDocuments(self, documentsIds: List[str]) -> List[VectorStoreDocumentOperationResponse]: + vectorStoreDocumentOperationResponses = [] + + for documentId in documentsIds: + try: + embeddingsIds=(self.collection.get(where = {"source" : documentId})).get("ids", None) + self.collection.update( + ids=embeddingsIds, + metadatas=[{"status": "ENABLED"} for _ in range(len(embeddingsIds))]) + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, True, "Documento riabilitato con successo.")) + except Exception as e: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, "Errore nella riabilitazione del documento.")) + continue + + return vectorStoreDocumentOperationResponses + """ + Uploads the documents embeddings and returns the response. + Args: + documentsIds (List[str]): The documents to upload the embeddings. + documentsChunks (List[List[LangchainCoreDocument]]): The documents chunks to upload the embeddings. + documentsEmbeddings (List[List[List[float]]]): The documents embeddings to upload. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def uploadEmbeddings(self, documentsIds: List[str], documentsChunks: List[List[LangchainCoreDocument]], documentsEmbeddings: List[List[List[float]]]) -> List[VectorStoreDocumentOperationResponse]: + vectorStoreDocumentOperationResponses = [] + + for documentId, documentChunks, documentEmbeddings in zip(documentsIds, documentsChunks, documentsEmbeddings): + ids=[f"{documentId}@{i}" for i in range(len(documentChunks))] + + metadatas = [ + { + "page": chunk.metadata.get('page', 'NULL'), + "source": chunk.metadata.get('source', documentId), + "status": 'ENABLED' + } for chunk in documentChunks + ] + + try: + self.collection.add( + ids = ids, + embeddings = documentEmbeddings, + documents = [chunk.page_content for chunk in documentChunks], + metadatas = metadatas + ) + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, True, "Creazione embeddings avvenuta con successo.")) + except: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, "Errore nel caricamento degli embeddings.")) + continue + return vectorStoreDocumentOperationResponses + + """ + Changes the vector store and returns the response. + Args: + userId (int): The id of the user. + vectorStore (str): The vector store to change. + Returns: + VectorStoreDocumentOperationResponse: The response of the operation. + """ + def getRetriever(self, embeddingModel : LangchainEmbeddingModel) -> BaseRetriever: + return Chroma(client=self.chromadb, collection_name = self.collection.name, embedding_function=embeddingModel.getEmbeddingFunction()).as_retriever(search_type="similarity_score_threshold", search_kwargs={'filter': {'status':'ENABLED'}, 'score_threshold': 0.05}) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_document_operation_response.py b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_document_operation_response.py new file mode 100644 index 00000000..a2db5413 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_document_operation_response.py @@ -0,0 +1,27 @@ +from domain.document.document_operation_response import DocumentOperationResponse +from domain.document.document_id import DocumentId +from dataclasses import dataclass + +""" +This class is used to store the response of a document operation in the Vector Store. + attributes: + documentId: str + status: bool + message: str +""" +@dataclass +class VectorStoreDocumentOperationResponse: + documentId: str + status: bool + message: str + + """ + Converts the VectorStoreDocumentOperationResponse to a DocumentOperationResponse. + Returns: + DocumentOperationResponse: The DocumentOperationResponse converted from the VectorStoreDocumentOperationResponse. + """ + def toDocumentOperationResponse(self) -> DocumentOperationResponse: + return DocumentOperationResponse(DocumentId(self.documentId), self.status, self.message) + + def ok(self) -> bool: + return self.status \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_document_status_response.py b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_document_status_response.py new file mode 100644 index 00000000..f04c80ac --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_document_status_response.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass + +""" +This class is used to store the response of a document status operation in the Vector Store. + attributes: + documentId: str + status: str +""" +@dataclass +class VectorStoreDocumentStatusResponse: + documentId: str + status: str + + def ok(self) -> bool: + return self.status \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_manager.py b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_manager.py new file mode 100644 index 00000000..8ce859d2 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_manager.py @@ -0,0 +1,76 @@ +from typing import List + +from langchain_core.retrievers import BaseRetriever + +from adapter.out.persistence.vector_store.vector_store_document_operation_response import VectorStoreDocumentOperationResponse +from adapter.out.persistence.vector_store.vector_store_document_status_response import VectorStoreDocumentStatusResponse + +from langchain_core.documents.base import Document as LangchainCoreDocument + +from adapter.out.upload_documents.langchain_embedding_model import LangchainEmbeddingModel + +""" +This interface is used to manage the documents embeddings. +""" +class VectorStoreManager: + """ + Gets the status of the documents and returns the response. + Args: + documentsIds (List[str]): The documents to get the status. + Returns: + List[VectorStoreDocumentStatusResponse]: The response of the operation. + """ + def getDocumentsStatus(self, documentsIds: List[str]) -> List[VectorStoreDocumentStatusResponse]: + pass + + """ + Deletes the documents embeddings and returns the response. + Args: + documentsIds (List[str]): The documents to delete the embeddings. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def deleteDocumentsEmbeddings(self, documentsIds: List[str]) -> List[VectorStoreDocumentOperationResponse]: + pass + + """ + Conceals the documents and returns the response. + Args: + documentsIds (List[str]): The documents to conceal. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def concealDocuments(self, documentsIds: List[str]) -> List[VectorStoreDocumentOperationResponse]: + pass + + """ + Enables the documents and returns the response. + Args: + documentsIds (List[str]): The documents to enable. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def enableDocuments(self, documentsIds: List[str]) -> List[VectorStoreDocumentOperationResponse]: + pass + + """ + Uploads the documents embeddings and returns the response. + Args: + documentsIds (List[str]): The documents to upload the embeddings. + documentsChunks (List[List[LangchainCoreDocument]]): The documents chunks to upload the embeddings. + documentsEmbeddings (List[List[List[float]]]): The documents embeddings to upload. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def uploadEmbeddings(self, documentsIds: List[str], documentsChunks: List[List[LangchainCoreDocument]], documentsEmbeddings: List[List[List[float]]]) -> List[VectorStoreDocumentOperationResponse]: + pass + + """ + Gets the retriever. + Args: + embeddingModel (LangchainEmbeddingModel): The embedding model to use. + Returns: + BaseRetriever: The retriever. + """ + def getRetriever(self, embeddingModel : LangchainEmbeddingModel) -> BaseRetriever: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_pinecone_manager.py b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_pinecone_manager.py new file mode 100644 index 00000000..ac5630ca --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/persistence/vector_store/vector_store_pinecone_manager.py @@ -0,0 +1,248 @@ +from typing import List + +from langchain_core.retrievers import BaseRetriever +from pinecone import Pinecone +from pinecone import PineconeApiException +from adapter.out.persistence.vector_store.vector_store_manager import VectorStoreManager +from adapter.out.persistence.vector_store.vector_store_document_operation_response import VectorStoreDocumentOperationResponse +from adapter.out.persistence.vector_store.vector_store_document_status_response import VectorStoreDocumentStatusResponse +from langchain_core.documents.base import Document as LangchainCoreDocument +from langchain_community.vectorstores import Pinecone as PineconeLangchain +from adapter.out.upload_documents.langchain_embedding_model import LangchainEmbeddingModel + + +""" + This class is the implementation of the VectorStoreManager interface. It uses the Pinecone to manage the documents embeddings. + Attributes: + pinecone (Pinecone): The Pinecone to use to manage the documents embeddings. + index (Pinecone.Index): The index of the Pinecone to use to manage the documents embeddings. + dimension (int): The dimension of the embeddings. +""" +class VectorStorePineconeManager(VectorStoreManager): + def __init__(self): + with open('/run/secrets/pinecone_api', 'r') as file: + pineconeApi = file.read() + with open('/run/secrets/pinecone_environment', 'r') as file: + pineconeEnvironment = file.read() + with open('/run/secrets/pinecone_index_name', 'r') as file: + pineconeIndexName = file.read() + + self.pinecone = Pinecone( + api_key=pineconeApi, + environment=pineconeEnvironment + ) + self.index = self.pinecone.Index(pineconeIndexName) + self.dimension = self.pinecone.describe_index(pineconeIndexName).get('dimension', 768) + + + """ + Gets the status of the documents and returns the response. + Args: + documentsIds (List[str]): The documents to get the status. + Returns: + List[VectorStoreDocumentStatusResponse]: The response of the operation. + """ + def getDocumentsStatus(self, documentsIds: List[str]) -> List[VectorStoreDocumentStatusResponse]: + vectorStoreDocumentStatusResponses = [] + for documentId in documentsIds: + try: + queryResponse = self.index.query( + top_k = 1, + vector = [0.0 for _ in range(self.dimension)], + include_values = False, + include_metadata = True, + filter = { + "source": {"$eq": documentId} + } + ) + documentStatus = {documentEmbeddingsMatch.get('metadata', {}).get('status', None) for documentEmbeddingsMatch in queryResponse.get('matches', [])} + documentStatus.discard(None) + + if len(documentStatus) == 0: + vectorStoreDocumentStatusResponses.append(VectorStoreDocumentStatusResponse(documentId, 'NOT_EMBEDDED')) + elif len(documentStatus) == 1: + vectorStoreDocumentStatusResponses.append(VectorStoreDocumentStatusResponse(documentId, documentStatus.pop())) + else: + vectorStoreDocumentStatusResponses.append(VectorStoreDocumentStatusResponse(documentId, 'INCONSISTENT')) + except PineconeApiException: + vectorStoreDocumentStatusResponses.append(VectorStoreDocumentStatusResponse(documentId, None)) + continue + + return vectorStoreDocumentStatusResponses + + + """ + Deletes the documents embeddings and returns the response. + Args: + documentsIds (List[str]): The documents to delete the embeddings. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def deleteDocumentsEmbeddings(self, documentsIds: List[str]) -> List[VectorStoreDocumentOperationResponse]: + vectorStoreDocumentOperationResponses = [] + for documentId in documentsIds: + try: + queryResponse = self.index.query( + top_k = 10000, + vector = [0.0 for _ in range(self.dimension)], + include_values = False, + include_metadata = False, + filter = { + "source": {"$eq": documentId} + } + ) + ids = {match.get('id', '') for match in queryResponse.get('matches', [])} + ids.discard('') + + if len(ids) > 0: + deleteResponse = self.index.delete(ids=list(ids)) + if deleteResponse: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, f"{deleteResponse.get('message', 'Errore nella eliminazione degli embeddings.')}")) + else: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, True, "Eliminazione embeddings avvenuta con successo.")) + else: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, True, "Nessun embedding trovato da eliminare.")) + except PineconeApiException as e: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, f"Errore nell'eliminazione degli embeddings: {e}")) + + return vectorStoreDocumentOperationResponses + + + """ + Conceals the documents and returns the response. + Args: + documentsIds (List[str]): The documents to conceal. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def concealDocuments(self, documentsIds: List[str]) -> List[VectorStoreDocumentOperationResponse]: + vectorStoreDocumentOperationResponses = [] + for documentId in documentsIds: + messageError = [] + try: + queryResponse = self.index.query( + top_k = 10000, + vector = [0.0 for _ in range(self.dimension)], + include_values = False, + include_metadata = False, + filter = { + "source": {"$eq": documentId} + } + ) + documentEmbeddings = [match.get('id', '') for match in queryResponse.get('matches', [{}])] + flagError = False + for documentEmbedding in documentEmbeddings: + concealResponse = self.index.update( + id = documentEmbedding, + set_metadata = {"status": "CONCEALED"} + ) + if concealResponse: + flagError = True + messageError.append(concealResponse.get('message', "Errore nell'occultamento del documento.")) + if flagError: + concatenated_messages = "-".join(messageError) + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, f"{concatenated_messages}")) + else: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, True, "Documento occultato con successo.")) + except PineconeApiException as e: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, f"Errore nell'occultamento del documento: {e}")) + + return vectorStoreDocumentOperationResponses + + + """ + Enables the documents and returns the response. + Args: + documentsIds (List[str]): The documents to enable. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def enableDocuments(self, documentsIds: List[str]) -> List[VectorStoreDocumentOperationResponse]: + vectorStoreDocumentOperationResponses = [] + for documentId in documentsIds: + messageError = [] + try: + queryResponse = self.index.query( + top_k = 10000, + vector = [0.0 for _ in range(self.dimension)], + include_values = False, + include_metadata = False, + filter = { + "source": {"$eq": documentId} + } + ) + documentEmbeddings = [match.get('id', '') for match in queryResponse.get('matches', [{}])] + flagError = False + for documentEmbedding in documentEmbeddings: + concealResponse = self.index.update( + id = documentEmbedding, + set_metadata = {"status": "ENABLED"} + ) + if concealResponse: + flagError = True + messageError.append(concealResponse.get('message', "Errore nella riabilitazione del documento.")) + if flagError: + concatenated_messages = "-".join(messageError) + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, f"{concatenated_messages}")) + else: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, True, "Documento riabilitato con successo.")) + except PineconeApiException as e: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, f"Errore nella riabilitazione del documento: {e}")) + + return vectorStoreDocumentOperationResponses + + + """ + Uploads the documents embeddings and returns the response. + Args: + documentsId (List[str]): The documents to upload the embeddings. + documentsChunks (List[List[LangchainCoreDocument]]): The documents chunks to upload the embeddings. + documentsEmbeddings (List[List[List[float]]]): The documents embeddings to upload. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def uploadEmbeddings(self, documentsId: List[str], documentsChunks: List[List[LangchainCoreDocument]], documentsEmbeddings: List[List[List[float]]]) -> List[VectorStoreDocumentOperationResponse]: + vectorStoreDocumentOperationResponses = [] + for documentId, documentChunks, documentEmbeddings in zip(documentsId, documentsChunks, documentsEmbeddings): + ids=[f"{documentId}@{i}" for i in range(len(documentChunks))] + + metadatas = [ + { + "text": documentChunk.page_content, + "page": documentChunk.metadata.get('page',-1), + "source": documentChunk.metadata.get('source', documentId), + "status": documentChunk.metadata.get('status', 'ENABLED') + } for documentChunk in documentChunks + ] + + try: + uploadResponse = self.index.upsert( + vectors = [ + { + "id": id, + "metadata": metadata, + "values": documentEmbedding + } for id, metadata, documentEmbedding in zip(ids, metadatas, documentEmbeddings) + ] + ) + + if uploadResponse.get('upserted_count', 0) != len(documentChunks): + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, f"{uploadResponse.get('message', 'Errore nel caricamento degli embeddings.')}")) + else: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, True, "Creazione embeddings avvenuta con successo.")) + except PineconeApiException as e: + vectorStoreDocumentOperationResponses.append(VectorStoreDocumentOperationResponse(documentId, False, f"Errore nel caricamento degli embeddings: {e}")) + + return vectorStoreDocumentOperationResponses + + + """ + Gets the retriever. + Args: + LangchainEmbeddingModel: The embedding model to use to get the retriever. + Returns: + BaseRetriever: The retriever. + + """ + def getRetriever(self, embeddingModel : LangchainEmbeddingModel) -> BaseRetriever: + return PineconeLangchain(self.index, embeddingModel.getEmbeddingFunction(), "text").as_retriever(search_type="similarity_score_threshold", search_kwargs={'filter': {'status':'ENABLED'}, 'score_threshold': 0.05}) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/rename_chat/rename_chat_postgres.py b/3 - PB/MVP/src/backend/adapter/out/rename_chat/rename_chat_postgres.py new file mode 100644 index 00000000..99dfff10 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/rename_chat/rename_chat_postgres.py @@ -0,0 +1,26 @@ +from application.port.out.rename_chat_port import RenameChatPort +from domain.chat.chat_id import ChatId +from domain.chat.chat_operation_response import ChatOperationResponse +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM + +""" +This class is the implementation of the RenameChatPort interface. It uses the PostgresChatORM to rename the chat. + Attributes: + postgresChatORM (PostgresChatORM): The PostgresChatORM to use to rename the chat. +""" +class RenameChatPostgres(RenameChatPort): + def __init__(self, postgresChatORM: PostgresChatORM): + self.outPort = postgresChatORM + + + """ + Renames the chat and returns the response. + Args: + chatId (ChatId): The chat id. + title (str): The new title of the chat. + Returns: + ChatOperationResponse: The response of the operation. + """ + def renameChat(self, chatId: ChatId, title: str) -> ChatOperationResponse: + postgresChatOperationResponse = self.outPort.renameChat(chatId.id, title) + return postgresChatOperationResponse.toChatOperationResponse() \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/set_configuration/set_configuration_postgres.py b/3 - PB/MVP/src/backend/adapter/out/set_configuration/set_configuration_postgres.py new file mode 100644 index 00000000..5b4051af --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/set_configuration/set_configuration_postgres.py @@ -0,0 +1,81 @@ +import os +from application.port.out.set_configuration_port import SetConfigurationPort +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +from domain.configuration.llm_model_configuration import LLMModelType +from adapter.out.persistence.postgres.configuration_models import PostgresLLMModelType +from domain.configuration.document_store_configuration import DocumentStoreType +from adapter.out.persistence.postgres.configuration_models import PostgresDocumentStoreType +from domain.configuration.vector_store_configuration import VectorStoreType +from adapter.out.persistence.postgres.configuration_models import PostgresVectorStoreType +from domain.configuration.embedding_model_configuration import EmbeddingModelType +from adapter.out.persistence.postgres.configuration_models import PostgresEmbeddingModelType +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM + +""" +This class is the implementation of the SetConfigurationPort interface. It uses the PostgresConfigurationORM to set the configuration. + Attributes: + postgresConfigurationORM (PostgresConfigurationORM): The PostgresConfigurationORM to use to set the configuration. +""" +class SetConfigurationPostgres(SetConfigurationPort): + def __init__(self, postgresConfigurationORM: PostgresConfigurationORM): + self.postgresConfigurationORM = postgresConfigurationORM + + """ + Set the configuration and returns the response. + Args: + LLModel (LLMModelType): The LLM model to set; + DocumentStore (DocumentStoreType): The Document Store to set; + VectorStore (VectorStoreType): The Vector Store to set; + EmbeddingModel (EmbeddingModelType): The Embedding Model to set. + Returns: + ConfigurationOperationResponse: The response of the operation. + """ + def setConfiguration(self, LLModel: LLMModelType, DocumentStore: DocumentStoreType, VectorStore: VectorStoreType, EmbeddingModel: EmbeddingModelType) -> ConfigurationOperationResponse: + LLMModelChoice = self.toPostgresLLMModelTypeFrom(LLModel) + DocumentStoreChoice = self.toPostgresDocumentStoreTypeFrom(DocumentStore) + VectorStoreChoice = self.toPostgresVectorStoreTypeFrom(VectorStore) + EmbeddingModelChoice = self.toPostgresEmbeddingModelTypeFrom(EmbeddingModel) + userId = os.environ.get('USER_ID') + + postgresConfigurationOperationResponse = self.postgresConfigurationORM.setConfiguration(userId, LLMModelChoice, DocumentStoreChoice, VectorStoreChoice, EmbeddingModelChoice) + return postgresConfigurationOperationResponse.toConfigurationOperationResponse() + + """ + Converts the LLMModelType to the PostgresLLMModelType. + Args: + LLMModel (LLMModelType): The LLM model to convert. + Returns: + PostgresLLMModelType: The converted LLM model. + """ + def toPostgresLLMModelTypeFrom(self, LLMModel: LLMModelType) -> PostgresLLMModelType: + return PostgresLLMModelType[LLMModel.name] + + """ + Converts the DocumentStoreType to the PostgresDocumentStoreType. + Args: + DocumentStore (DocumentStoreType): The Document Store to convert. + Returns: + PostgresDocumentStoreType: The converted Document Store. + """ + def toPostgresDocumentStoreTypeFrom(self, DocumentStore: DocumentStoreType) -> PostgresDocumentStoreType: + return PostgresDocumentStoreType[DocumentStore.name] + + """ + Converts the VectorStoreType to the PostgresVectorStoreType. + Args: + VectorStore (VectorStoreType): The Vector Store to convert. + Returns: + PostgresVectorStoreType: The converted Vector Store. + """ + def toPostgresVectorStoreTypeFrom(self, VectorStore: VectorStoreType) -> PostgresVectorStoreType: + return PostgresVectorStoreType[VectorStore.name] + + """ + Converts the EmbeddingModelType to the PostgresEmbeddingModelType. + Args: + EmbeddingModel (EmbeddingModelType): The Embedding Model to convert. + Returns: + PostgresEmbeddingModelType: The converted Embedding Model. + """ + def toPostgresEmbeddingModelTypeFrom(self, EmbeddingModel: EmbeddingModelType) -> PostgresEmbeddingModelType: + return PostgresEmbeddingModelType[EmbeddingModel.name] \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/DOCX_text_extractor.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/DOCX_text_extractor.py new file mode 100644 index 00000000..a0ea764d --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/DOCX_text_extractor.py @@ -0,0 +1,29 @@ +import os +from typing import List +import tempfile + +from domain.document.document_content import DocumentContent +from adapter.out.upload_documents.text_extractor import TextExtractor +from langchain_core.documents.base import Document as LangchainCoreDocuments +from langchain_community.document_loaders.word_document import Docx2txtLoader +from langchain.text_splitter import CharacterTextSplitter + +""" +This class is used to extract the text from the DOCX documents. +""" +class DOCXTextExtractor(TextExtractor): + + """ + Extracts the text from the document and returns the chunks. + Args: + documentContent (DocumentContent): The document to extract the text. + Returns: + List[LangchainCoreDocuments]: The chunks of the document. + """ + def extractText(self, documentContent:DocumentContent) -> List[LangchainCoreDocuments]: + with tempfile.NamedTemporaryFile(delete=False) as tempFile: + tempFile.write(documentContent.content) + docx = Docx2txtLoader(tempFile.name) + documents = docx.load() + textSplitter = CharacterTextSplitter(chunk_size = int(os.environ.get("CHUNK_SIZE")), chunk_overlap = int(os.environ.get("CHUNK_OVERLAP"))) + return textSplitter.split_documents(documents) diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/PDF_text_extractor.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/PDF_text_extractor.py new file mode 100644 index 00000000..80e4f779 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/PDF_text_extractor.py @@ -0,0 +1,30 @@ +import os +from typing import List +import tempfile + +from domain.document.document_content import DocumentContent +from adapter.out.upload_documents.text_extractor import TextExtractor +from langchain_core.documents.base import Document as LangchainCoreDocuments +from langchain_community.document_loaders import PyPDFLoader +from langchain.text_splitter import CharacterTextSplitter + +""" +This class is used to extract the text from the PDF documents. +""" +class PDFTextExtractor(TextExtractor): + + """ + Extracts the text from the document and returns the chunks. + Args: + documentContent (DocumentContent): The document to extract the text. + Returns: + List[LangchainCoreDocuments]: The chunks of the document. + """ + def extractText(self, documentContent:DocumentContent) -> List[LangchainCoreDocuments]: + with tempfile.NamedTemporaryFile(delete=False) as tempFile: + tempFile.write(documentContent.content) + pdf = PyPDFLoader(tempFile.name) + documents = pdf.load() + textSplitter = CharacterTextSplitter(chunk_size = int(os.environ.get("CHUNK_SIZE")), chunk_overlap = int(os.environ.get("CHUNK_OVERLAP"))) + return textSplitter.split_documents(documents) + diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/chunkerizer.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/chunkerizer.py new file mode 100644 index 00000000..bc4683b0 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/chunkerizer.py @@ -0,0 +1,51 @@ +from typing import List +from langchain_core.documents.base import Document as LangchainCoreDocuments +from domain.document.document import Document +from adapter.out.upload_documents.text_extractor import TextExtractor +from adapter.out.upload_documents.DOCX_text_extractor import DOCXTextExtractor +from adapter.out.upload_documents.PDF_text_extractor import PDFTextExtractor + + +""" +This class is used to extract the text from the documents. +""" + +class Chunkerizer: + def __init__(self): + pass + + + """ + Extracts the text from the document and returns the chunks. + Args: + document (Document): The document to extract the text. + Returns: + List[LangchainCoreDocuments]: The chunks of the document. + """ + def extractText(self, document : Document) -> List[LangchainCoreDocuments]: + textExtractor = Chunkerizer.getTextExtractorFrom(document.plainDocument.metadata.type.name) + if textExtractor is not None: + documentChunks = textExtractor.extractText(document.plainDocument.content) + for documentChunk in documentChunks: + documentChunk.metadata["source"] = document.plainDocument.metadata.id.id + documentChunk.metadata["status"] = document.documentStatus.status.name + return documentChunks + else: + return [] + + + """ + Gets the text extractor from the document type and returns it. + Args: + documentType (str): The document type. + Returns: + TextExtractor: The text extractor. + """ + @staticmethod + def getTextExtractorFrom(documentType: str) -> TextExtractor: + if documentType == "PDF": + return PDFTextExtractor() + elif documentType == "DOCX": + return DOCXTextExtractor() + else: + return None \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/documents_uploader_AWSS3.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/documents_uploader_AWSS3.py new file mode 100644 index 00000000..8d0dc778 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/documents_uploader_AWSS3.py @@ -0,0 +1,52 @@ +from typing import List + +from adapter.out.persistence.aws.AWS_document import AWSDocument +from adapter.out.persistence.aws.AWS_manager import AWSS3Manager +from application.port.out.documents_uploader_port import DocumentsUploaderPort +from domain.document.document import Document +from domain.document.document_operation_response import DocumentOperationResponse + +""" + A documents uploader that uploads documents to the AWS S3 bucket. +Attributes: + awss3manager (AWSS3Manager): The AWS S3 manager. +Methods: + uploadDocuments(self, documents:List[Document], forceUpload:bool) -> List[DocumentOperationResponse]: + Uploads a list of documents to the AWS S3 bucket. + toAWSDocumentFrom(self, document: Document) -> AWSDocument: + Converts a document to an AWS document. +""" +class DocumentsUploaderAWSS3(DocumentsUploaderPort): + def __init__(self, awss3manager: AWSS3Manager): + self.awss3manager = awss3manager + + """ + Uploads a list of documents to the AWS S3 bucket. + Args: + documents (List[Document]): The list of documents to upload. + forceUpload (bool): A flag indicating whether to force the upload of the documents, even if they already exist in the bucket. + Attributes: + awss3manager (AWSS3Manager): The AWS S3 manager. + Returns: + List[DocumentOperationResponse]: A list of document operation responses. + """ + def uploadDocuments(self, documents: List[Document], forceUpload: bool) -> List[DocumentOperationResponse]: + awsDocuments = [self.toAWSDocumentFrom(document) for document in documents] + awsDocumentOperationResponses = self.awss3manager.uploadDocuments(awsDocuments, forceUpload) + documentOperationResponses = [awsDocumentOperationResponse.toDocumentOperationResponse() for awsDocumentOperationResponse in awsDocumentOperationResponses] + return documentOperationResponses + + """ + Converts a document to an AWS document. + Args: + document (Document): The document to convert. + Returns: + AWSDocument: The AWS document. + """ + def toAWSDocumentFrom(self, document: Document) -> AWSDocument: + return AWSDocument( + id=document.plainDocument.metadata.id.id, + content=document.plainDocument.content.content, + size=document.plainDocument.metadata.size, + uploadTime=document.plainDocument.metadata.uploadTime + ) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/embeddings_creator.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/embeddings_creator.py new file mode 100644 index 00000000..a15cba4b --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/embeddings_creator.py @@ -0,0 +1,21 @@ +from typing import List +from langchain_core.documents.base import Document as LangchainCoreDocuments +from adapter.out.upload_documents.langchain_embedding_model import LangchainEmbeddingModel + + +""" +This class is used to create the embeddings of the documents. +""" +class EmbeddingsCreator: + def __init__(self, langchainEmbeddingModel: LangchainEmbeddingModel): + self.langchainEmbeddingModel = langchainEmbeddingModel + + """ + Embeds the document and returns the embeddings. + Args: + documents (List[LangchainCoreDocuments]): The documents to embed. + Returns: + List[List[float]]: The embeddings of the documents. + """ + def embedDocument(self, documents: List[LangchainCoreDocuments]) -> List[List[float]]: + return self.langchainEmbeddingModel.embedDocument([document.page_content for document in documents]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/embeddings_uploader_facade_langchain.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/embeddings_uploader_facade_langchain.py new file mode 100644 index 00000000..23416300 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/embeddings_uploader_facade_langchain.py @@ -0,0 +1,60 @@ +from typing import List + +from domain.document.document_id import DocumentId +from domain.document.document import Document +from domain.document.document_operation_response import DocumentOperationResponse +from application.port.out.embeddings_uploader_port import EmbeddingsUploaderPort +from adapter.out.persistence.vector_store.langchain_document import LangchainDocument +from adapter.out.upload_documents.chunkerizer import Chunkerizer +from adapter.out.upload_documents.embeddings_creator import EmbeddingsCreator +from adapter.out.upload_documents.embeddings_uploader_vector_store import EmbeddingsUploaderVectorStore + +""" +This class is the implementation of the EmbeddingsUploaderPort interface. It uses the Chunkerizer, EmbeddingsCreator and EmbeddingsUploaderVectorStore to upload the documents embeddings. + Attributes: + chunkerizer (Chunkerizer): The Chunkerizer to use to chunk the documents. + embeddingsCreator (EmbeddingsCreator): The EmbeddingsCreator to use to create the documents embeddings. + embeddingsUploaderVectorStore (EmbeddingsUploaderVectorStore): The EmbeddingsUploaderVectorStore to use to upload the documents embeddings. +""" +class EmbeddingsUploaderFacadeLangchain(EmbeddingsUploaderPort): + def __init__(self, chunkerizer: Chunkerizer, embeddingsCreator: EmbeddingsCreator, embeddingsUploaderVectorStore: EmbeddingsUploaderVectorStore): + self.chunkerizer = chunkerizer + self.embeddingsCreator = embeddingsCreator + self.embeddingsUploaderVectorStore = embeddingsUploaderVectorStore + + + """ + Uploads the documents embeddings and returns the response. + Args: + documents (List[Document]): The documents to upload the embeddings. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def uploadEmbeddings(self, documents: List[Document]) -> List[DocumentOperationResponse]: + documentsChunks = [] + for document in documents: + documentChunks = self.chunkerizer.extractText(document) + documentsChunks.append(documentChunks) + + documentsEmbeddings = [] + for documentChunks in documentsChunks: + documentEmbeddings = self.embeddingsCreator.embedDocument(documentChunks) + documentsEmbeddings.append(documentEmbeddings) + + vectorStoreDocumentOperationResponses = self.embeddingsUploaderVectorStore.uploadEmbeddings( + [ + LangchainDocument( + documentId=document.plainDocument.metadata.id.id, + chunks=documentChunks, + embeddings=documentEmbeddings + ) for document, documentChunks, documentEmbeddings in zip(documents, documentsChunks, documentsEmbeddings) + ] + ) + + return [ + DocumentOperationResponse( + DocumentId(vectorStoreDocumentOperationResponse.documentId), + vectorStoreDocumentOperationResponse.ok(), + vectorStoreDocumentOperationResponse.message + ) for vectorStoreDocumentOperationResponse in vectorStoreDocumentOperationResponses + ] \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/embeddings_uploader_vector_store.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/embeddings_uploader_vector_store.py new file mode 100644 index 00000000..a578e846 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/embeddings_uploader_vector_store.py @@ -0,0 +1,26 @@ +from typing import List +from adapter.out.persistence.vector_store.vector_store_manager import VectorStoreManager +from adapter.out.persistence.vector_store.vector_store_document_operation_response import VectorStoreDocumentOperationResponse +from adapter.out.persistence.vector_store.langchain_document import LangchainDocument + +""" +This class is the implementation of the EmbeddingsUploaderPort interface. It uses the VectorStoreManager to upload the documents embeddings. + Attributes: + vectorStoreManager (VectorStoreManager): The VectorStoreManager to use to upload the documents embeddings. +""" +class EmbeddingsUploaderVectorStore: + def __init__(self, vectorStoreManager: VectorStoreManager): + self.vectorStoreManager = vectorStoreManager + + + """ + Uploads the documents embeddings and returns the response. + Args: + documents (List[LangchainDocument]): The documents to upload the embeddings. + Returns: + List[VectorStoreDocumentOperationResponse]: The response of the operation. + """ + def uploadEmbeddings(self, documents: List[LangchainDocument]) -> List[VectorStoreDocumentOperationResponse]: + documentsId, documentsChunks, documentsEmbeddings = zip(*[(document.documentId, document.chunks, document.embeddings) for document in documents]) + return self.vectorStoreManager.uploadEmbeddings(documentsId, documentsChunks, documentsEmbeddings) + \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/huggingface_embedding_model.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/huggingface_embedding_model.py new file mode 100644 index 00000000..255d73ac --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/huggingface_embedding_model.py @@ -0,0 +1,37 @@ +from typing import List + +from langchain_community.embeddings import HuggingFaceInferenceAPIEmbeddings +from adapter.out.upload_documents.langchain_embedding_model import LangchainEmbeddingModel + +""" +This class is used to create the embeddings of the documents using the HuggingFace model. +""" +class HuggingFaceEmbeddingModel(LangchainEmbeddingModel): + def __init__(self): + with open('/run/secrets/huggingface_key', 'r') as file: + huggingFaceKey = file.read() + + self.model = HuggingFaceInferenceAPIEmbeddings(api_key=huggingFaceKey, model_name="sentence-transformers/all-mpnet-base-v2") + self.embeddingsDimension = 768 + + """ + Embeds the document and returns the embeddings. + Args: + documentChunks (List[str]): The document chunks to embed. + Returns: + List[List[float]]: The embeddings of the document. + """ + def embedDocument(self, documentChunks: List[str]) -> List[List[float]]: + try: + return self.model.embed_documents(documentChunks) + except Exception as e: + return [] + + + """ + Gets the embeddings dimension and returns it. + Returns: + int: The embeddings dimension. + """ + def getEmbeddingFunction(self): + return self.model \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/langchain_embedding_model.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/langchain_embedding_model.py new file mode 100644 index 00000000..76b0fcb4 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/langchain_embedding_model.py @@ -0,0 +1,25 @@ +from typing import List + +""" +This class is the interface of the LangchainEmbeddingModel. +""" +class LangchainEmbeddingModel: + + """ + Embeds the document and returns the embeddings. + Args: + documentChunks (List[str]): The document chunks to embed. + Returns: + List[List[float]]: The embeddings of the document. + """ + def embedDocument(self, documentChunks: List[str]) -> List[List[float]]: + pass + + + """ + Gets the embeddings dimension and returns it. + Returns: + int: The embeddings dimension. + """ + def getEmbeddingFunction(self): + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/openai_embedding_model.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/openai_embedding_model.py new file mode 100644 index 00000000..598749f4 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/openai_embedding_model.py @@ -0,0 +1,37 @@ +from typing import List + +from langchain_openai import OpenAIEmbeddings +from adapter.out.upload_documents.langchain_embedding_model import LangchainEmbeddingModel + +""" +This class is used to create the embeddings of the documents using the OpenAI model. +""" +class OpenAIEmbeddingModel(LangchainEmbeddingModel): + def __init__(self): + with open('/run/secrets/openai_key', 'r') as file: + openaikey = file.read() + + self.model = OpenAIEmbeddings(model="text-embedding-3-small", openai_api_key=openaikey) + self.embeddingsDimension = 1536 + + + """ + Embeds the document and returns the embeddings. + Args: + documentChunks (List[str]): The document chunks to embed. + Returns: + List[List[float]]: The embeddings of the document. + """ + def embedDocument(self, documentChunks: List[str]) -> List[List[float]]: + try: + return self.model.embed_documents(documentChunks) + except Exception as e: + return [] + + """ + Gets the embeddings dimension and returns it. + Returns: + int: The embeddings dimension. + """ + def getEmbeddingFunction(self): + return self.model \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/adapter/out/upload_documents/text_extractor.py b/3 - PB/MVP/src/backend/adapter/out/upload_documents/text_extractor.py new file mode 100644 index 00000000..5e729c82 --- /dev/null +++ b/3 - PB/MVP/src/backend/adapter/out/upload_documents/text_extractor.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document_content import DocumentContent +from langchain_core.documents.base import Document as LangchainCoreDocuments + +""" +This class is used to extract the text from the documents. +""" +class TextExtractor: + + """ + Extracts the text from the document and returns the chunks. + Args: + documentContent (DocumentContent): The document to extract the text. + Returns: + List[LangchainCoreDocuments]: The chunks of the document. + """ + def extractText(self, documentContent: DocumentContent) -> List[LangchainCoreDocuments]: + pass diff --git a/3 - PB/MVP/src/backend/api_exceptions.py b/3 - PB/MVP/src/backend/api_exceptions.py new file mode 100644 index 00000000..6f2b7af8 --- /dev/null +++ b/3 - PB/MVP/src/backend/api_exceptions.py @@ -0,0 +1,36 @@ +""" +Modulo contenente le eccezioni personalizzate per l'API. +""" +class APIBadRequest(Exception): + def __init__(self, message, status_code=None): + self.message = message + if status_code is None: + self.status_code = 400 + else: + self.status_code = status_code +""" +Eccezione per documento non supportato. +""" +class DocumentNotSupported(APIBadRequest): + def __init__(self, message="Documento non supportato."): + super().__init__(message, status_code=422) + +""" +Eccezione per parametri insufficienti. +""" +class InsufficientParameters(APIBadRequest): + def __init__(self, message="Parametri insufficienti o errati."): + super().__init__(message, status_code=400) + +""" +Eccezione per elaborazione API. +""" +class APIElaborationException(Exception): + def __init__(self, message): + self.message = message + self.status_code = 500 + +class ConfigurationNotSetException(Exception): + def __init__(self, message="Configurazione non impostata."): + self.message = message + self.status_code = 401 \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/app.py b/3 - PB/MVP/src/backend/app.py new file mode 100644 index 00000000..8e9c5224 --- /dev/null +++ b/3 - PB/MVP/src/backend/app.py @@ -0,0 +1,69 @@ +from flask import Flask, jsonify, redirect, url_for, request +from flask_cors import CORS + +from api_exceptions import APIBadRequest +from api_exceptions import APIElaborationException, ConfigurationNotSetException +from blueprints.get_chat_messages import getChatMessagesBlueprint +from blueprints.get_chats import getChatsBlueprint + +from blueprints.get_document_content import getDocumentContentBlueprint +from blueprints.upload_documents import uploadDocumentsBlueprint +from blueprints.delete_documents import deleteDocumentsBlueprint +from adapter.out.persistence.postgres.database import init_db, db_session +from blueprints.set_configuration import setConfigurationBlueprint +from blueprints.change_configuration import changeConfigurationBlueprint +from blueprints.conceal_documents import concealDocumentsBlueprint +from blueprints.embed_documents import embedDocumentsBlueprint +from blueprints.enable_documents import enableDocumentsBlueprint +from blueprints.get_configuration import getConfigurationBlueprint, getConfiguration +from blueprints.get_documents import getDocumentsBlueprint +from blueprints.get_configuration_options import getConfigurationOptionsBlueprint +from blueprints.ask_chatbot import askChatbotBlueprint +from blueprints.delete_chats import deleteChatsBlueprint +from blueprints.rename_chat import renameChatBlueprint + +app = Flask(__name__) +CORS(app) + +init_db() + +@app.teardown_appcontext +def shutdown_session(exception=None): + db_session.remove() + +app.register_blueprint(uploadDocumentsBlueprint) +app.register_blueprint(deleteDocumentsBlueprint) +app.register_blueprint(getDocumentsBlueprint) +app.register_blueprint(concealDocumentsBlueprint) +app.register_blueprint(enableDocumentsBlueprint) +app.register_blueprint(embedDocumentsBlueprint) +app.register_blueprint(getDocumentContentBlueprint) +app.register_blueprint(getConfigurationBlueprint) +app.register_blueprint(changeConfigurationBlueprint) +app.register_blueprint(setConfigurationBlueprint) +app.register_blueprint(getConfigurationOptionsBlueprint) +app.register_blueprint(askChatbotBlueprint) +app.register_blueprint(getChatsBlueprint) +app.register_blueprint(getChatMessagesBlueprint) +app.register_blueprint(deleteChatsBlueprint) +app.register_blueprint(renameChatBlueprint) + + +@app.errorhandler(APIBadRequest) +def handle_api_error(error): + return jsonify(error.message), error.status_code + +@app.errorhandler(APIElaborationException) +def handle_api_elaboration_error(error): + return jsonify(error.message), error.status_code + +@app.before_request +def check_configuration(): + excluded_endpoints = ['getConfiguration', 'setConfiguration', 'getConfigurationOptions'] + if request.endpoint is not None and request.endpoint.split('.')[1] not in excluded_endpoints: + config_response = getConfiguration() + + if config_response.status_code == 401: + return jsonify("Configurazione inesistente."), 401 + elif config_response.status_code == 500: + raise APIElaborationException("Errore nel recupero della configurazione.") \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/ask_chatbot_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/ask_chatbot_use_case.py new file mode 100644 index 00000000..d95934e8 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/ask_chatbot_use_case.py @@ -0,0 +1,20 @@ +from domain.chat.message import Message +from domain.chat.chat_id import ChatId +from domain.chat.message_response import MessageResponse + +""" +This class is the interface of the AskChatbotUseCase. +""" +class AskChatbotUseCase: + + """ + Asks the chatbot the message and returns the response. + Args: + message (Message): The message to ask the chatbot. + chatId (ChatId): The chat id. + Returns: + MessageResponse: The response of the chatbot. + + """ + def askChatbot(self, message: Message, chatId: ChatId) -> MessageResponse: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/change_configuration_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/change_configuration_use_case.py new file mode 100644 index 00000000..fcbf7741 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/change_configuration_use_case.py @@ -0,0 +1,17 @@ +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +from domain.configuration.llm_model_configuration import LLMModelType + +""" +This class is the interface of the ChangeConfigurationUseCase. +""" +class ChangeConfigurationUseCase: + + """ + Changes the LLM model and returns the response. + Args: + LLModel (LLMModelType): The LLM model to change. + Returns: + ConfigurationOperationResponse: The response of the operation. + """ + def changeLLMModel(self, LLModel: LLMModelType) -> ConfigurationOperationResponse: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/conceal_documents_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/conceal_documents_use_case.py new file mode 100644 index 00000000..eb56364b --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/conceal_documents_use_case.py @@ -0,0 +1,17 @@ +from typing import List +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse +""" +This interface is the output port of the ConcealDocumentsUseCase. It is used to conceal the documents. +""" +class ConcealDocumentsUseCase: + + """ + Conceals the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to conceal. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def concealDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/delete_chats_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/delete_chats_use_case.py new file mode 100644 index 00000000..6e9060a1 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/delete_chats_use_case.py @@ -0,0 +1,18 @@ +from typing import List +from domain.chat.chat_operation_response import ChatOperationResponse +from domain.chat.chat_id import ChatId + +""" +This class is the interface of the DeleteChatsUseCase. +""" +class DeleteChatsUseCase: + + """ + Deletes the chats and returns the response. + Args: + chatsIdsList (List[ChatId]): The chats to delete. + Returns: + List[ChatOperationResponse]: The response of the operation. + """ + def deleteChats(self, chatsIdsList: List[ChatId]) -> List[ChatOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/delete_documents_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/delete_documents_use_case.py new file mode 100644 index 00000000..b6b13a2c --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/delete_documents_use_case.py @@ -0,0 +1,18 @@ +from typing import List +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This interface is the output port of the DeleteDocumentsUseCase. It is used to delete the documents. +""" +class DeleteDocumentsUseCase: + + """ + Deletes the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to delete. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def deleteDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/embed_documents_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/embed_documents_use_case.py new file mode 100644 index 00000000..9a94e06e --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/embed_documents_use_case.py @@ -0,0 +1,19 @@ +from typing import List +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This interface is the output port of the EmbedDocumentsUseCase. It is used to embed the documents. +""" + +class EmbedDocumentsUseCase: + + """ + Embeds the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to embed. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def embedDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/enable_documents_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/enable_documents_use_case.py new file mode 100644 index 00000000..567e0cc3 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/enable_documents_use_case.py @@ -0,0 +1,19 @@ +from typing import List +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + + +""" +This interface is the output port of the EnableDocumentsUseCase. It is used to enable the documents. +""" +class EnableDocumentsUseCase: + + """ + Enables the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to enable. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def enableDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/get_chat_messages_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/get_chat_messages_use_case.py new file mode 100644 index 00000000..28674a73 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/get_chat_messages_use_case.py @@ -0,0 +1,17 @@ +from domain.chat.chat import Chat +from domain.chat.chat_id import ChatId + +""" +This class is the interface of the GetChatMessagesUseCase. +""" +class GetChatMessagesUseCase: + + """ + Gets the chat messages and returns the chat. + Args: + chatId (ChatId): The chat id. + Returns: + Chat: The chat. + """ + def getChatMessages(self, chatId: ChatId)->Chat: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/get_chats_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/get_chats_use_case.py new file mode 100644 index 00000000..5ce30c0c --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/get_chats_use_case.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.chat.chat_filter import ChatFilter +from domain.chat.chat_preview import ChatPreview + +""" +This interface is the input port of the GetChatsUseCase. It is used to get the chats. +""" +class GetChatsUseCase: + + """ + Gets the chats and returns the chat previews. + Args: + chatFilter (ChatFilter): The chat filter. + Returns: + List[ChatPreview]: The chat previews. + """ + def getChats(self, chatFilter: ChatFilter) -> List[ChatPreview]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/get_configuration_options_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/get_configuration_options_use_case.py new file mode 100644 index 00000000..250f6b5d --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/get_configuration_options_use_case.py @@ -0,0 +1,13 @@ +from domain.configuration.configuration_options import ConfigurationOptions +""" +This class is the interface of the GetConfigurationOptionsUseCase. +""" +class GetConfigurationOptionsUseCase: + + """ + Gets the configuration options and returns them. + Returns: + ConfigurationOptions: The configuration options. + """ + def getConfigurationOptions(self) -> ConfigurationOptions: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/get_configuration_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/get_configuration_use_case.py new file mode 100644 index 00000000..c72fba35 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/get_configuration_use_case.py @@ -0,0 +1,14 @@ +from domain.configuration.configuration import Configuration + +""" +This class is the interface of the GetConfigurationUseCase. +""" +class GetConfigurationUseCase: + + """ + Gets the configuration and returns it. + Returns: + Configuration: The configuration. + """ + def getConfiguration(self) -> Configuration: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/get_documents_content_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/get_documents_content_use_case.py new file mode 100644 index 00000000..04f5dbf8 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/get_documents_content_use_case.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document import Document +from domain.document.document_id import DocumentId + +""" +This interface is the input port of the GetDocumentsContentUseCase. It is used to get the content of the documents. +""" +class GetDocumentsContentUseCase: + + """ + Gets the content of the documents and returns the documents. + Args: + documentIds (List[DocumentId]): The documents to get the content. + Returns: + List[Document]: The documents with the content. + """ + def getDocumentsContent(self, documentIds: List[DocumentId]) -> List[Document]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/get_documents_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/get_documents_use_case.py new file mode 100644 index 00000000..62f469d0 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/get_documents_use_case.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document_filter import DocumentFilter +from domain.document.light_document import LightDocument + +""" +This interface is the input port of the GetDocumentsUseCase. It is used to get the documents. +""" +class GetDocumentsUseCase: + + """ + Gets the documents and returns the light documents. + Args: + documentFilter (DocumentFilter): The document filter. + Returns: + List[LightDocument]: The light documents. + """ + def getDocuments(self, documentFilter: DocumentFilter) -> List[LightDocument]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/rename_chat_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/rename_chat_use_case.py new file mode 100644 index 00000000..77a0e12d --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/rename_chat_use_case.py @@ -0,0 +1,18 @@ +from domain.chat.chat_id import ChatId +from domain.chat.chat_operation_response import ChatOperationResponse + +""" +This interface is the input port of the RenameChatUseCase. It is used to rename the chat. +""" +class RenameChatUseCase: + + """ + Renames the chat and returns the response. + Args: + chatId (ChatId): The chat to rename. + titel (str): The new titel of the chat. + Returns: + ChatOperationResponse: The response of the operation. + """ + def renameChat(self, chatId: ChatId, titel: str) -> ChatOperationResponse: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/set_configuration_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/set_configuration_use_case.py new file mode 100644 index 00000000..c56fb7ba --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/set_configuration_use_case.py @@ -0,0 +1,23 @@ +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +from domain.configuration.llm_model_configuration import LLMModelType +from domain.configuration.document_store_configuration import DocumentStoreType +from domain.configuration.vector_store_configuration import VectorStoreType +from domain.configuration.embedding_model_configuration import EmbeddingModelType + +""" +This class is the interface of the SetConfigurationUseCase. +""" +class SetConfigurationUseCase: + + """ + Set the configuration and returns the response. + Args: + LLModel (LLMModelType): The LLM model to set; + DocumentStore (DocumentStoreType): The Document Store to set; + VectorStore (VectorStoreType): The Vector Store to set; + EmbeddingModel (EmbeddingModelType): The Embedding Model to set. + Returns: + ConfigurationOperationResponse: The response of the operation. + """ + def setConfiguration(self, LLModel: LLMModelType, DocumentStore: DocumentStoreType, VectorStore: VectorStoreType, EmbeddingModel: EmbeddingModelType) -> ConfigurationOperationResponse: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/_in/upload_documents_use_case.py b/3 - PB/MVP/src/backend/application/port/_in/upload_documents_use_case.py new file mode 100644 index 00000000..152f9cfc --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/_in/upload_documents_use_case.py @@ -0,0 +1,27 @@ +from typing import List + +from domain.document.document import Document +from domain.document.document_operation_response import DocumentOperationResponse + +""" + This interface is responsible for uploading documents to the AWS S3 bucket. + This will be implemented by the UploadDocumentsService class. + Attributes: + documents (List[Document]): The list of documents to be uploaded. + forceUpload (bool): A flag to force the upload of the documents. + Methods: + uploadDocuments() -> List[DocumentOperationResponse]: + Upload the documents to the AWS S3 bucket. +""" +class UploadDocumentsUseCase: + + """ + Uploads the documents and returns the response. + Args: + documents (List[Document]): The documents to upload. + forceUpload (bool): A flag to force the upload of the documents. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def uploadDocuments(self, documents: List[Document], forceUpload: bool) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/ask_chatbot_port.py b/3 - PB/MVP/src/backend/application/port/out/ask_chatbot_port.py new file mode 100644 index 00000000..9842ad96 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/ask_chatbot_port.py @@ -0,0 +1,19 @@ +from domain.chat.message_response import MessageResponse +from domain.chat.message import Message +from domain.chat.chat_id import ChatId + +""" +This interface is the output port of the AskChatbotUseCase. It is used to ask the chatbot. +""" +class AskChatbotPort: + + """ + Asks the chatbot and returns the response. + Args: + message (Message): The message to ask the chatbot. + chatId (ChatId): The chat id. + Returns: + MessageResponse: The response of the chatbot. + """ + def askChatbot(self, message: Message, chatId: ChatId) -> MessageResponse: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/change_configuration_port.py b/3 - PB/MVP/src/backend/application/port/out/change_configuration_port.py new file mode 100644 index 00000000..85e92746 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/change_configuration_port.py @@ -0,0 +1,17 @@ +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +from domain.configuration.llm_model_configuration import LLMModelType + +""" +This interface is the output port of the ChangeConfigurationUseCase. It is used to change the configuration. +""" +class ChangeConfigurationPort: + + """ + Changes the LLM model and returns the response. + Args: + LLModel (LLMModelType): The LLM model to change. + Returns: + ConfigurationOperationResponse: The response of the operation. + """ + def changeLLMModel(self, LLModel: LLMModelType) -> ConfigurationOperationResponse: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/conceal_documents_port.py b/3 - PB/MVP/src/backend/application/port/out/conceal_documents_port.py new file mode 100644 index 00000000..ea14c925 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/conceal_documents_port.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This interface is the output port of the ConcealDocumentsUseCase. It is used to conceal the documents. +""" +class ConcealDocumentsPort: + + """ + Conceals the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to conceal. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def concealDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/delete_chats_port.py b/3 - PB/MVP/src/backend/application/port/out/delete_chats_port.py new file mode 100644 index 00000000..a1938902 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/delete_chats_port.py @@ -0,0 +1,18 @@ +from typing import List +from domain.chat.chat_operation_response import ChatOperationResponse +from domain.chat.chat_id import ChatId + +""" +This interface is the output port of the DeleteChatsUseCase. It is used to delete the chats. +""" +class DeleteChatsPort: + + """ + Deletes the chats and returns the response. + Args: + chatsIdsList (List[ChatId]): The chats to delete. + Returns: + List[ChatOperationResponse]: The response of the operation. + """ + def deleteChats(self, chatsIdsList: List[ChatId]) -> List[ChatOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/delete_documents_port.py b/3 - PB/MVP/src/backend/application/port/out/delete_documents_port.py new file mode 100644 index 00000000..180f57bb --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/delete_documents_port.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This interface is the output port of the DeleteDocumentsUseCase. It is used to delete the documents. +""" +class DeleteDocumentsPort: + + """ + Deletes the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to delete. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def deleteDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/delete_embeddings_port.py b/3 - PB/MVP/src/backend/application/port/out/delete_embeddings_port.py new file mode 100644 index 00000000..03cf143a --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/delete_embeddings_port.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This interface is the output port of the DeleteEmbeddingsUseCase. It is used to delete the embeddings. +""" +class DeleteEmbeddingsPort: + + """ + Deletes the embeddings of the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to delete the embeddings. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def deleteDocumentsEmbeddings(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/documents_uploader_port.py b/3 - PB/MVP/src/backend/application/port/out/documents_uploader_port.py new file mode 100644 index 00000000..74118935 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/documents_uploader_port.py @@ -0,0 +1,20 @@ +from typing import List + +from domain.document.document import Document +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This interface is the output port of the DocumentsUploaderUseCase. It is used to upload the documents. +""" +class DocumentsUploaderPort: + + """ + Uploads the documents and returns the response. + Args: + documents (List[Document]): The documents to upload. + forceUpload (bool): If the upload should be forced. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def uploadDocuments(self, documents: List[Document], forceUpload: bool) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/embeddings_uploader_port.py b/3 - PB/MVP/src/backend/application/port/out/embeddings_uploader_port.py new file mode 100644 index 00000000..58ddde00 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/embeddings_uploader_port.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document import Document +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This interface is the output port of the EmbeddingsUploaderUseCase. It is used to upload the embeddings. +""" +class EmbeddingsUploaderPort: + + """ + Uploads the embeddings and returns the response. + Args: + documents (List[Document]): The documents to upload the embeddings. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def uploadEmbeddings(self, documents: List[Document]) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/enable_documents_port.py b/3 - PB/MVP/src/backend/application/port/out/enable_documents_port.py new file mode 100644 index 00000000..615ba8ac --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/enable_documents_port.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This interface is the output port of the EnableDocumentsUseCase. It is used to enable the documents. +""" +class EnableDocumentsPort: + + """ + Enables the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to enable. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def enableDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/get_chat_messages_port.py b/3 - PB/MVP/src/backend/application/port/out/get_chat_messages_port.py new file mode 100644 index 00000000..51c9feef --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/get_chat_messages_port.py @@ -0,0 +1,17 @@ +from domain.chat.chat import Chat +from domain.chat.chat_id import ChatId + +""" +This interface is the output port of the GetChatMessagesUseCase. It is used to get the chat messages. +""" +class GetChatMessagesPort: + + """ + Gets the chat messages and returns the chat. + Args: + chatId (ChatId): The chat id. + Returns: + Chat: The chat. + """ + def getChatMessages(self, chatId: ChatId)->Chat: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/get_chats_port.py b/3 - PB/MVP/src/backend/application/port/out/get_chats_port.py new file mode 100644 index 00000000..9377de11 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/get_chats_port.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.chat.chat_filter import ChatFilter +from domain.chat.chat_preview import ChatPreview + +""" +This interface is the output port of the GetChatsUseCase. It is used to get the chats. +""" +class GetChatsPort: + + """ + Gets the chats and returns the chat previews. + Args: + chatFilter (ChatFilter): The chat filter. + Returns: + List[ChatPreview]: The chat previews. + """ + def getChats(self, chatFilter: ChatFilter) -> List[ChatPreview]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/get_configuration_options_port.py b/3 - PB/MVP/src/backend/application/port/out/get_configuration_options_port.py new file mode 100644 index 00000000..cb40529d --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/get_configuration_options_port.py @@ -0,0 +1,13 @@ +from domain.configuration.configuration_options import ConfigurationOptions +""" +This interface is the output port of the GetConfigurationOptionsUseCase. It is used to get the configuration options. +""" +class GetConfigurationOptionsPort: + + """ + Gets the configuration options and returns them. + Returns: + ConfigurationOptions: The configuration options. + """ + def getConfigurationOptions(self) -> ConfigurationOptions: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/get_configuration_port.py b/3 - PB/MVP/src/backend/application/port/out/get_configuration_port.py new file mode 100644 index 00000000..27f856bd --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/get_configuration_port.py @@ -0,0 +1,13 @@ +from domain.configuration.configuration import Configuration +""" +This interface is the output port of the GetConfigurationUseCase. It is used to get the configuration. +""" +class GetConfigurationPort: + + """ + Gets the configuration and returns it. + Returns: + Configuration: The configuration. + """ + def getConfiguration(self) -> Configuration: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/get_documents_content_port.py b/3 - PB/MVP/src/backend/application/port/out/get_documents_content_port.py new file mode 100644 index 00000000..7570e084 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/get_documents_content_port.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document_id import DocumentId +from domain.document.plain_document import PlainDocument + +""" +This interface is the output port of the GetDocumentsContentUseCase. It is used to get the documents content. +""" +class GetDocumentsContentPort: + + """ + Gets the documents content and returns the plain documents. + Args: + documentIds (List[DocumentId]): The document ids. + Returns: + List[PlainDocument]: The plain documents. + """ + def getDocumentsContent(self, documentIds: List[DocumentId]) -> List[PlainDocument]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/get_documents_metadata_port.py b/3 - PB/MVP/src/backend/application/port/out/get_documents_metadata_port.py new file mode 100644 index 00000000..78d06672 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/get_documents_metadata_port.py @@ -0,0 +1,19 @@ +from typing import List + +from domain.document.document_filter import DocumentFilter +from domain.document.document_metadata import DocumentMetadata + +""" +This interface is the output port of the GetDocumentsMetadataUseCase. It is used to get the documents metadata. +""" +class GetDocumentsMetadataPort: + + """ + Gets the documents metadata and returns the document metadata. + Args: + documentFilter (DocumentFilter): The document filter. + Returns: + List[DocumentMetadata]: The document metadata. + """ + def getDocumentsMetadata(self, documentFilter: DocumentFilter) -> List[DocumentMetadata]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/get_documents_status_port.py b/3 - PB/MVP/src/backend/application/port/out/get_documents_status_port.py new file mode 100644 index 00000000..8f98e927 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/get_documents_status_port.py @@ -0,0 +1,19 @@ +from typing import List, Dict + +from domain.document.document_id import DocumentId +from domain.document.document_status import DocumentStatus + +""" +This interface is the output port of the GetDocumentsStatusUseCase. It is used to get the documents status. +""" +class GetDocumentsStatusPort: + + """ + Gets the documents status and returns the document status. + Args: + documentsId (List[DocumentId]): The document ids. + Returns: + List[DocumentStatus]: The document status. + """ + def getDocumentsStatus(self, documentsId: List[DocumentId])-> List[DocumentStatus]: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/persist_chat_port.py b/3 - PB/MVP/src/backend/application/port/out/persist_chat_port.py new file mode 100644 index 00000000..df1877d0 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/persist_chat_port.py @@ -0,0 +1,21 @@ +from typing import List + +from domain.chat.message import Message +from domain.chat.chat_id import ChatId +from domain.chat.chat_operation_response import ChatOperationResponse + +""" +This interface is the output port of the PersistChatUseCase. It is used to persist the chat. +""" +class PersistChatPort: + + """ + Persists the chat and returns the response. + Args: + messages (List[Message]): The messages to persist. + chatId (ChatId): The chat id. + Returns: + ChatOperationResponse: The response of the operation. + """ + def persistChat(self, messages: List[Message], chatId: ChatId) -> ChatOperationResponse: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/rename_chat_port.py b/3 - PB/MVP/src/backend/application/port/out/rename_chat_port.py new file mode 100644 index 00000000..e36cb1c0 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/rename_chat_port.py @@ -0,0 +1,18 @@ +from domain.chat.chat_id import ChatId +from domain.chat.chat_operation_response import ChatOperationResponse + +""" +This interface is the output port of the RenameChatUseCase. It is used to rename the chat. +""" +class RenameChatPort: + + """ + Renames the chat and returns the response. + Args: + chatId (ChatId): The chat id. + title (str): The new title. + Returns: + ChatOperationResponse: The response of the operation. + """ + def renameChat(self, chatId: ChatId, title: str) -> ChatOperationResponse: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/port/out/set_configuration_port.py b/3 - PB/MVP/src/backend/application/port/out/set_configuration_port.py new file mode 100644 index 00000000..d67ba6e0 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/port/out/set_configuration_port.py @@ -0,0 +1,23 @@ +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +from domain.configuration.llm_model_configuration import LLMModelType +from domain.configuration.document_store_configuration import DocumentStoreType +from domain.configuration.vector_store_configuration import VectorStoreType +from domain.configuration.embedding_model_configuration import EmbeddingModelType + +""" +This interface is the output port of the SetConfigurationUseCase. It is used to set the configuration. +""" +class SetConfigurationPort: + + """ + Set the configuration and returns the response. + Args: + LLModel (LLMModelType): The LLM model to set; + DocumentStore (DocumentStoreType): The Document Store to set; + VectorStore (VectorStoreType): The Vector Store to set; + EmbeddingModel (EmbeddingModelType): The Embedding Model to set. + Returns: + ConfigurationOperationResponse: The response of the operation. + """ + def setConfiguration(self, LLModel: LLMModelType, DocumentStore:DocumentStoreType, VectorStore:VectorStoreType, EmbeddingModel:EmbeddingModelType) -> ConfigurationOperationResponse: + pass \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/ask_chatbot_service.py b/3 - PB/MVP/src/backend/application/service/ask_chatbot_service.py new file mode 100644 index 00000000..e354e103 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/ask_chatbot_service.py @@ -0,0 +1,41 @@ +from application.port._in.ask_chatbot_use_case import AskChatbotUseCase +from domain.chat.message import Message +from domain.chat.message_response import MessageResponse +from domain.chat.chat_id import ChatId + +from application.port.out.ask_chatbot_port import AskChatbotPort +from application.port.out.persist_chat_port import PersistChatPort + +""" +This class is the implementation of the AskChatbotUseCase interface. It uses the AskChatbotOutPort and the PersistChatOutPort to ask the chatbot and persist the chat. + Attributes: + askChatbotOutPort (AskChatbotPort): The AskChatbotOutPort to use to ask the chatbot. + persistChatOutPort (PersistChatPort): The PersistChatOutPort to use to persist the chat. +""" +class AskChatbotService(AskChatbotUseCase): + def __init__(self, askChatbotOutPort: AskChatbotPort, persistChatOutPort: PersistChatPort): + self.askChatbotOutPort = askChatbotOutPort + self.persistChatOutPort = persistChatOutPort + + + """ + Asks the chatbot and persists the chat. + Args: + message (Message): The message to ask the chatbot. + chatId (ChatId): The chat id. + Returns: + MessageResponse: The response of the operation. + """ + def askChatbot(self, message: Message, chatId: ChatId) -> MessageResponse: + messageResponse = self.askChatbotOutPort.askChatbot(message, chatId) + + if messageResponse and messageResponse.ok(): + chatOperationResponse = self.persistChatOutPort.persistChat([message, messageResponse.messageResponse], chatId) + + return MessageResponse( + status=chatOperationResponse.ok(), + messageResponse=messageResponse.messageResponse if chatOperationResponse.ok() else None, + chatId=chatOperationResponse.chatId + ) + + return messageResponse \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/change_configuration_service.py b/3 - PB/MVP/src/backend/application/service/change_configuration_service.py new file mode 100644 index 00000000..91c0fb4c --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/change_configuration_service.py @@ -0,0 +1,23 @@ +from application.port._in.change_configuration_use_case import ChangeConfigurationUseCase +from domain.configuration.llm_model_configuration import LLMModelType +from application.port.out.change_configuration_port import ChangeConfigurationPort +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +""" +This class is the implementation of the ChangeConfigurationUseCase interface. It uses the ChangeConfigurationPort to change the configuration. + Attributes: + outport (ChangeConfigurationPort): The ChangeConfigurationPort to use to change the configuration. +""" +class ChangeConfigurationService(ChangeConfigurationUseCase): + def __init__(self, changeConfigurationPort: ChangeConfigurationPort): + self.outport = changeConfigurationPort + + + """ + Changes the LLM model and returns the response. + Args: + LLModel (LLMModelType): The LLM model to change. + Returns: + ConfigurationOperationResponse: The response of the operation. + """ + def changeLLMModel(self, LLModel:LLMModelType ) -> ConfigurationOperationResponse: + return self.outport.changeLLMModel(LLModel) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/conceal_documents_service.py b/3 - PB/MVP/src/backend/application/service/conceal_documents_service.py new file mode 100644 index 00000000..71f46936 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/conceal_documents_service.py @@ -0,0 +1,26 @@ +from application.port._in.conceal_documents_use_case import ConcealDocumentsUseCase +from domain.document.document_id import DocumentId +from typing import List +from domain.document.document_operation_response import DocumentOperationResponse +from application.port.out.conceal_documents_port import ConcealDocumentsPort + +""" +This class is the implementation of the ConcealDocumentsUseCase interface. + Attributes: + outPort (ConcealDocumentsPort): The port to use to conceal the documents. +""" +class ConcealDocumentsService(ConcealDocumentsUseCase): + def __init__(self, concealDocumentsPort: ConcealDocumentsPort): + self.outPort = concealDocumentsPort + + + """ + Conceals the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to conceal. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def concealDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + return self.outPort.concealDocuments(documentsIds) + diff --git a/3 - PB/MVP/src/backend/application/service/delete_chats_service.py b/3 - PB/MVP/src/backend/application/service/delete_chats_service.py new file mode 100644 index 00000000..c6c31bd1 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/delete_chats_service.py @@ -0,0 +1,25 @@ +from typing import List +from domain.chat.chat_operation_response import ChatOperationResponse +from domain.chat.chat_id import ChatId +from application.port._in.delete_chats_use_case import DeleteChatsUseCase +from application.port.out.delete_chats_port import DeleteChatsPort + +""" +This class is the implementation of the DeleteChatsUseCase interface. + Attributes: + outPort (DeleteChatsPort): The port to use to delete the chats. +""" +class DeleteChatsService(DeleteChatsUseCase): + def __init__(self, deleteChatsPort: DeleteChatsPort): + self.outPort = deleteChatsPort + + + """ + Deletes the chats and returns the response. + Args: + chatsIdsList (List[ChatId]): The chats to delete. + Returns: + List[ChatOperationResponse]: The response of the operation. + """ + def deleteChats(self, chatsIdsList: List[ChatId]) -> List[ChatOperationResponse]: + return self.outPort.deleteChats(chatsIdsList) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/delete_documents.py b/3 - PB/MVP/src/backend/application/service/delete_documents.py new file mode 100644 index 00000000..521ee21c --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/delete_documents.py @@ -0,0 +1,23 @@ +from typing import List +from application.port.out.delete_documents_port import DeleteDocumentsPort +from domain.document.document_operation_response import DocumentOperationResponse +from domain.document.document_id import DocumentId + +""" +This class is the implementation of the DeleteDocumentsUseCase interface. + Attributes: + outPort (DeleteDocumentsPort): The port to use to delete the documents. +""" +class DeleteDocuments: + def __init__(self, deleteDocumentsPort: DeleteDocumentsPort): + self.outPort = deleteDocumentsPort + + """ + Deletes the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to delete. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def deleteDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + return self.outPort.deleteDocuments(documentsIds) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/delete_documents_embeddings.py b/3 - PB/MVP/src/backend/application/service/delete_documents_embeddings.py new file mode 100644 index 00000000..70057091 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/delete_documents_embeddings.py @@ -0,0 +1,24 @@ +from typing import List +from application.port.out.delete_embeddings_port import DeleteEmbeddingsPort +from domain.document.document_operation_response import DocumentOperationResponse +from domain.document.document_id import DocumentId + +""" +This class is the implementation of the DeleteDocumentsEmbeddingsUseCase interface. + Attributes: + outPort (DeleteEmbeddingsPort): The port to use to delete the documents embeddings. +""" +class DeleteDocumentsEmbeddings: + def __init__(self, deleteEmbeddingsPort: DeleteEmbeddingsPort): + self.outPort = deleteEmbeddingsPort + + + """ + Deletes the documents embeddings and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to delete the embeddings. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def deleteDocumentsEmbeddings(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + return self.outPort.deleteDocumentsEmbeddings(documentsIds) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/delete_documents_service.py b/3 - PB/MVP/src/backend/application/service/delete_documents_service.py new file mode 100644 index 00000000..e57bea55 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/delete_documents_service.py @@ -0,0 +1,41 @@ +from application.port._in.delete_documents_use_case import DeleteDocumentsUseCase +from domain.document.document_id import DocumentId +from typing import List +from domain.document.document_operation_response import DocumentOperationResponse +from application.service.delete_documents import DeleteDocuments +from application.service.delete_documents_embeddings import DeleteDocumentsEmbeddings + +from domain.exception.exception import ElaborationException +""" +This class is the implementation of the DeleteDocumentsUseCase interface. + Attributes: + documentsDeleter (DeleteDocuments): The port to use to delete the documents. + deleteDocumentsEmbeddings (DeleteDocumentsEmbeddings): The port to use to delete the documents embeddings. +""" +class DeleteDocumentsService(DeleteDocumentsUseCase): + def __init__(self, deleteDocuments: DeleteDocuments, deleteDocumentsEmbeddings: DeleteDocumentsEmbeddings): + self.documentsDeleter = deleteDocuments + self.deleteDocumentsEmbeddings = deleteDocumentsEmbeddings + + """ + Deletes the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to delete. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def deleteDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + documentOperationResponses = self.deleteDocumentsEmbeddings.deleteDocumentsEmbeddings(documentsIds) + + finalOperationResponses = [] + if len(documentsIds) != len(documentOperationResponses): + raise ElaborationException("Errore nell'elaborazione delle operazioni di cancellazione dei documenti.") + + for documentId, documentOperationResponse in zip(documentsIds, documentOperationResponses): + if documentOperationResponse.ok(): + deleteDocumentOperationResponse = self.documentsDeleter.deleteDocuments([documentId]) + finalOperationResponses = finalOperationResponses + deleteDocumentOperationResponse + else: + finalOperationResponses.append(documentOperationResponse) + print(len(finalOperationResponses)) + return finalOperationResponses \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/documents_uploader.py b/3 - PB/MVP/src/backend/application/service/documents_uploader.py new file mode 100644 index 00000000..2a77d939 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/documents_uploader.py @@ -0,0 +1,26 @@ +from typing import List + +from application.port.out.documents_uploader_port import DocumentsUploaderPort +from domain.document.document import Document +from domain.document.document_operation_response import DocumentOperationResponse + +""" +This module contains the DocumentsUploader class, which is responsible for uploading documents to the system. +Methods: + uploadDocuments(self, documents:List[Document], forceUpload:bool) -> List[DocumentOperationResponse]: + Uploads a list of documents to the system. +""" +class DocumentsUploader: + def __init__(self, documentUploaderPort: DocumentsUploaderPort): + self.outPort = documentUploaderPort + + """ + Uploads a list of documents to the system. + Args: + documents (List[Document]): The documents to upload. + forceUpload (bool): Whether to force the upload of the documents. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def uploadDocuments(self, documents:List[Document], forceUpload:bool) -> List[DocumentOperationResponse]: + return self.outPort.uploadDocuments(documents, forceUpload) diff --git a/3 - PB/MVP/src/backend/application/service/embed_documents_service.py b/3 - PB/MVP/src/backend/application/service/embed_documents_service.py new file mode 100644 index 00000000..dd3b0522 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/embed_documents_service.py @@ -0,0 +1,60 @@ +from typing import List +from application.port._in.embed_documents_use_case import EmbedDocumentsUseCase +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse +from application.service.get_documents_content import GetDocumentsContent +from application.service.embeddings_uploader import EmbeddingsUploader +from application.service.get_documents_status import GetDocumentsStatus +from domain.document.document_status import Status +from domain.document.document import Document + +from domain.exception.exception import ElaborationException +""" +This class is the implementation of the EmbedDocumentsUseCase interface. + Attributes: + getDocumentsContent (GetDocumentsContent): The port to use to get the documents content. + embeddingsUploader (EmbeddingsUploader): The port to use to upload the documents embeddings. + getDocumentStatus (GetDocumentsStatus): The port to use to get the documents status. +""" +class EmbedDocumentsService(EmbedDocumentsUseCase): + def __init__(self, getDocumentsContent: GetDocumentsContent, embeddingsUploader: EmbeddingsUploader, getDocumentStatus: GetDocumentsStatus): + self.getDocumentsContent = getDocumentsContent + self.embeddingsUploader = embeddingsUploader + self.getDocumentStatus = getDocumentStatus + + + """ + Embeds the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to embed. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def embedDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + verifiedDocumentsIds =[] + verifiedDocumentsStatus = [] + + documentsStatus = self.getDocumentStatus.getDocumentsStatus(documentsIds) + + if len(documentsIds) != len(documentsStatus) or len(documentsStatus) == 0: + raise ElaborationException("Errore nel recupero degli stati dei documenti.") + for documentId, documentStatus in zip(documentsIds, documentsStatus): + if documentStatus.status == Status.NOT_EMBEDDED: + verifiedDocumentsIds.append(documentId) + verifiedDocumentsStatus.append(documentStatus) + + if verifiedDocumentsIds != []: + plainDocuments = self.getDocumentsContent.getDocumentsContent(verifiedDocumentsIds) + else: + raise ElaborationException("Nessun documento su cui rigenerare gli embeddings.") + + if len(verifiedDocumentsIds) != len(plainDocuments) or len(plainDocuments) == 0: + raise ElaborationException("Errore nel recupero dei contenuti dei documenti.") + + documentsToEmbed = [] + for plainDocument, documentStatus in zip(plainDocuments, verifiedDocumentsStatus): + documentsToEmbed.append(Document(documentStatus, plainDocument)) if plainDocument else None + + if len(documentsToEmbed) != len(verifiedDocumentsStatus): + raise ElaborationException("Errore nel recupero dei contenuti dei documenti.") + return self.embeddingsUploader.uploadEmbeddings(documentsToEmbed) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/embeddings_uploader.py b/3 - PB/MVP/src/backend/application/service/embeddings_uploader.py new file mode 100644 index 00000000..71fdbc61 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/embeddings_uploader.py @@ -0,0 +1,26 @@ +from typing import List + +from domain.document.document import Document +from domain.document.document_operation_response import DocumentOperationResponse +from application.port.out.embeddings_uploader_port import EmbeddingsUploaderPort + +""" + An embeddings uploader that uploads embeddings to the system. +Methods: + uploadEmbeddings(self, documents:List[Document]) -> List[DocumentOperationResponse]: + Uploads a list of embeddings to the system. +""" +class EmbeddingsUploader: + def __init__(self, outPort: EmbeddingsUploaderPort): + self.outPort = outPort + + + """ + Uploads a list of embeddings to the system. + Args: + documents (List[Document]): The documents to upload. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def uploadEmbeddings(self, documents: List[Document]) -> List[DocumentOperationResponse]: + return self.outPort.uploadEmbeddings(documents) diff --git a/3 - PB/MVP/src/backend/application/service/enable_documents_service.py b/3 - PB/MVP/src/backend/application/service/enable_documents_service.py new file mode 100644 index 00000000..c4e63fa0 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/enable_documents_service.py @@ -0,0 +1,27 @@ +from typing import List +from application.port._in.enable_documents_use_case import EnableDocumentsUseCase +from domain.document.document_id import DocumentId +from domain.document.document_operation_response import DocumentOperationResponse +from application.port.out.enable_documents_port import EnableDocumentsPort + + +""" + A service that enables documents. +Methods: + enableDocuments(self, documentsIds:List[DocumentId]) -> List[DocumentOperationResponse]: + Enables a list of documents. +""" +class EnableDocumentsService(EnableDocumentsUseCase): + def __init__(self, enableDocumentsPort: EnableDocumentsPort): + self.outPort = enableDocumentsPort + + + """ + Enables the documents and returns the response. + Args: + documentsIds (List[DocumentId]): The documents to enable. + Returns: + List[DocumentOperationResponse]: The response of the operation. + """ + def enableDocuments(self, documentsIds: List[DocumentId]) -> List[DocumentOperationResponse]: + return self.outPort.enableDocuments(documentsIds) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/get_chat_messages_service.py b/3 - PB/MVP/src/backend/application/service/get_chat_messages_service.py new file mode 100644 index 00000000..da5e807e --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/get_chat_messages_service.py @@ -0,0 +1,23 @@ +from application.port._in.get_chat_messages_use_case import GetChatMessagesUseCase +from domain.chat.chat import Chat +from domain.chat.chat_id import ChatId +from application.port.out.get_chat_messages_port import GetChatMessagesPort + +""" +This class is the implementation of the GetChatMessagesUseCase interface. + Attributes: + outPort (GetChatMessagesPort): The port to use to get the chat messages. +""" +class GetChatMessagesService(GetChatMessagesUseCase): + def __init__(self, outPort: GetChatMessagesPort): + self.outPort = outPort + + """ + Gets the chat messages and returns the chat. + Args: + chatId (ChatId): The chat id. + Returns: + Chat: The chat. + """ + def getChatMessages(self, chatId: ChatId)->Chat: + return self.outPort.getChatMessages(chatId) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/get_chats_service.py b/3 - PB/MVP/src/backend/application/service/get_chats_service.py new file mode 100644 index 00000000..c59101be --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/get_chats_service.py @@ -0,0 +1,26 @@ +from typing import List + +from application.port._in.get_chats_use_case import GetChatsUseCase +from application.port.out.get_chats_port import GetChatsPort +from domain.chat.chat_filter import ChatFilter +from domain.chat.chat_preview import ChatPreview + +""" +This class is the implementation of the GetChatsUseCase interface. + Attributes: + getChatsPort (GetChatsPort): The port to use to get the chats. +""" +class GetChatsService(GetChatsUseCase): + def __init__(self, getChatsPort: GetChatsPort): + self.getChatsPort = getChatsPort + + """ + Gets the chats and returns the chat previews. + Args: + chatFilter (ChatFilter): The chat filter. + Returns: + List[ChatPreview]: The chat previews. + """ + def getChats(self, chatFilter: ChatFilter) -> List[ChatPreview]: + return self.getChatsPort.getChats(chatFilter) + diff --git a/3 - PB/MVP/src/backend/application/service/get_configuration_options_service.py b/3 - PB/MVP/src/backend/application/service/get_configuration_options_service.py new file mode 100644 index 00000000..bd4979f2 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/get_configuration_options_service.py @@ -0,0 +1,21 @@ +from application.port._in.get_configuration_options_use_case import GetConfigurationOptionsUseCase +from application.port.out.get_configuration_options_port import GetConfigurationOptionsPort +from domain.configuration.configuration_options import ConfigurationOptions + +""" +This class is the implementation of the GetConfigurationOptionsUseCase interface. + Attributes: + getConfigurationOptionsPort (GetConfigurationOptionsPort): The port to use to get the configuration options. +""" +class GetConfigurationOptionsService(GetConfigurationOptionsUseCase): + def __init__(self, getConfigurationOptionsPort: GetConfigurationOptionsPort): + self.outPort = getConfigurationOptionsPort + + + """ + Gets the configuration options and returns them. + Returns: + ConfigurationOptions: The configuration options. + """ + def getConfigurationOptions(self) -> ConfigurationOptions: + return self.outPort.getConfigurationOptions() \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/get_configuration_service.py b/3 - PB/MVP/src/backend/application/service/get_configuration_service.py new file mode 100644 index 00000000..48f8bcd5 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/get_configuration_service.py @@ -0,0 +1,20 @@ +from application.port._in.get_configuration_use_case import GetConfigurationUseCase +from application.port.out.get_configuration_port import GetConfigurationPort +from domain.configuration.configuration import Configuration + +""" +This class is the implementation of the GetConfigurationUseCase interface. + Attributes: + getConfigurationPort (GetConfigurationPort): The port to use to get the configuration. +""" +class GetConfigurationService(GetConfigurationUseCase): + def __init__(self, getConfigurationPort: GetConfigurationPort): + self.outPort = getConfigurationPort + + """ + Gets the configuration and returns it. + Returns: + Configuration: The configuration. + """ + def getConfiguration(self) -> Configuration: + return self.outPort.getConfiguration() \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/get_documents_content.py b/3 - PB/MVP/src/backend/application/service/get_documents_content.py new file mode 100644 index 00000000..afe25736 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/get_documents_content.py @@ -0,0 +1,25 @@ +from typing import List + +from domain.configuration.configuration import Configuration +from domain.document.document_id import DocumentId +from domain.document.plain_document import PlainDocument +from application.port.out.get_documents_content_port import GetDocumentsContentPort + +""" +This class is the implementation of the GetDocumentsContentUseCase interface. + Attributes: + outPort (GetDocumentsContentPort): The port to use to get the documents content. +""" +class GetDocumentsContent: + def __init__(self, outPort: GetDocumentsContentPort): + self.outPort = outPort + + """ + Gets the documents content and returns it. + Args: + documentIds (List[DocumentId]): The documents ids. + Returns: + List[PlainDocument]: The documents content. + """ + def getDocumentsContent(self, documentIds: List[DocumentId])->List[PlainDocument]: + return self.outPort.getDocumentsContent(documentIds) diff --git a/3 - PB/MVP/src/backend/application/service/get_documents_content_facade_service.py b/3 - PB/MVP/src/backend/application/service/get_documents_content_facade_service.py new file mode 100644 index 00000000..f52c757a --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/get_documents_content_facade_service.py @@ -0,0 +1,41 @@ +from typing import List + +from application.port._in.get_documents_content_use_case import GetDocumentsContentUseCase +from domain.document.document import Document +from domain.document.document_id import DocumentId +from application.service.get_documents_status import GetDocumentsStatus +from application.service.get_documents_content import GetDocumentsContent + +from domain.exception.exception import ElaborationException + +""" + A service that gets the content of documents. +Methods: + getDocumentsContent(self, documentIds:List[DocumentId]) -> List[Document]: + Gets the content of a list of documents. +""" +class GetDocumentsContentFacadeService(GetDocumentsContentUseCase): + def __init__(self, documentContentGetter: GetDocumentsContent, getDocumentsStatus: GetDocumentsStatus): + self.documentContentGetter = documentContentGetter + self.getDocumentsStatus = getDocumentsStatus + + + """ + Gets the content of a list of documents. + Args: + documentIds (List[DocumentId]): The documents to get the content. + Returns: + List[Document]: The documents with the content. + """ + def getDocumentsContent(self, documentIds: List[DocumentId]) -> List[Document]: + documentsContent = self.documentContentGetter.getDocumentsContent(documentIds) + documentsStatus = self.getDocumentsStatus.getDocumentsStatus(documentIds) + + if len(documentsContent) != len(documentsStatus) or len(documentsContent) == 0: + raise ElaborationException("Errore nel recupero dei contenuti dei documenti.") + + documents = [] + for documentContent, documentStatus in zip(documentsContent, documentsStatus): + document = Document(plainDocument=documentContent, documentStatus=documentStatus) + documents.append(document) + return documents diff --git a/3 - PB/MVP/src/backend/application/service/get_documents_facade_service.py b/3 - PB/MVP/src/backend/application/service/get_documents_facade_service.py new file mode 100644 index 00000000..09ea8cda --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/get_documents_facade_service.py @@ -0,0 +1,45 @@ +from typing import List + +from application.port._in.get_documents_use_case import GetDocumentsUseCase +from domain.document.document_filter import DocumentFilter +from domain.document.light_document import LightDocument +from application.service.get_documents_status import GetDocumentsStatus +from application.service.get_documents_metadata import GetDocumentsMetadata +from domain.exception.exception import ElaborationException + +""" + A service that gets the documents. +Methods: + getDocuments(self, documentFilter:DocumentFilter) -> List[LightDocument]: + Gets the documents. +""" +class GetDocumentsFacadeService(GetDocumentsUseCase): + def __init__(self, getDocumentsMetadatas: GetDocumentsMetadata, getDocumentsStatus: GetDocumentsStatus): + self.getDocumentsMetadatas = getDocumentsMetadatas + self.getDocumentsStatus = getDocumentsStatus + + + """ + Gets the documents. + Args: + documentFilter (DocumentFilter): The filter to use to get the documents. + Returns: + List[LightDocument]: The documents. + """ + def getDocuments(self, documentFilter: DocumentFilter) -> List[LightDocument]: + documentsMetadata = self.getDocumentsMetadatas.getDocumentsMetadata(documentFilter) + + if len(documentsMetadata) == 0: + raise ElaborationException("Errore nel recupero dei documenti.") + else: + documentsId = [document.id for document in documentsMetadata] + documentsStatus = self.getDocumentsStatus.getDocumentsStatus(documentsId) + + if len(documentsMetadata) != len(documentsStatus) or len(documentsMetadata) == 0: + raise ElaborationException("Errore nel recupero dei documenti.") + + lightDocuments = [] + for documentMetadata, documentStatus in zip(documentsMetadata, documentsStatus): + lightDocument = LightDocument(metadata=documentMetadata, status=documentStatus) + lightDocuments.append(lightDocument) + return lightDocuments \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/get_documents_metadata.py b/3 - PB/MVP/src/backend/application/service/get_documents_metadata.py new file mode 100644 index 00000000..71aec49a --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/get_documents_metadata.py @@ -0,0 +1,24 @@ +from typing import List + +from domain.document.document_filter import DocumentFilter +from domain.document.document_metadata import DocumentMetadata +from application.port.out.get_documents_metadata_port import GetDocumentsMetadataPort + +""" +This class is the implementation of the GetDocumentsMetadataUseCase interface. + Attributes: + outPort (GetDocumentsMetadataPort): The port to use to get the documents metadata. +""" +class GetDocumentsMetadata: + def __init__(self, outPort: GetDocumentsMetadataPort): + self.outPort = outPort + + """ + Gets the documents metadata and returns it. + Args: + documentFilter (DocumentFilter): The document filter. + Returns: + List[DocumentMetadata]: The documents metadata. + """ + def getDocumentsMetadata(self, documentFilter: DocumentFilter) -> List[DocumentMetadata]: + return self.outPort.getDocumentsMetadata(documentFilter) diff --git a/3 - PB/MVP/src/backend/application/service/get_documents_status.py b/3 - PB/MVP/src/backend/application/service/get_documents_status.py new file mode 100644 index 00000000..f39ac732 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/get_documents_status.py @@ -0,0 +1,24 @@ +from typing import List, Dict + +from application.port.out.get_documents_status_port import GetDocumentsStatusPort +from domain.document.document_id import DocumentId +from domain.document.document_status import DocumentStatus + +""" +This class is the implementation of the GetDocumentsStatusUseCase interface. + Attributes: + outPort (GetDocumentsStatusPort): The port to use to get the documents status. +""" +class GetDocumentsStatus: + def __init__(self, outPort: GetDocumentsStatusPort): + self.outPort = outPort + + """ + Gets the documents status and returns it. + Args: + documentsIds (List[DocumentId]): The documents ids. + Returns: + List[DocumentStatus]: The documents status. + """ + def getDocumentsStatus(self, documentsIds: List[DocumentId]) -> List[DocumentStatus]: + return self.outPort.getDocumentsStatus(documentsIds) diff --git a/3 - PB/MVP/src/backend/application/service/rename_chat_service.py b/3 - PB/MVP/src/backend/application/service/rename_chat_service.py new file mode 100644 index 00000000..8693d9e3 --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/rename_chat_service.py @@ -0,0 +1,22 @@ +from domain.chat.chat_id import ChatId +from domain.chat.chat_operation_response import ChatOperationResponse +from application.port._in.rename_chat_use_case import RenameChatUseCase +from application.port.out.rename_chat_port import RenameChatPort + +""" +This class is the implementation of the RenameChatUseCase interface. + Attributes: + outPort (RenameChatPort): The port to use to rename the chat. +""" +class RenameChatService(RenameChatUseCase): + def __init__(self, renameChatPort: RenameChatPort): + self.outPort = renameChatPort + + """ + Renames the chat and returns the response. + Args: + chatId (ChatId): The chat id. + title (str): The new title of the chat. + """ + def renameChat(self, chatId: ChatId, title: str) -> ChatOperationResponse: + return self.outPort.renameChat(chatId, title) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/set_configuration_service.py b/3 - PB/MVP/src/backend/application/service/set_configuration_service.py new file mode 100644 index 00000000..af7bf6eb --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/set_configuration_service.py @@ -0,0 +1,29 @@ +from application.port._in.set_configuration_use_case import SetConfigurationUseCase +from domain.configuration.llm_model_configuration import LLMModelType +from domain.configuration.document_store_configuration import DocumentStoreType +from domain.configuration.vector_store_configuration import VectorStoreType +from domain.configuration.embedding_model_configuration import EmbeddingModelType +from application.port.out.set_configuration_port import SetConfigurationPort +from domain.configuration.configuration_operation_response import ConfigurationOperationResponse +""" +This class is the implementation of the SetConfigurationUseCase interface. It uses the SetConfigurationPort to set the configuration. + Attributes: + outport (SetConfigurationPort): The SetConfigurationPort to use to set the configuration. +""" +class SetConfigurationService(SetConfigurationUseCase): + def __init__(self, setConfigurationPort: SetConfigurationPort): + self.outport = setConfigurationPort + + + """ + Changes the LLM model and returns the response. + Args: + LLModel (LLMModelType): The LLM model to set; + DocumentStore (DocumentStoreType): The Document Store to set; + VectorStoreType (VectorStoreType): The Vector Store to set; + EmbeddingModel (EmbeddingModelType): The Embedding Model to set. + Returns: + ConfigurationOperationResponse: The response of the operation. + """ + def setConfiguration(self, LLModel:LLMModelType, DocumentStore:DocumentStoreType, VectorStoreType:VectorStoreType, EmbeddingModel:EmbeddingModelType) -> ConfigurationOperationResponse: + return self.outport.setConfiguration(LLModel, DocumentStore, VectorStoreType, EmbeddingModel) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/application/service/upload_documents_service.py b/3 - PB/MVP/src/backend/application/service/upload_documents_service.py new file mode 100644 index 00000000..43e90eaa --- /dev/null +++ b/3 - PB/MVP/src/backend/application/service/upload_documents_service.py @@ -0,0 +1,50 @@ +from typing import List + +from application.port._in.upload_documents_use_case import UploadDocumentsUseCase +from application.service.documents_uploader import DocumentsUploader +from application.service.embeddings_uploader import EmbeddingsUploader +from domain.document.document import Document +from domain.document.document_operation_response import DocumentOperationResponse + +from domain.exception.exception import ElaborationException + +""" + UploadDocumentsService class + This class implements the UploadDocumentsUseCase interface + This class is responsible for uploading documents and embeddings to the storage + It uses the DocumentsUploader and EmbeddingsUploader ports to upload the documents and embeddings + It also handles the case when a document is uploaded successfully but the embeddings are not + In this case, the document is not returned as a successful document + Methods: + uploadDocuments: Uploads the documents and embeddings to the storage +""" +class UploadDocumentsService(UploadDocumentsUseCase): + def __init__(self, documentsUploader: DocumentsUploader, embeddingsUploader: EmbeddingsUploader): + self.documentsUploader = documentsUploader + self.embeddingsUploader = embeddingsUploader + """ + Args: + documents: List of Document objects to be uploaded + forceUpload: Boolean to force the upload of the documents + Returns: + List of DocumentOperationResponse objects + """ + + def uploadDocuments(self, documents: List[Document], forceUpload: bool) -> List[DocumentOperationResponse]: + documentOperationResponses = self.documentsUploader.uploadDocuments(documents, forceUpload) + + if len(documents) != len(documentOperationResponses): + raise ElaborationException("Errore nell'elaborazione delle operazioni di upload dei documenti.") + + finalOperationResponses = [] + for document, documentOperationResponse in zip(documents, documentOperationResponses): + if documentOperationResponse.ok(): + embeddingsOperationResponse = self.embeddingsUploader.uploadEmbeddings([document]) + finalOperationResponses.append(embeddingsOperationResponse[0]) + else: + finalOperationResponses.append(documentOperationResponse) + + if len(documents) != len(finalOperationResponses): + raise ElaborationException("Errore nell'elaborazione delle operazioni di upload dei documenti.") + + return finalOperationResponses \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/ask_chatbot.py b/3 - PB/MVP/src/backend/blueprints/ask_chatbot.py new file mode 100644 index 00000000..faf44a63 --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/ask_chatbot.py @@ -0,0 +1,54 @@ +from flask import request, Blueprint, jsonify +from adapter._in.web.ask_chatbot_controller import AskChatbotController +from application.service.ask_chatbot_service import AskChatbotService +from api_exceptions import InsufficientParameters, APIBadRequest, APIElaborationException +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM + +from adapter.out.configuration_manager import ConfigurationManager + +from adapter.out.ask_chatbot.postgres_persist_chat import PostgresPersistChat + +askChatbotBlueprint = Blueprint("askChatbot", __name__) + +""" +This method is the endpoint for the askChatbot API. +Returns: + jsonify: The response of the API. +""" + +@askChatbotBlueprint.route("/askChatbot", methods=['POST']) +def askChatbot(): + userMessage = request.form.get('message') + chatId = request.form.get('chatId') + if userMessage is None: + raise InsufficientParameters() + if userMessage.strip() == "": + raise APIBadRequest(f"Filtro '{userMessage}' non valido.") + if chatId is not None and (not chatId.isdigit() or int(chatId) < 0): + raise APIBadRequest(f"Chat id '{chatId}' non valido.") + validChatId = chatId if chatId is not None else None + + configurationManager = ConfigurationManager(postgresConfigurationORM=PostgresConfigurationORM()) + + controller = AskChatbotController( + AskChatbotService( + configurationManager.getAskChatbotPort(), + PostgresPersistChat(PostgresChatORM()) + ) + ) + + chatbotResponse = controller.askChatbot(' '.join(userMessage.split()), validChatId) + + if chatbotResponse is None or chatbotResponse.chatId is None or not chatbotResponse.ok(): + raise APIElaborationException("Errore nella generazione della risposta.") + + return jsonify({ + "status": chatbotResponse.ok(), + "messageResponse": { + "content": chatbotResponse.messageResponse.content, + "timestamp": chatbotResponse.messageResponse.timestamp, + "relevantDocuments": [relevantDocument.id for relevantDocument in chatbotResponse.messageResponse.relevantDocuments], + "sender": chatbotResponse.messageResponse.sender.name + } if chatbotResponse.messageResponse else None, + "chatId": chatbotResponse.chatId.id}) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/change_configuration.py b/3 - PB/MVP/src/backend/blueprints/change_configuration.py new file mode 100644 index 00000000..15e5d7fe --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/change_configuration.py @@ -0,0 +1,32 @@ +from flask import request, Blueprint, jsonify +from adapter._in.web.change_configuration_controller import ChangeConfigurationController +from application.service.change_configuration_service import ChangeConfigurationService +from api_exceptions import InsufficientParameters, APIElaborationException, APIBadRequest +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.change_configuration.change_configuration_postgres import ChangeConfigurationPostgres + +changeConfigurationBlueprint = Blueprint("changeConfiguration", __name__) +""" +This method is the endpoint for the changeConfiguration API. +Returns: + jsonify: The response of the API. +""" +@changeConfigurationBlueprint.route("/changeConfiguration", methods=['POST']) +def changeConfiguration(): + LLMModelChoice = request.form.get('LLMModel') + if LLMModelChoice is None: + raise InsufficientParameters() + if LLMModelChoice.strip() == "": + raise APIBadRequest(f"Modello LLM '{LLMModelChoice}' non valido.") + validLLMModelChoice = LLMModelChoice.strip().upper() + + controller = ChangeConfigurationController(ChangeConfigurationService(ChangeConfigurationPostgres(PostgresConfigurationORM()))) + + configurationOperationResponse = controller.changeLLMModel(validLLMModelChoice) + + if configurationOperationResponse is None: + raise APIElaborationException("Errore nell'aggiornamento del modello LLM.") + + return jsonify({ + "status": configurationOperationResponse.ok(), + "message": configurationOperationResponse.message}) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/conceal_documents.py b/3 - PB/MVP/src/backend/blueprints/conceal_documents.py new file mode 100644 index 00000000..96cf1314 --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/conceal_documents.py @@ -0,0 +1,42 @@ +from flask import request, Blueprint, jsonify +from adapter._in.web.conceal_documents_controller import ConcealDocumentsController +from application.service.conceal_documents_service import ConcealDocumentsService + +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.configuration_manager import ConfigurationManager +from api_exceptions import APIBadRequest, InsufficientParameters, APIElaborationException + +concealDocumentsBlueprint = Blueprint("concealDocuments", __name__) + +""" +This method is the endpoint for the concealDocuments API. +Returns: + jsonify: The response of the API. +""" +@concealDocumentsBlueprint.route("/concealDocuments", methods=['POST']) +def concealDocuments(): + requestedIds = request.form.getlist('documentIds') + if requestedIds is None: + raise InsufficientParameters() + if len(requestedIds) == 0: + raise APIBadRequest("Nessun id di documento specificato.") + validDocumentIds = [] + for requestedId in requestedIds: + if requestedId.strip() == "": + raise APIBadRequest(f"Id di documento '{requestedId}' non valido.") + else: + validDocumentIds.append(requestedId.strip()) + + configurationManager = ConfigurationManager(postgresConfigurationORM=PostgresConfigurationORM()) + + controller = ConcealDocumentsController(ConcealDocumentsService(configurationManager.getConcealDocumentsPort())) + + documentOperationResponses = controller.concealDocuments(validDocumentIds) + + if len(documentOperationResponses) == 0: + raise APIElaborationException("Errore nell'occultamento dei documenti.") + + return jsonify([{ + "id": documentOperationResponse.documentId.id, + "status": documentOperationResponse.ok(), + "message": documentOperationResponse.message} for documentOperationResponse in documentOperationResponses]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/delete_chats.py b/3 - PB/MVP/src/backend/blueprints/delete_chats.py new file mode 100644 index 00000000..e6b0a981 --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/delete_chats.py @@ -0,0 +1,46 @@ +from flask import request, Blueprint, jsonify +from adapter._in.web.delete_chats_controller import DeleteChatsController +from application.service.delete_chats_service import DeleteChatsService + +from api_exceptions import APIBadRequest, InsufficientParameters, APIElaborationException +from adapter.out.delete_chats.delete_chats_postgres import DeleteChatsPostgres +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM + +deleteChatsBlueprint = Blueprint("deleteChats", __name__) + +""" +This method is the endpoint for the deleteChats API. +Returns: + jsonify: The response of the API. +""" +@deleteChatsBlueprint.route("/deleteChats", methods=['POST']) +def deleteChats(): + requestedIds = request.form.getlist('chatIds') + if requestedIds is None: + raise InsufficientParameters() + if len(requestedIds) == 0: + raise APIBadRequest("Nessun chat id specificato.") + validChatIds = [] + for requestedId in requestedIds: + if requestedId == "" or not requestedId.isdigit() or int(requestedId) < 0: + raise APIBadRequest(f"Chat id '{requestedId}' non valido.") + else: + validChatIds.append(int(requestedId)) + + controller = DeleteChatsController( + DeleteChatsService( + DeleteChatsPostgres( + PostgresChatORM() + ) + ) + ) + + chatOperationResponses = controller.deleteChats(validChatIds) + + if len(chatOperationResponses) == 0: + raise APIElaborationException("Errore nell'eliminazione delle chat.") + + return jsonify([{ + "id": chatOperationResponse.chatId.id, + "status": chatOperationResponse.ok(), + "message": chatOperationResponse.message} for chatOperationResponse in chatOperationResponses]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/delete_documents.py b/3 - PB/MVP/src/backend/blueprints/delete_documents.py new file mode 100644 index 00000000..595461be --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/delete_documents.py @@ -0,0 +1,49 @@ +from flask import request, Blueprint, jsonify +from adapter._in.web.delete_documents_controller import DeleteDocumentsController +from application.service.delete_documents_service import DeleteDocumentsService +from application.service.delete_documents import DeleteDocuments +from application.service.delete_documents_embeddings import DeleteDocumentsEmbeddings + +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.configuration_manager import ConfigurationManager +from api_exceptions import InsufficientParameters, APIBadRequest, APIElaborationException + +deleteDocumentsBlueprint = Blueprint("deleteDocuments", __name__) + +""" +This method is the endpoint for the deleteDocuments API. +Returns: + jsonify: The response of the API. +""" +@deleteDocumentsBlueprint.route("/deleteDocuments", methods=['POST']) +def deleteDocuments(): + requestedIds = request.form.getlist('documentIds') + if requestedIds is None: + raise InsufficientParameters() + if len(requestedIds) == 0: + raise APIBadRequest("Nessun id di documento specificato.") + validDocumentIds = [] + for requestedId in requestedIds: + if requestedId.strip() == "": + raise APIBadRequest(f"Id di documento '{requestedId}' non valido.") + else: + validDocumentIds.append((requestedId).strip()) + + configurationManager = ConfigurationManager(postgresConfigurationORM=PostgresConfigurationORM()) + + controller = DeleteDocumentsController( + DeleteDocumentsService( + DeleteDocuments(configurationManager.getDeleteDocumentsPort()), + DeleteDocumentsEmbeddings(configurationManager.getDeleteEmbeddingsPort()) + ) + ) + + documentOperationResponses = controller.deleteDocuments(validDocumentIds) + + if len(documentOperationResponses) == 0: + raise APIElaborationException("Errore nell'eliminazione dei documenti.") + + return jsonify([{ + "id": documentOperationResponse.documentId.id, + "status": documentOperationResponse.ok(), + "message": documentOperationResponse.message} for documentOperationResponse in documentOperationResponses]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/embed_documents.py b/3 - PB/MVP/src/backend/blueprints/embed_documents.py new file mode 100644 index 00000000..efecfd36 --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/embed_documents.py @@ -0,0 +1,50 @@ +from flask import request, Blueprint, jsonify +from adapter._in.web.embed_documents_controller import EmbedDocumentsController +from application.service.embed_documents_service import EmbedDocumentsService +from application.service.get_documents_content import GetDocumentsContent +from application.service.embeddings_uploader import EmbeddingsUploader +from application.service.get_documents_status import GetDocumentsStatus +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.configuration_manager import ConfigurationManager +from api_exceptions import InsufficientParameters, APIBadRequest, APIElaborationException + +embedDocumentsBlueprint = Blueprint('embed_documents', __name__) + +""" +This method is the endpoint for the embedDocuments API. +Returns: + jsonify: The response of the API. +""" +@embedDocumentsBlueprint.route('/embedDocuments', methods=['POST']) +def embedDocuments(): + requestedIds = request.form.getlist('documentIds') + if requestedIds is None: + raise InsufficientParameters() + if len(requestedIds) == 0: + raise APIBadRequest("Nessun id di documento specificato.") + validDocumentIds = [] + for requestedId in requestedIds: + if requestedId.strip() == "": + raise APIBadRequest(f"Id di documento '{requestedId}' non valido.") + else: + validDocumentIds.append((requestedId).strip()) + + configurationManager = ConfigurationManager(postgresConfigurationORM=PostgresConfigurationORM()) + + controller = EmbedDocumentsController( + embedDocumentsUseCase = EmbedDocumentsService( + GetDocumentsContent(configurationManager.getGetDocumentsContentPort()), + EmbeddingsUploader(configurationManager.getEmbeddingsUploaderPort()), + GetDocumentsStatus(configurationManager.getGetDocumentsStatusPort()) + ) + ) + + documentOperationResponses = controller.embedDocuments(validDocumentIds) + + if len(documentOperationResponses) == 0: + raise APIElaborationException("Errore nella generazione degli embeddings dei documenti.") + + return jsonify([{"id": documentOperationResponse.documentId.id, + "status": documentOperationResponse.ok(), + "message": documentOperationResponse.message} + for documentOperationResponse in documentOperationResponses]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/enable_documents.py b/3 - PB/MVP/src/backend/blueprints/enable_documents.py new file mode 100644 index 00000000..16e3fbbb --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/enable_documents.py @@ -0,0 +1,42 @@ +from flask import request, Blueprint, jsonify +from adapter._in.web.enable_documents_controller import EnableDocumentsController +from application.service.enable_documents_service import EnableDocumentsService + +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.configuration_manager import ConfigurationManager +from api_exceptions import InsufficientParameters, APIBadRequest, APIElaborationException + +enableDocumentsBlueprint = Blueprint("enableDocuments", __name__) + +""" +This method is the endpoint for the enableDocuments API. +Returns: + jsonify: The response of the API. +""" +@enableDocumentsBlueprint.route("/enableDocuments", methods=['POST']) +def enableDocuments(): + requestedIds = request.form.getlist('documentIds') + if requestedIds is None: + raise InsufficientParameters() + if len(requestedIds) == 0: + raise APIBadRequest("Nessun id di documento specificato.") + validDocumentIds = [] + for requestedId in requestedIds: + if requestedId.strip() == "": + raise APIBadRequest(f"Id di documento '{requestedId}' non valido.") + else: + validDocumentIds.append((requestedId).strip()) + + configurationManager = ConfigurationManager(postgresConfigurationORM=PostgresConfigurationORM()) + + controller = EnableDocumentsController(EnableDocumentsService(configurationManager.getEnableDocumentsPort())) + + documentOperationResponses = controller.enableDocuments(validDocumentIds) + + if len(documentOperationResponses) == 0: + raise APIElaborationException("Errore nella riabilitazione dei documenti.") + + return jsonify([{ + "id": documentOperationResponse.documentId.id, + "status": documentOperationResponse.ok(), + "message": documentOperationResponse.message} for documentOperationResponse in documentOperationResponses]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/get_chat_messages.py b/3 - PB/MVP/src/backend/blueprints/get_chat_messages.py new file mode 100644 index 00000000..2ac13e69 --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/get_chat_messages.py @@ -0,0 +1,47 @@ +from flask import Blueprint, jsonify + +from adapter._in.web.get_chat_messages_controller import GetChatMessagesController + +from api_exceptions import InsufficientParameters, APIBadRequest, APIElaborationException +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM +from application.service.get_chat_messages_service import GetChatMessagesService +from adapter.out.get_chat_messages.get_chat_messages_postgres import GetChatMessagesPostgres + +getChatMessagesBlueprint = Blueprint("getChatMessages", __name__) + +""" +This method is the endpoint for the getChatMessages API. +Returns: + jsonify: The response of the API. +""" +@getChatMessagesBlueprint.route('/getChatMessages/', methods=['GET']) +def getChatMessages(chatId): + if chatId is None: + raise InsufficientParameters() + if int(chatId) < 0: + raise APIBadRequest(f"Chat id '{chatId}' non valido.") + + controller = GetChatMessagesController( + GetChatMessagesService( + GetChatMessagesPostgres( + PostgresChatORM() + ) + ) + ) + + chatMessages = controller.getChatMessages(int(chatId)) + + if chatMessages is None: + raise APIElaborationException("Errore nel recupero dei messaggi.") + + return jsonify({ + "title": chatMessages.title, + "id": chatMessages.chatId.id, + "messages": [ + { + "content": chatMessage.content, + "timestamp": chatMessage.timestamp.isoformat(), + "sender": chatMessage.sender.name, + "relevantDocuments": [relevantDocument.id for relevantDocument in chatMessage.relevantDocuments] + } for chatMessage in chatMessages.messages] + }) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/get_chats.py b/3 - PB/MVP/src/backend/blueprints/get_chats.py new file mode 100644 index 00000000..733451e9 --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/get_chats.py @@ -0,0 +1,51 @@ +from flask import Blueprint, jsonify + +from adapter._in.web.get_chats_controller import GetChatsController + +from api_exceptions import InsufficientParameters, APIBadRequest, APIElaborationException +from adapter.out.get_chats.get_chats_postgres import GetChatsPostgres +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM +from application.service.get_chats_service import GetChatsService + +getChatsBlueprint = Blueprint("getChats", __name__) + +""" +This method is the endpoint for the getChats API. +Returns: + jsonify: The response of the API. +""" +@getChatsBlueprint.route('/getChats', defaults={'filter': ''}, methods=['GET']) +@getChatsBlueprint.route("/getChats/", methods=['GET']) +def getDocuments(filter): + if filter is None: + raise InsufficientParameters() + validFilter = filter.strip() + + controller = GetChatsController( + GetChatsService( + GetChatsPostgres( + PostgresChatORM() + ) + ) + ) + + retrievedChats = controller.getChats(validFilter) + + if retrievedChats is None: + raise APIElaborationException('Errore nel recupero delle chat.') + + if len(retrievedChats) == 0: + return jsonify([]), 404 + + return jsonify( + [{ + "id": chat.id.id, + "title": chat.title, + "lastMessage": { + "content": chat.lastMessage.content, + "sender":chat.lastMessage.sender.name, + "timestamp": chat.lastMessage.timestamp.isoformat(), + "relevantDocuments": [relevantDocument.id for relevantDocument in chat.lastMessage.relevantDocuments] + } + } for chat in retrievedChats] + ) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/get_configuration.py b/3 - PB/MVP/src/backend/blueprints/get_configuration.py new file mode 100644 index 00000000..c24a3534 --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/get_configuration.py @@ -0,0 +1,58 @@ +from flask import Blueprint, jsonify + +from adapter._in.web.get_configuration_controller import GetConfigurationController +from application.service.get_configuration_service import GetConfigurationService + +from adapter.out.get_configuration.get_configuration_postgres import GetConfigurationPostgres +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM + +from api_exceptions import APIElaborationException, ConfigurationNotSetException + +getConfigurationBlueprint = Blueprint("getConfiguration", __name__) +""" +This method is the endpoint for the getConfiguration API. +Returns: + jsonify: The response of the API. +""" +@getConfigurationBlueprint.route('/getConfiguration', methods=['GET']) +def getConfiguration(): + controller = GetConfigurationController( + GetConfigurationService( + GetConfigurationPostgres(PostgresConfigurationORM()) + ) + ) + + configuration = controller.getConfiguration() + if configuration is None: + raise APIElaborationException("Errore nel recupero della configurazione.") + + if configuration.documentStore is None or configuration.vectorStore is None or configuration.embeddingModel is None or configuration.LLMModel is None: + return jsonify("Configurazione inesistente."), 401 + + return jsonify({ + "vectorStore": { + "name": configuration.vectorStore.name.name, + "organization": configuration.vectorStore.organization, + "description": configuration.vectorStore.description, + "type": configuration.vectorStore.type, + "costIndicator": configuration.vectorStore.costIndicator}, + "documentStore": { + "name": configuration.documentStore.name.name, + "organization": configuration.documentStore.organization, + "description": configuration.documentStore.description, + "type": configuration.documentStore.type, + "costIndicator": configuration.documentStore.costIndicator}, + "embeddingModel": { + "name": configuration.embeddingModel.name.name, + "organization": configuration.embeddingModel.organization, + "description": configuration.embeddingModel.description, + "type": configuration.embeddingModel.type, + "costIndicator": configuration.embeddingModel.costIndicator}, + "LLMModel": { + "name": configuration.LLMModel.name.name, + "organization": configuration.LLMModel.organization, + "description": configuration.LLMModel.description, + "type": configuration.LLMModel.type, + "costIndicator": configuration.LLMModel.costIndicator + } + }) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/get_configuration_options.py b/3 - PB/MVP/src/backend/blueprints/get_configuration_options.py new file mode 100644 index 00000000..3443b56e --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/get_configuration_options.py @@ -0,0 +1,55 @@ +from flask import Blueprint, jsonify +import json + +from adapter._in.web.get_configuration_options_controller import GetConfigurationOptionsController +from application.service.get_configuration_options_service import GetConfigurationOptionsService + +from adapter.out.get_configuration.get_configuration_options_postgres import GetConfigurationOptionsPostgres +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM + +getConfigurationOptionsBlueprint = Blueprint("getConfigurationOptions", __name__) + +""" +This method is the endpoint for the getConfigurationOptions API. +Returns: + jsonify: The response of the API. +""" +@getConfigurationOptionsBlueprint.route('/getConfigurationOptions', methods=['GET']) +def getConfigurationOptions(): + controller = GetConfigurationOptionsController( + GetConfigurationOptionsService( + GetConfigurationOptionsPostgres(PostgresConfigurationORM()) + ) + ) + + configurationOptions = controller.getConfigurationOptions() + + if configurationOptions is None: + return jsonify({}), 404 + + return jsonify({ + "vectorStores": [{ + "name": vectorStoreOption.name.name, + "organization": vectorStoreOption.organization, + "description": vectorStoreOption.description, + "type": vectorStoreOption.type, + "costIndicator": vectorStoreOption.costIndicator} for vectorStoreOption in configurationOptions.vectorStoreOptions], + "documentStores": [{ + "name": documentStoreOption.name.name, + "organization": documentStoreOption.organization, + "description": documentStoreOption.description, + "type": documentStoreOption.type, + "costIndicator": documentStoreOption.costIndicator} for documentStoreOption in configurationOptions.documentStoreOptions], + "embeddingModels": [{ + "name": embeddingModelOption.name.name, + "organization": embeddingModelOption.organization, + "description": embeddingModelOption.description, + "type": embeddingModelOption.type, + "costIndicator": embeddingModelOption.costIndicator} for embeddingModelOption in configurationOptions.embeddingModelOptions], + "LLMModels": [{ + "name": LLMModelOption.name.name, + "organization": LLMModelOption.organization, + "description": LLMModelOption.description, + "type": LLMModelOption.type, + "costIndicator": LLMModelOption.costIndicator} for LLMModelOption in configurationOptions.LLMModelOptions], + }) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/get_document_content.py b/3 - PB/MVP/src/backend/blueprints/get_document_content.py new file mode 100644 index 00000000..b8aba92e --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/get_document_content.py @@ -0,0 +1,46 @@ +from flask import Blueprint, jsonify +from adapter._in.web.get_document_content_controller import GetDocumentContentController +from application.service.get_documents_content_facade_service import GetDocumentsContentFacadeService +from application.service.get_documents_status import GetDocumentsStatus +from application.service.get_documents_content import GetDocumentsContent + +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.configuration_manager import ConfigurationManager +from api_exceptions import InsufficientParameters, APIBadRequest, APIElaborationException + +getDocumentContentBlueprint = Blueprint("getDocumentContent", __name__) + +""" +This method is the endpoint for the getDocumentContent API. +Returns: + jsonify: The response of the API. +""" +@getDocumentContentBlueprint.route("/getDocumentContent/", methods=['GET']) +def getDocumentsContent(documentId): + if documentId is None: + raise InsufficientParameters() + if documentId.strip() == "": + raise APIBadRequest(f"Id di documento '{documentId}' non valido.") + + configurationManager = ConfigurationManager(postgresConfigurationORM=PostgresConfigurationORM()) + + controller = GetDocumentContentController( + GetDocumentsContentFacadeService( + GetDocumentsContent(configurationManager.getGetDocumentsContentPort()), + GetDocumentsStatus(configurationManager.getGetDocumentsStatusPort()) + ) + ) + + retrievedDocument = controller.getDocumentContent(documentId.strip()) + + if retrievedDocument is None or retrievedDocument.plainDocument is None: + return jsonify({}), 404 + + return jsonify({ + "id": retrievedDocument.plainDocument.metadata.id.id, + "content": retrievedDocument.plainDocument.content.content.hex(), + "type": retrievedDocument.plainDocument.metadata.type.name, + "size": retrievedDocument.plainDocument.metadata.size, + "uploadTime": retrievedDocument.plainDocument.metadata.uploadTime.isoformat(), + "status": retrievedDocument.documentStatus.status.name + }) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/get_documents.py b/3 - PB/MVP/src/backend/blueprints/get_documents.py new file mode 100644 index 00000000..4fd34712 --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/get_documents.py @@ -0,0 +1,44 @@ +from flask import Blueprint, jsonify + +from adapter._in.web.get_documents_controller import GetDocumentsController +from application.service.get_documents_facade_service import GetDocumentsFacadeService +from application.service.get_documents_metadata import GetDocumentsMetadata +from application.service.get_documents_status import GetDocumentsStatus + +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.configuration_manager import ConfigurationManager +from api_exceptions import InsufficientParameters, APIBadRequest + +getDocumentsBlueprint = Blueprint("getDocuments", __name__) + +""" +This method is the endpoint for the getDocuments API. +Returns: + jsonify: The response of the API. +""" +@getDocumentsBlueprint.route('/getDocuments', defaults={'filter': ''}, methods=['GET']) +@getDocumentsBlueprint.route("/getDocuments/", methods=['GET']) +def getDocuments(filter): + if filter is None: + raise InsufficientParameters() + validFilter = filter.strip() + + configurationManager = ConfigurationManager(postgresConfigurationORM=PostgresConfigurationORM()) + + controller = GetDocumentsController( + GetDocumentsFacadeService( + GetDocumentsMetadata(configurationManager.getGetDocumentsMetadataPort()), + GetDocumentsStatus(configurationManager.getGetDocumentsStatusPort()) + ) + ) + + documents = controller.getDocuments(validFilter) + + if len(documents) == 0: + return jsonify([]), 404 + return jsonify([{ + "id": document.metadata.id.id, + "type": document.metadata.type.name, + "size": document.metadata.size, + "uploadTime": document.metadata.uploadTime.isoformat(), + "status": document.status.status.name} for document in documents]) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/rename_chat.py b/3 - PB/MVP/src/backend/blueprints/rename_chat.py new file mode 100644 index 00000000..3bce8117 --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/rename_chat.py @@ -0,0 +1,46 @@ +from flask import request, Blueprint, jsonify +from adapter._in.web.rename_chat_controller import RenameChatController +from application.service.rename_chat_service import RenameChatService + +from adapter.out.rename_chat.rename_chat_postgres import RenameChatPostgres +from adapter.out.persistence.postgres.postgres_chat_orm import PostgresChatORM + +from api_exceptions import InsufficientParameters, APIBadRequest, APIElaborationException + +renameChatBlueprint = Blueprint("renameChat", __name__) + +""" +This method is the endpoint for the renameChat API. +Returns: + + jsonify: The response of the API. + +""" +@renameChatBlueprint.route("/renameChat", methods=['POST']) +def renameChat(): + requestedId = request.form.get('chatId') + requestedTitle = request.form.get('title') + if requestedId is None or requestedTitle is None: + raise InsufficientParameters() + if requestedId.strip() == "" or not requestedId.isdigit() or int(requestedId) < 0: + raise APIBadRequest(f"Chat id '{requestedId}' non valido.") + if requestedTitle.strip() == '': + raise APIBadRequest("Il titolo della chat non può essere vuoto.", 400) + + controller = RenameChatController( + RenameChatService( + RenameChatPostgres( + PostgresChatORM() + ) + ) + ) + + chatOperationResponse = controller.renameChat(chatId=int(requestedId), title=requestedTitle.strip()) + + if chatOperationResponse is None: + raise APIElaborationException("Errore nella rinomina della chat.") + + return jsonify({ + "id": chatOperationResponse.chatId.id, + "status": chatOperationResponse.ok(), + "message": chatOperationResponse.message}) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/set_configuration.py b/3 - PB/MVP/src/backend/blueprints/set_configuration.py new file mode 100644 index 00000000..d0e21a5e --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/set_configuration.py @@ -0,0 +1,45 @@ +from flask import request, Blueprint, jsonify +from adapter._in.web.set_configuration_controller import SetConfigurationController +from application.service.set_configuration_service import SetConfigurationService +from api_exceptions import InsufficientParameters, APIElaborationException, APIBadRequest +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.set_configuration.set_configuration_postgres import SetConfigurationPostgres + +setConfigurationBlueprint = Blueprint("setConfiguration", __name__) +""" +This method is the endpoint for the setConfiguration API. +Returns: + jsonify: The response of the API. +""" +@setConfigurationBlueprint.route("/setConfiguration", methods=['POST']) +def setConfiguration(): + LLMModelChoice = request.form.get('LLMModel') + DocumentStoreChoice = request.form.get('documentStore') + VectorStoreChoice = request.form.get('vectorStore') + EmbeddingModelChoice = request.form.get('embeddingModel') + if LLMModelChoice is None or DocumentStoreChoice is None or VectorStoreChoice is None or EmbeddingModelChoice is None: + raise InsufficientParameters() + if LLMModelChoice.strip() == "": + raise APIBadRequest(f"Modello LLM '{LLMModelChoice}' non valido.") + if DocumentStoreChoice.strip() == "": + raise APIBadRequest(f"Document Store '{DocumentStoreChoice}' non valido.") + if VectorStoreChoice.strip() == "": + raise APIBadRequest(f"Vector Store '{VectorStoreChoice}' non valido.") + if EmbeddingModelChoice.strip() == "": + raise APIBadRequest(f"Modello di embedding '{EmbeddingModelChoice}' non valido.") + + validLLMModelChoice = LLMModelChoice.strip().upper() + validDocumentStoreChoice = DocumentStoreChoice.strip().upper() + validVectorStoreChoice = VectorStoreChoice.strip().upper() + validEmbeddingModelChoice = EmbeddingModelChoice.strip().upper() + + controller = SetConfigurationController(SetConfigurationService(SetConfigurationPostgres(PostgresConfigurationORM()))) + + configurationOperationResponse = controller.setConfiguration(validLLMModelChoice, validDocumentStoreChoice, validVectorStoreChoice, validEmbeddingModelChoice) + + if configurationOperationResponse is None: + raise APIElaborationException("Errore nella inizializzazione della configurazione.") + + return jsonify({ + "status": configurationOperationResponse.ok(), + "message": configurationOperationResponse.message}) \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/blueprints/upload_documents.py b/3 - PB/MVP/src/backend/blueprints/upload_documents.py new file mode 100644 index 00000000..c328ae4b --- /dev/null +++ b/3 - PB/MVP/src/backend/blueprints/upload_documents.py @@ -0,0 +1,66 @@ +import os +from flask import request, Blueprint, jsonify +from werkzeug.utils import secure_filename +from adapter._in.web.presentation_domain.new_document import NewDocument +from adapter._in.web.upload_documents_controller import UploadDocumentsController +from application.service.upload_documents_service import UploadDocumentsService +from application.service.documents_uploader import DocumentsUploader +from application.service.embeddings_uploader import EmbeddingsUploader + +from adapter.out.persistence.postgres.postgres_configuration_orm import PostgresConfigurationORM +from adapter.out.configuration_manager import ConfigurationManager + +from api_exceptions import InsufficientParameters, DocumentNotSupported, APIElaborationException + +uploadDocumentsBlueprint = Blueprint("uploadDocuments", __name__) + +""" +This method is the endpoint for the uploadDocuments API. +Returns: + jsonify: The response of the API. +""" +@uploadDocumentsBlueprint.route("/uploadDocuments", methods=['POST']) +def uploadDocuments(): + forceUpload = request.form.get('forceUpload') + if forceUpload is None: + forceUpload = False + + newDocuments = [] + for uploadedDocument in request.files.getlist('documents'): + secureFilename = secure_filename(uploadedDocument.filename) + if secureFilename == '': + raise DocumentNotSupported("L'upload di documenti senza titolo non è supportato.") + + contentType = uploadedDocument.content_type + if contentType == "application/pdf" or contentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.document": + newDocument = NewDocument( + documentId = secureFilename, + type = "PDF" if contentType == "application/pdf" else "DOCX", + size = uploadedDocument.content_length, + content = uploadedDocument.read() + ) + newDocuments.append(newDocument) + else: + raise DocumentNotSupported(f"Documento {uploadedDocument.filename} non supportato.") + + if len(newDocuments) == 0: + raise InsufficientParameters() + + configurationManager = ConfigurationManager(postgresConfigurationORM=PostgresConfigurationORM()) + + controller = UploadDocumentsController( + uploadDocumentsUseCase = UploadDocumentsService( + DocumentsUploader(configurationManager.getDocumentsUploaderPort()), + EmbeddingsUploader(configurationManager.getEmbeddingsUploaderPort()) + ) + ) + + documentOperationResponses = controller.uploadDocuments(newDocuments, forceUpload) + + if len(documentOperationResponses) == 0: + raise APIElaborationException("Errore nell'upload dei documenti.") + + return jsonify([{ + "id": documentOperationResponse.documentId.id, + "status": documentOperationResponse.ok(), + "message": documentOperationResponse.message} for documentOperationResponse in documentOperationResponses]) diff --git a/3 - PB/MVP/src/backend/domain/chat/chat.py b/3 - PB/MVP/src/backend/domain/chat/chat.py new file mode 100644 index 00000000..560a2ee4 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/chat/chat.py @@ -0,0 +1,18 @@ +from dataclasses import dataclass +from typing import List + +from domain.chat.chat_id import ChatId +from domain.chat.message import Message + +""" +Chat: classe che rappresenta una chat + Attributes: + title (str): Il titolo della chat + chatId (ChatId): L'identificativo della chat + messages (List[Message]): La lista dei messaggi della chat +""" +@dataclass +class Chat: + title: str + chatId: ChatId + messages: List[Message] \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/chat/chat_filter.py b/3 - PB/MVP/src/backend/domain/chat/chat_filter.py new file mode 100644 index 00000000..be8f628f --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/chat/chat_filter.py @@ -0,0 +1,10 @@ +from dataclasses import dataclass + +""" +ChatFilter: classe che rappresenta un filtro per la ricerca di chat + Attributes: + searchFilter (str): Il filtro di ricerca +""" +@dataclass +class ChatFilter: + searchFilter: str \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/chat/chat_id.py b/3 - PB/MVP/src/backend/domain/chat/chat_id.py new file mode 100644 index 00000000..8fb34098 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/chat/chat_id.py @@ -0,0 +1,9 @@ +from dataclasses import dataclass +""" +ChatId: classe che rappresenta l'identificativo di una chat + Attributes: + id (int): L'identificativo della chat +""" +@dataclass +class ChatId: + id: int \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/chat/chat_info.py b/3 - PB/MVP/src/backend/domain/chat/chat_info.py new file mode 100644 index 00000000..20a4e7cc --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/chat/chat_info.py @@ -0,0 +1,13 @@ +from dataclasses import dataclass +from datetime import datetime + +""" +ChatInfo: classe che rappresenta le informazioni di una chat + Attributes: + title (str): Il titolo della chat + timestamp (datetime): Il timestamp della chat +""" +@dataclass +class ChatInfo: + title: str + timestamp: datetime \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/chat/chat_operation_response.py b/3 - PB/MVP/src/backend/domain/chat/chat_operation_response.py new file mode 100644 index 00000000..dc90e6c3 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/chat/chat_operation_response.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass + +from domain.chat.chat_id import ChatId + +""" +ChatOperationResponse: classe che rappresenta la risposta di un'operazione su una chat + Attributes: + chatId (ChatId): L'identificativo della chat + status (bool): Lo stato dell'operazione + message (str): Il messaggio dell'operazione +""" +@dataclass +class ChatOperationResponse: + chatId: ChatId + status: bool + message: str + + def ok(self) -> bool: + return self.status \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/chat/chat_preview.py b/3 - PB/MVP/src/backend/domain/chat/chat_preview.py new file mode 100644 index 00000000..bc903070 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/chat/chat_preview.py @@ -0,0 +1,17 @@ +from dataclasses import dataclass + +from domain.chat.chat_id import ChatId +from domain.chat.message import Message + +""" +ChatPreview: classe che rappresenta una preview di una chat + Attributes: + id (ChatId): L'identificativo della chat + title (str): Il titolo della chat + lastMessage (Message): L'ultimo messaggio della chat +""" +@dataclass +class ChatPreview: + id: ChatId + title: str + lastMessage: Message \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/chat/message.py b/3 - PB/MVP/src/backend/domain/chat/message.py new file mode 100644 index 00000000..d4256711 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/chat/message.py @@ -0,0 +1,31 @@ +from datetime import datetime +from typing import List +from enum import Enum +from domain.document.document_id import DocumentId +from dataclasses import dataclass + +""" +MessageSender: enum che rappresenta il mittente di un messaggio + Attributes: + USER (int): Il mittente è l'utente + CHATBOT (int): Il mittente è il chatbot +""" +@dataclass +class MessageSender(Enum): + USER = 1 + CHATBOT = 2 + +""" +Message: classe che rappresenta un messaggio + Attributes: + content (str): Il contenuto del messaggio + timestamp (datetime): Il timestamp del messaggio + relevantDocuments (List[DocumentId]): La lista dei documenti rilevanti al messaggio + sender (MessageSender): Il mittente del messaggio +""" +@dataclass +class Message: + content: str + timestamp: datetime + relevantDocuments: List[DocumentId] + sender: MessageSender \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/chat/message_response.py b/3 - PB/MVP/src/backend/domain/chat/message_response.py new file mode 100644 index 00000000..a75d9745 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/chat/message_response.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from domain.chat.message import Message +from domain.chat.chat_id import ChatId + +""" +MessageResponse: classe che rappresenta la risposta di un'operazione su un messaggio + Attributes: + chatId (ChatId): L'identificativo della chat + status (bool): Lo stato dell'operazione + messageResponse (Message): Il messaggio dell'operazione +""" +@dataclass +class MessageResponse: + chatId: ChatId + status: bool + messageResponse: Message + + def ok(self) -> bool: + return self.status \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/configuration/configuration.py b/3 - PB/MVP/src/backend/domain/configuration/configuration.py new file mode 100644 index 00000000..787c8d0c --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/configuration/configuration.py @@ -0,0 +1,20 @@ +from dataclasses import dataclass +from domain.configuration.document_store_configuration import DocumentStoreConfiguration +from domain.configuration.embedding_model_configuration import EmbeddingModelConfiguration +from domain.configuration.llm_model_configuration import LLMModelConfiguration +from domain.configuration.vector_store_configuration import VectorStoreConfiguration + +""" +Configuration: classe che rappresenta la configurazione + Attributes: + vectorStore (VectorStoreConfiguration): La configurazione del VectorStore + embeddingModel (EmbeddingModelConfiguration): La configurazione dell'EmbeddingModel + LLMModel (LLMModelConfiguration): La configurazione del LLMModel + documentStore (DocumentStoreConfiguration): La configurazione del DocumentStore +""" +@dataclass +class Configuration: + vectorStore: VectorStoreConfiguration + embeddingModel: EmbeddingModelConfiguration + LLMModel: LLMModelConfiguration + documentStore: DocumentStoreConfiguration diff --git a/3 - PB/MVP/src/backend/domain/configuration/configuration_operation_response.py b/3 - PB/MVP/src/backend/domain/configuration/configuration_operation_response.py new file mode 100644 index 00000000..6396fd74 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/configuration/configuration_operation_response.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass + +""" +ConfigurationOperationResponse: classe che rappresenta la risposta di un'operazione di configurazione + Attributes: + status (bool): Lo stato dell'operazione + message (str): Il messaggio dell'operazione +""" +@dataclass +class ConfigurationOperationResponse: + status: bool + message: str + + def ok(self) -> bool: + return self.status \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/configuration/configuration_options.py b/3 - PB/MVP/src/backend/domain/configuration/configuration_options.py new file mode 100644 index 00000000..53efbb88 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/configuration/configuration_options.py @@ -0,0 +1,21 @@ +from dataclasses import dataclass +from typing import List +from domain.configuration.document_store_configuration import DocumentStoreConfiguration +from domain.configuration.embedding_model_configuration import EmbeddingModelConfiguration +from domain.configuration.llm_model_configuration import LLMModelConfiguration +from domain.configuration.vector_store_configuration import VectorStoreConfiguration + +""" +ConfigurationOptions: classe che rappresenta le opzioni di configurazione + Attributes: + vectorStoreOptions (List[VectorStoreConfiguration]): Le opzioni del VectorStore + embeddingModelOptions (List[EmbeddingModelConfiguration]): Le opzioni dell'EmbeddingModel + LLMModelOptions (List[LLMModelConfiguration]): Le opzioni del LLMModel + documentStoreOptions (List[DocumentStoreConfiguration]): Le opzioni del DocumentStore +""" +@dataclass +class ConfigurationOptions: + vectorStoreOptions: List[VectorStoreConfiguration] + embeddingModelOptions: List[EmbeddingModelConfiguration] + LLMModelOptions: List[LLMModelConfiguration] + documentStoreOptions: List[DocumentStoreConfiguration] diff --git a/3 - PB/MVP/src/backend/domain/configuration/document_store_configuration.py b/3 - PB/MVP/src/backend/domain/configuration/document_store_configuration.py new file mode 100644 index 00000000..7c1340f5 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/configuration/document_store_configuration.py @@ -0,0 +1,28 @@ +from dataclasses import dataclass +from enum import Enum + +""" +DocumentStoreType: enum che rappresenta il tipo di document store + Attributes: + AWS (int): Document store di tipo AWS +""" +@dataclass +class DocumentStoreType(Enum): + AWS = 1 + +""" +DocumentStoreConfiguration: classe che rappresenta la configurazione di un document store + Attributes: + name (DocumentStoreType): Il tipo di document store + organization (str): L'organizzazione + description (str): La descrizione + type (str): Il tipo + costIndicator (str): L'indicatore di costo +""" +@dataclass +class DocumentStoreConfiguration: + name: DocumentStoreType + organization: str + description: str + type: str + costIndicator: str \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/configuration/embedding_model_configuration.py b/3 - PB/MVP/src/backend/domain/configuration/embedding_model_configuration.py new file mode 100644 index 00000000..fd59d8a6 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/configuration/embedding_model_configuration.py @@ -0,0 +1,30 @@ +from dataclasses import dataclass +from enum import Enum + +""" +EmbeddingModelType: enum che rappresenta il tipo di modello di embedding + Attributes: + OPENAI (int): Modello di embedding di tipo OpenAI + HUGGINGFACE (int): Modello di embedding di tipo HuggingFace +""" +@dataclass +class EmbeddingModelType(Enum): + OPENAI = 1 + HUGGINGFACE = 2 + +""" +EmbeddingModelConfiguration: classe che rappresenta la configurazione di un modello di embedding + Attributes: + name (EmbeddingModelType): Il tipo di modello di embedding + organization (str): L'organizzazione + description (str): La descrizione + type (str): Il tipo + costIndicator (str): L'indicatore di costo +""" +@dataclass +class EmbeddingModelConfiguration: + name: EmbeddingModelType + organization: str + description: str + type: str + costIndicator: str \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/configuration/llm_model_configuration.py b/3 - PB/MVP/src/backend/domain/configuration/llm_model_configuration.py new file mode 100644 index 00000000..b497044d --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/configuration/llm_model_configuration.py @@ -0,0 +1,30 @@ +from dataclasses import dataclass +from enum import Enum + +""" +LLMModelType: enum che rappresenta il tipo di modello di LLM + Attributes: + OPENAI (int): Modello di LLM di tipo OpenAI + HUGGINGFACE (int): Modello di LLM di tipo HuggingFace +""" +@dataclass +class LLMModelType(Enum): + OPENAI = 1 + HUGGINGFACE = 2 + +""" +LLMModelConfiguration: classe che rappresenta la configurazione di un modello di LLM + Attributes: + name (LLMModelType): Il tipo di modello di LLM + organization (str): L'organizzazione + description (str): La descrizione + type (str): Il tipo + costIndicator (str): L'indicatore di costo +""" +@dataclass +class LLMModelConfiguration: + name: LLMModelType + organization: str + description: str + type: str + costIndicator: str \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/configuration/vector_store_configuration.py b/3 - PB/MVP/src/backend/domain/configuration/vector_store_configuration.py new file mode 100644 index 00000000..e938129e --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/configuration/vector_store_configuration.py @@ -0,0 +1,30 @@ +from dataclasses import dataclass +from enum import Enum + +""" +VectorStoreType: enum che rappresenta il tipo di vector store + Attributes: + PINECONE (int): Vector store di tipo Pinecone + CHROMA_DB (int): Vector store di tipo ChromaDB +""" +@dataclass +class VectorStoreType(Enum): + PINECONE = 1 + CHROMA_DB = 2 + +""" +VectorStoreConfiguration: classe che rappresenta la configurazione di un vector store + Attributes: + name (VectorStoreType): Il tipo di vector store + organization (str): L'organizzazione + description (str): La descrizione + type (str): Il tipo + costIndicator (str): L'indicatore di costo +""" +@dataclass +class VectorStoreConfiguration: + name: VectorStoreType + organization: str + description: str + type: str + costIndicator: str \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/document/document.py b/3 - PB/MVP/src/backend/domain/document/document.py new file mode 100644 index 00000000..7e054914 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/document/document.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass + +from domain.document.document_status import DocumentStatus +from domain.document.plain_document import PlainDocument + +""" +Document: classe che rappresenta un documento + Attributes: + documentStatus (DocumentStatus): Lo stato del documento + plainDocument (PlainDocument): Il documento in formato testuale +""" +@dataclass +class Document: + documentStatus: DocumentStatus + plainDocument: PlainDocument \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/document/document_content.py b/3 - PB/MVP/src/backend/domain/document/document_content.py new file mode 100644 index 00000000..1e9a5d2b --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/document/document_content.py @@ -0,0 +1,11 @@ +from dataclasses import dataclass + +""" +DocumentContent: classe che rappresenta il contenuto di un documento + Attributes: + content (bytes): Il contenuto del documento +""" + +@dataclass +class DocumentContent: + content: bytes \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/document/document_filter.py b/3 - PB/MVP/src/backend/domain/document/document_filter.py new file mode 100644 index 00000000..c2396bca --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/document/document_filter.py @@ -0,0 +1,11 @@ +from dataclasses import dataclass + +""" +DocumentFilter: classe che rappresenta un filtro per la ricerca di documenti + Attributes: + searchFilter (str): Il filtro di ricerca + +""" +@dataclass +class DocumentFilter: + searchFilter: str \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/document/document_id.py b/3 - PB/MVP/src/backend/domain/document/document_id.py new file mode 100644 index 00000000..3d83fdb2 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/document/document_id.py @@ -0,0 +1,24 @@ +from dataclasses import dataclass + +"""The unique identifier of a document.""" +@dataclass +class DocumentId: + id: str + + """ + Args: + id (str): The unique identifier of the document. + Returns: + DocumentId: The DocumentId object. + """ + def __hash__(self): + return hash(self.id) + + """ + Args: + other (Any): The object to compare. + Returns: + bool: True if the object is a DocumentId and has the same id, False otherwise. + """ + def __eq__(self, other): + return isinstance(other, DocumentId) and self.id == other.id \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/document/document_metadata.py b/3 - PB/MVP/src/backend/domain/document/document_metadata.py new file mode 100644 index 00000000..02721108 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/document/document_metadata.py @@ -0,0 +1,31 @@ +import os +from dataclasses import dataclass +from datetime import datetime +from enum import Enum + +from domain.document.document_id import DocumentId + +""" +The type of a document. +""" +@dataclass +class DocumentType(Enum): + PDF = 1 + DOCX = 2 + + +""" +The metadata of a document. + Attributes: + id (DocumentId): The unique identifier of the document. + type (DocumentType): The type of the document. + size (float): The size of the document in bytes. + uploadTime (datetime): The time when the document was uploaded. +""" +@dataclass +class DocumentMetadata: + id: DocumentId + type: DocumentType + size: float + uploadTime: datetime + diff --git a/3 - PB/MVP/src/backend/domain/document/document_operation_response.py b/3 - PB/MVP/src/backend/domain/document/document_operation_response.py new file mode 100644 index 00000000..26db8f88 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/document/document_operation_response.py @@ -0,0 +1,24 @@ +from dataclasses import dataclass +from domain.document.document_id import DocumentId + +""" + This class is responsible for managing the AWS S3 bucket. + Attributes: + documentId (DocumentId): The ID of the document. + status (bool): The status of the operation. + message (str): The message of the operation. + Methods: + ok() -> bool: + Return the status of the operation. +""" +@dataclass +class DocumentOperationResponse: + documentId: DocumentId + status: bool + message: str + + def ok(self) -> bool: + return self.status + + def ok(self) -> bool: + return self.status \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/document/document_status.py b/3 - PB/MVP/src/backend/domain/document/document_status.py new file mode 100644 index 00000000..1d761f78 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/document/document_status.py @@ -0,0 +1,21 @@ +from dataclasses import dataclass +from enum import Enum + +""" +The status of a document. +""" +@dataclass +class Status(Enum): + CONCEALED = 1 + ENABLED = 2 + NOT_EMBEDDED = 3 + INCONSISTENT = 4 + +""" +The status of a document. + Attributes: + status (Status): The status of the document. +""" +@dataclass +class DocumentStatus: + status: Status \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/document/light_document.py b/3 - PB/MVP/src/backend/domain/document/light_document.py new file mode 100644 index 00000000..778c3228 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/document/light_document.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass + +from domain.document.document_metadata import DocumentMetadata +from domain.document.document_status import DocumentStatus + +""" +LightDocument: classe che rappresenta un documento leggero + Attributes: + metadata (DocumentMetadata): I metadati del documento + status (DocumentStatus): Lo stato del documento +""" +@dataclass +class LightDocument: + metadata: DocumentMetadata + status: DocumentStatus \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/document/plain_document.py b/3 - PB/MVP/src/backend/domain/document/plain_document.py new file mode 100644 index 00000000..c589bfbf --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/document/plain_document.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass + +from domain.document.document_content import DocumentContent +from domain.document.document_metadata import DocumentMetadata + +""" +PlainDocument: classe che rappresenta un documento in formato testuale + Attributes: + metadata (DocumentMetadata): I metadati del documento + content (DocumentContent): Il contenuto del documento +""" +@dataclass +class PlainDocument: + metadata: DocumentMetadata + content: DocumentContent \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/domain/exception/exception.py b/3 - PB/MVP/src/backend/domain/exception/exception.py new file mode 100644 index 00000000..5da87032 --- /dev/null +++ b/3 - PB/MVP/src/backend/domain/exception/exception.py @@ -0,0 +1,6 @@ +""" + Exception class for elaboration errors +""" +class ElaborationException(Exception): + def __init__(self, message): + self.message = message \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/flask.dockerfile b/3 - PB/MVP/src/backend/flask.dockerfile new file mode 100644 index 00000000..96c200cd --- /dev/null +++ b/3 - PB/MVP/src/backend/flask.dockerfile @@ -0,0 +1,17 @@ +FROM python:3.12-slim + +WORKDIR /app + +COPY requirements.txt ./ + +ENV PYTHONDONTWRITEBYTECODE=1 + +RUN apt-get update --fix-missing && apt-get install -y --fix-missing build-essential + +RUN pip install -r requirements.txt + +COPY . . + +EXPOSE 4000 + +CMD [ "flask", "run", "--host=0.0.0.0", "--port=4000"] \ No newline at end of file diff --git a/3 - PB/MVP/src/backend/installed.txt b/3 - PB/MVP/src/backend/installed.txt new file mode 100644 index 00000000..288b5987 Binary files /dev/null and b/3 - PB/MVP/src/backend/installed.txt differ diff --git a/3 - PB/MVP/src/backend/requirements.txt b/3 - PB/MVP/src/backend/requirements.txt new file mode 100644 index 00000000..30c0050e --- /dev/null +++ b/3 - PB/MVP/src/backend/requirements.txt @@ -0,0 +1,24 @@ +boto3 +chromadb +docx2txt +Flask +flask_cors +Flask-SQLAlchemy +huggingface-hub +InstructorEmbedding +langchain +langchain_community +langchain_core +langchain-openai +openai +pypdf +PyPDF2 +pytest +pytest-mock +python-dotenv +pinecone-client +psycopg[binary,pool] +psycopg2-binary +# sentence-transformers +tiktoken +# torch \ No newline at end of file diff --git a/3 - PB/MVP/src/compose.yml b/3 - PB/MVP/src/compose.yml new file mode 100644 index 00000000..c4cacadc --- /dev/null +++ b/3 - PB/MVP/src/compose.yml @@ -0,0 +1,84 @@ +services: + # next.js frontend + nextapp: + container_name: nextapp + image: nextapp:1.0.0 + build: + context: ./frontend + dockerfile: next.dockerfile + ports: + - 3000:3000 + depends_on: + - flaskapp + + # flask backend + flaskapp: + container_name: flaskapp + image: flaskapp:1.0.0 + secrets: + - aws_access_key_id + - aws_bucket_name + - aws_secret_access_key + - chromadb_collection + - huggingface_key + - openai_key + - pinecone_api + - pinecone_environment + - pinecone_index_name + build: + context: ./backend + dockerfile: flask.dockerfile + ports: + - 4000:4000 + environment: + - FLASK_DEBUG=true + - DATABASE_URL=postgresql://postgres:postgres@database:5432/postgres + - TMP_STORAGE_FOLDER=tmp + - CHROMA_DB_PATH=chroma_db + - CHUNK_SIZE=512 + - CHUNK_OVERLAP=128 + - RETRIEVER_CHUNKS_NUM=4 + - AWS_REGION_NAME=eu-west-1 + - MAX_FILE_SIZE=10485760 + - USER_ID=1 + volumes: + - ./backend:/app + depends_on: + - database + + # postgres database + database: + container_name: database + image: postgres:16 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + ports: + - 5432:5432 + volumes: + - pgdata:/var/lib/postgresql/data + +secrets: + aws_access_key_id: + file: ./secrets/aws_access_key_id.txt + aws_bucket_name: + file: ./secrets/aws_bucket_name.txt + aws_secret_access_key: + file: ./secrets/aws_secret_access_key.txt + chromadb_collection: + file: ./secrets/chromadb_collection.txt + huggingface_key: + file: ./secrets/huggingface_key.txt + openai_key: + file: ./secrets/openai_key.txt + pinecone_api: + file: ./secrets/pinecone_api.txt + pinecone_environment: + file: ./secrets/pinecone_environment.txt + pinecone_index_name: + file: ./secrets/pinecone_index_name.txt + + +volumes: + pgdata: {} \ No newline at end of file diff --git a/3 - PB/MVP/src/frontend/.dockerignore b/3 - PB/MVP/src/frontend/.dockerignore new file mode 100644 index 00000000..72e9aa42 --- /dev/null +++ b/3 - PB/MVP/src/frontend/.dockerignore @@ -0,0 +1,7 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git \ No newline at end of file diff --git a/3 - PB/MVP/src/frontend/.eslintrc.json b/3 - PB/MVP/src/frontend/.eslintrc.json new file mode 100644 index 00000000..bffb357a --- /dev/null +++ b/3 - PB/MVP/src/frontend/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/3 - PB/MVP/src/frontend/.gitignore b/3 - PB/MVP/src/frontend/.gitignore new file mode 100644 index 00000000..fd3dbb57 --- /dev/null +++ b/3 - PB/MVP/src/frontend/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/3 - PB/MVP/src/frontend/components.json b/3 - PB/MVP/src/frontend/components.json new file mode 100644 index 00000000..8c574b77 --- /dev/null +++ b/3 - PB/MVP/src/frontend/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils" + } +} \ No newline at end of file diff --git a/3 - PB/MVP/src/frontend/next.config.mjs b/3 - PB/MVP/src/frontend/next.config.mjs new file mode 100644 index 00000000..a67b77a4 --- /dev/null +++ b/3 - PB/MVP/src/frontend/next.config.mjs @@ -0,0 +1,27 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + swcMinify: true, + output: 'standalone', + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: 'avatars.githubusercontent.com', + }, + { + protocol: 'https', + hostname: 'images.unsplash.com', + }, + ], + }, + webpack: (config, options) => { + config.module.rules.push({ + test: /\bcanvas\.(node)/, + use: 'raw-loader', + }) + return config + }, +} + +export default nextConfig diff --git a/3 - PB/MVP/src/frontend/next.dockerfile b/3 - PB/MVP/src/frontend/next.dockerfile new file mode 100644 index 00000000..a9ae68f4 --- /dev/null +++ b/3 - PB/MVP/src/frontend/next.dockerfile @@ -0,0 +1,68 @@ +FROM node:21-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app + +RUN npm install -g node-gyp; +RUN apk add --no-cache \ + build-base \ + g++ \ + cairo-dev \ + jpeg-dev \ + pango-dev \ + giflib-dev + +# Install dependencies based on the preferred package manager +COPY package.json package-lock.json* ./ +RUN npm ci; + + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN npm run build; + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT 3000 +ENV HOSTNAME "0.0.0.0" +ENV API_URL "http://172.19.0.3:4000" + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/next-config-js/output +CMD ["node", "server.js"] \ No newline at end of file diff --git a/3 - PB/MVP/src/frontend/package-lock.json b/3 - PB/MVP/src/frontend/package-lock.json new file mode 100644 index 00000000..2631aafa --- /dev/null +++ b/3 - PB/MVP/src/frontend/package-lock.json @@ -0,0 +1,14451 @@ +{ + "name": "kmai", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "kmai", + "version": "0.1.0", + "dependencies": { + "@cyntler/react-doc-viewer": "^1.14.1", + "@hookform/resolvers": "^3.3.4", + "@radix-ui/react-accessible-icon": "^1.0.3", + "@radix-ui/react-accordion": "^1.1.2", + "@radix-ui/react-alert-dialog": "^1.0.5", + "@radix-ui/react-aspect-ratio": "^1.0.3", + "@radix-ui/react-avatar": "^1.0.3", + "@radix-ui/react-checkbox": "^1.0.4", + "@radix-ui/react-collapsible": "^1.0.3", + "@radix-ui/react-context-menu": "^2.1.5", + "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-dropdown-menu": "^2.0.5", + "@radix-ui/react-hover-card": "^1.0.7", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-menubar": "^1.0.4", + "@radix-ui/react-navigation-menu": "^1.1.3", + "@radix-ui/react-popover": "^1.0.6", + "@radix-ui/react-progress": "^1.0.3", + "@radix-ui/react-radio-group": "^1.1.3", + "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.0.3", + "@radix-ui/react-slider": "^1.1.2", + "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-switch": "^1.0.3", + "@radix-ui/react-tabs": "^1.0.4", + "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-toggle": "^1.0.3", + "@radix-ui/react-toggle-group": "^1.0.4", + "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-table": "^8.9.1", + "@types/react-pdf": "^7.0.0", + "@vercel/analytics": "^1.0.1", + "@vercel/og": "^0.0.21", + "canvas": "^2.11.2", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.0", + "cmdk": "^0.2.1", + "contentlayer": "0.3.4", + "date-fns": "^3.6.0", + "embla-carousel-autoplay": "8.0.0-rc15", + "embla-carousel-react": "^8.0.0-rc15", + "framer-motion": "^11.0.14", + "geist": "^1.1.0", + "jotai": "^2.7.1", + "lodash.template": "^4.5.0", + "lucide-react": "^0.344.0", + "mammoth": "^1.7.1", + "markdown-wasm": "^1.2.0", + "next": "14.1.0", + "next-auth": "^4.24.7", + "next-themes": "^0.2.1", + "pdf-lib": "^1.17.1", + "pretty-bytes": "^6.1.1", + "react": "^18", + "react-day-picker": "^8.10.0", + "react-doc-viewer": "^0.1.5", + "react-dom": "^18", + "react-hook-form": "^7.51.0", + "react-resizable-panels": "^0.0.55", + "react-wrap-balancer": "^0.4.1", + "recharts": "^2.6.2", + "sharp": "^0.32.6", + "sonner": "^1.4.41", + "tailwind-merge": "^2.2.1", + "tailwindcss-animate": "^1.0.7", + "vaul": "^0.2.3", + "zod": "^3.22.4" + }, + "devDependencies": { + "@types/lodash.template": "^4.5.1", + "@types/node": "^17.0.45", + "@types/react": "^18.2.7", + "@types/react-color": "^3.0.6", + "@types/react-dom": "^18.2.4", + "autoprefixer": "^10.0.1", + "eslint": "^8", + "eslint-config-next": "14.1.1", + "file-loader": "^6.2.0", + "mdast-util-toc": "^6.1.1", + "postcss": "^8", + "raw-loader": "^4.0.2", + "rehype": "^12.0.1", + "rehype-autolink-headings": "^6.1.1", + "rehype-pretty-code": "^0.6.0", + "rehype-slug": "^5.1.0", + "remark": "^14.0.3", + "remark-code-import": "^1.2.0", + "remark-gfm": "^3.0.1", + "rimraf": "^4.1.3", + "shiki": "^0.12.1", + "tailwindcss": "^3.3.0", + "typescript": "^5", + "unist-builder": "3.0.0", + "unist-util-visit": "^4.1.2" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "peer": true, + "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.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dependencies": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", + "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", + "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.1", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.1", + "@babel/parser": "^7.24.1", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", + "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", + "dependencies": { + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "peer": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "peer": true + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "dependencies": { + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "peer": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "peer": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", + "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", + "peer": true, + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/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==" + }, + "node_modules/@babel/highlight/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==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", + "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", + "dependencies": { + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@contentlayer/cli": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@contentlayer/cli/-/cli-0.3.4.tgz", + "integrity": "sha512-vNDwgLuhYNu+m70NZ3XK9kexKNguuxPXg7Yvzj3B34cEilQjjzSrcTY/i+AIQm9V7uT5GGshx9ukzPf+SmoszQ==", + "dependencies": { + "@contentlayer/core": "0.3.4", + "@contentlayer/utils": "0.3.4", + "clipanion": "^3.2.1", + "typanion": "^3.12.1" + } + }, + "node_modules/@contentlayer/client": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@contentlayer/client/-/client-0.3.4.tgz", + "integrity": "sha512-QSlLyc3y4PtdC5lFw0L4wTZUH8BQnv2nk37hNCsPAqGf+dRO7TLAzdc+2/mVIRgK+vSH+pSOzjLsQpFxxXRTZA==", + "dependencies": { + "@contentlayer/core": "0.3.4" + } + }, + "node_modules/@contentlayer/core": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@contentlayer/core/-/core-0.3.4.tgz", + "integrity": "sha512-o68oBLwfYZ+2vtgfk1lgHxOl3LoxvRNiUfeQ8IWFWy/L4wnIkKIqLZX01zlRE5IzYM+ZMMN5V0cKQlO7DsyR9g==", + "dependencies": { + "@contentlayer/utils": "0.3.4", + "camel-case": "^4.1.2", + "comment-json": "^4.2.3", + "esbuild": "0.17.x || 0.18.x", + "gray-matter": "^4.0.3", + "mdx-bundler": "^9.2.1", + "rehype-stringify": "^9.0.3", + "remark-frontmatter": "^4.0.1", + "remark-parse": "^10.0.2", + "remark-rehype": "^10.1.0", + "source-map-support": "^0.5.21", + "type-fest": "^3.12.0", + "unified": "^10.1.2" + }, + "peerDependencies": { + "esbuild": "0.17.x || 0.18.x", + "markdown-wasm": "1.x" + }, + "peerDependenciesMeta": { + "esbuild": { + "optional": true + }, + "markdown-wasm": { + "optional": true + } + } + }, + "node_modules/@contentlayer/source-files": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@contentlayer/source-files/-/source-files-0.3.4.tgz", + "integrity": "sha512-4njyn0OFPu7WY4tAjMxiJgWOKeiHuBOGdQ36EYE03iij/pPPRbiWbL+cmLccYXUFEW58mDwpqROZZm6pnxjRDQ==", + "dependencies": { + "@contentlayer/core": "0.3.4", + "@contentlayer/utils": "0.3.4", + "chokidar": "^3.5.3", + "fast-glob": "^3.2.12", + "gray-matter": "^4.0.3", + "imagescript": "^1.2.16", + "micromatch": "^4.0.5", + "ts-pattern": "^4.3.0", + "unified": "^10.1.2", + "yaml": "^2.3.1", + "zod": "^3.21.4" + } + }, + "node_modules/@contentlayer/source-remote-files": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@contentlayer/source-remote-files/-/source-remote-files-0.3.4.tgz", + "integrity": "sha512-cyiv4sNUySZvR0uAKlM+kSAELzNd2h2QT1R2e41dRKbwOUVxeLfmGiLugr0aVac6Q3xYcD99dbHyR1xWPV+w9w==", + "dependencies": { + "@contentlayer/core": "0.3.4", + "@contentlayer/source-files": "0.3.4", + "@contentlayer/utils": "0.3.4" + } + }, + "node_modules/@contentlayer/utils": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@contentlayer/utils/-/utils-0.3.4.tgz", + "integrity": "sha512-ZWWOhbUWYQ2QHoLIlcUnEo7X4ZbwcyFPuzVQWWMkK43BxCveyQtZwBIzfyx54sqVzi0GUmKP8bHzsLQT0QxaLQ==", + "dependencies": { + "@effect-ts/core": "^0.60.5", + "@effect-ts/otel": "^0.15.1", + "@effect-ts/otel-exporter-trace-otlp-grpc": "^0.15.1", + "@effect-ts/otel-sdk-trace-node": "^0.15.1", + "@js-temporal/polyfill": "^0.4.4", + "@opentelemetry/api": "^1.4.1", + "@opentelemetry/core": "^1.13.0", + "@opentelemetry/exporter-trace-otlp-grpc": "^0.39.1", + "@opentelemetry/resources": "^1.13.0", + "@opentelemetry/sdk-trace-base": "^1.13.0", + "@opentelemetry/sdk-trace-node": "^1.13.0", + "@opentelemetry/semantic-conventions": "^1.13.0", + "chokidar": "^3.5.3", + "hash-wasm": "^4.9.0", + "inflection": "^2.0.1", + "memfs": "^3.5.1", + "oo-ascii-tree": "^1.84.0", + "ts-pattern": "^4.3.0", + "type-fest": "^3.12.0" + }, + "peerDependenciesMeta": { + "@effect-ts/core": { + "optional": true + }, + "@effect-ts/otel": { + "optional": true + }, + "@effect-ts/otel-node": { + "optional": true + } + } + }, + "node_modules/@cyntler/react-doc-viewer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@cyntler/react-doc-viewer/-/react-doc-viewer-1.14.1.tgz", + "integrity": "sha512-1LiYewtiLM6FZgkJmlAiibv3zeiDinII+WKjViLeaD7O9yP+F9TqYyYSTR05crZODltzHenn/Tcx9YesV9tKtA==", + "dependencies": { + "@types/mustache": "^4.2.3", + "@types/papaparse": "^5.3.9", + "mustache": "^4.2.0", + "papaparse": "^5.4.1", + "react-pdf": "7.5.0", + "styled-components": "^6.0.8" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "react": ">=16.13.1", + "react-dom": ">=16.13.1" + } + }, + "node_modules/@cyntler/react-doc-viewer/node_modules/pdfjs-dist": { + "version": "3.11.174", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", + "integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==", + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "canvas": "^2.11.2", + "path2d-polyfill": "^2.0.1" + } + }, + "node_modules/@cyntler/react-doc-viewer/node_modules/react-pdf": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-7.5.0.tgz", + "integrity": "sha512-hX7SfQGd9T6pdd3H5HcR1VzrRCehkhnBh/tsyz9GO9cXrYHgoxupboVL2VCQpBBSak+/UQSMCj+3JTOdheuwwQ==", + "dependencies": { + "clsx": "^2.0.0", + "make-cancellable-promise": "^1.3.1", + "make-event-props": "^1.6.0", + "merge-refs": "^1.2.1", + "pdfjs-dist": "3.11.174", + "prop-types": "^15.6.2", + "tiny-invariant": "^1.0.0", + "tiny-warning": "^1.0.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-pdf?sponsor=1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@effect-ts/core": { + "version": "0.60.5", + "resolved": "https://registry.npmjs.org/@effect-ts/core/-/core-0.60.5.tgz", + "integrity": "sha512-qi1WrtJA90XLMnj2hnUszW9Sx4dXP03ZJtCc5DiUBIOhF4Vw7plfb65/bdBySPoC9s7zy995TdUX1XBSxUkl5w==", + "dependencies": { + "@effect-ts/system": "^0.57.5" + } + }, + "node_modules/@effect-ts/otel": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@effect-ts/otel/-/otel-0.15.1.tgz", + "integrity": "sha512-AmZJHl7t0+Peh7Yb2+hqn6r9+rd9/UfeA4AMV9h0YGTdOyouyFfD3wzWlxnAUzAQ4Lrod4kC7Noruret4EpqpA==", + "peerDependencies": { + "@effect-ts/core": "^0.60.2", + "@opentelemetry/api": "^1.4.0", + "@opentelemetry/core": "^1.13.0", + "@opentelemetry/sdk-trace-base": "^1.13.0" + } + }, + "node_modules/@effect-ts/otel-exporter-trace-otlp-grpc": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@effect-ts/otel-exporter-trace-otlp-grpc/-/otel-exporter-trace-otlp-grpc-0.15.1.tgz", + "integrity": "sha512-47gAg0O2pW5Jlo86jfzjdkwL5a7Bzb+Kj5WTmdu4CxYRfWn9ytKjuuYIfsNDW8neuhdKzn+P5wCddgEh0glYyQ==", + "dependencies": { + "@effect-ts/otel": "^0.15.1" + }, + "peerDependencies": { + "@effect-ts/core": "^0.60.2", + "@opentelemetry/api": "^1.4.0", + "@opentelemetry/core": "^1.13.0", + "@opentelemetry/exporter-trace-otlp-grpc": "^0.39.0", + "@opentelemetry/sdk-trace-base": "^1.13.0" + } + }, + "node_modules/@effect-ts/otel-sdk-trace-node": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@effect-ts/otel-sdk-trace-node/-/otel-sdk-trace-node-0.15.1.tgz", + "integrity": "sha512-a2sF0ylmn8xOJs8fNeT/spJ1gUcsksAJCALxo9WOfuTCMtTwMVtVhCKEPEeQoL7wFqU+JgPkVdP91+FJ/Rkeow==", + "dependencies": { + "@effect-ts/otel": "^0.15.1" + }, + "peerDependencies": { + "@effect-ts/core": "^0.60.2", + "@opentelemetry/api": "^1.4.0", + "@opentelemetry/core": "^1.13.0", + "@opentelemetry/sdk-trace-base": "^1.13.0", + "@opentelemetry/sdk-trace-node": "^1.13.0" + } + }, + "node_modules/@effect-ts/system": { + "version": "0.57.5", + "resolved": "https://registry.npmjs.org/@effect-ts/system/-/system-0.57.5.tgz", + "integrity": "sha512-/crHGujo0xnuHIYNc1VgP0HGJGFSoSqq88JFXe6FmFyXPpWt8Xu39LyLg7rchsxfXFeEdA9CrIZvLV5eswXV5g==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + }, + "node_modules/@esbuild-plugins/node-resolve": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@esbuild-plugins/node-resolve/-/node-resolve-0.1.4.tgz", + "integrity": "sha512-haFQ0qhxEpqtWWY0kx1Y5oE3sMyO1PcoSiWEPrAw6tm/ZOOLXjSs6Q+v1v9eyuVF0nNt50YEvrcrvENmyoMv5g==", + "dependencies": { + "@types/resolve": "^1.17.1", + "debug": "^4.3.1", + "escape-string-regexp": "^4.0.0", + "resolve": "^1.19.0" + }, + "peerDependencies": { + "esbuild": "*" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@fal-works/esbuild-plugin-global-externals": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz", + "integrity": "sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==" + }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.4.tgz", + "integrity": "sha512-MqBisuxTkYvPFnEiu+dag3xG/NBUDzSbAFAWlzfkGnQkjVZ6by3h4atbBc+Ikqup1z5BfB4BN18gKWR1YyppNw==", + "dependencies": { + "@grpc/proto-loader": "^0.7.10", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.12", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.12.tgz", + "integrity": "sha512-DCVwMxqYzpUCiDMl7hQ384FqP4T3DbNpXU8pt681l3UWCip1WUiD5JrkImUwCB9a7f2cq4CUTmi5r/xIMRPY1Q==", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@hookform/resolvers": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz", + "integrity": "sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "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==", + "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-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@js-temporal/polyfill": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@js-temporal/polyfill/-/polyfill-0.4.4.tgz", + "integrity": "sha512-2X6bvghJ/JAoZO52lbgyAPFj8uCflhTo2g7nkFzEQdXd/D8rEeD4HtmTEpmtGCva260fcd66YNXBOYdnmHqSOg==", + "dependencies": { + "jsbi": "^4.3.0", + "tslib": "^2.4.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "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/@mapbox/node-pre-gyp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@mdx-js/esbuild": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@mdx-js/esbuild/-/esbuild-2.3.0.tgz", + "integrity": "sha512-r/vsqsM0E+U4Wr0DK+0EfmABE/eg+8ITW4DjvYdh3ve/tK2safaqHArNnaqbOk1DjYGrhxtoXoGaM3BY8fGBTA==", + "dependencies": { + "@mdx-js/mdx": "^2.0.0", + "node-fetch": "^3.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "esbuild": ">=0.11.0" + } + }, + "node_modules/@mdx-js/esbuild/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.3.0.tgz", + "integrity": "sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/mdx": "^2.0.0", + "estree-util-build-jsx": "^2.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "estree-util-to-js": "^1.1.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^2.0.0", + "markdown-extensions": "^1.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^2.0.0", + "remark-parse": "^10.0.0", + "remark-rehype": "^10.0.0", + "unified": "^10.0.0", + "unist-util-position-from-estree": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@next/env": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz", + "integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1.tgz", + "integrity": "sha512-NP1WoGFnFLpqqCWgGFjnn/sTwUExdPyjeFKRdQP1X/bL/tjAQ/TXDmYqw6vzGaP5NaZ2u6xzg+N/0nd7fOPOGQ==", + "dev": true, + "dependencies": { + "glob": "10.3.10" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz", + "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz", + "integrity": "sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz", + "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz", + "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz", + "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz", + "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz", + "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz", + "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz", + "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz", + "integrity": "sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.39.1.tgz", + "integrity": "sha512-9BJ8lMcOzEN0lu+Qji801y707oFO4xT3db6cosPvl+k7ItUHKN5ofWqtSbM9gbt1H4JJ/4/2TVrqI9Rq7hNv6Q==", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.22.0.tgz", + "integrity": "sha512-Nfdxyg8YtWqVWkyrCukkundAjPhUXi93JtVQmqDT1mZRVKqA7e2r7eJCrI+F651XUBMp0hsOJSGiFk3QSpaIJw==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.22.0.tgz", + "integrity": "sha512-0VoAlT6x+Xzik1v9goJ3pZ2ppi6+xd3aUfg4brfrLkDBHRIVjMP0eBHrKrhB+NKcDyMAg8fAbGL3Npg/F6AwWA==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.22.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.39.1.tgz", + "integrity": "sha512-l5RhLKx6U+yuLhMrtgavTDthX50E1mZM3/SSySC7OPZiArFHV/b/9x9jxAzrOgIQUDxyj4N0V9aLKSA2t7Qzxg==", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.13.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.39.1", + "@opentelemetry/otlp-transformer": "0.39.1", + "@opentelemetry/resources": "1.13.0", + "@opentelemetry/sdk-trace-base": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/core": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.13.0.tgz", + "integrity": "sha512-2dBX3Sj99H96uwJKvc2w9NOiNgbvAO6mOFJFramNkKfS9O4Um+VWgpnlAazoYjT6kUJ1MP70KQ5ngD4ed+4NUw==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/resources": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.13.0.tgz", + "integrity": "sha512-euqjOkiN6xhjE//0vQYGvbStxoD/WWQRhDiO0OTLlnLBO9Yw2Gd/VoSx2H+svsebjzYk5OxLuREBmcdw6rbUNg==", + "dependencies": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.13.0.tgz", + "integrity": "sha512-moTiQtc0uPR1hQLt6gLDJH9IIkeBhgRb71OKjNHZPE1VF45fHtD6nBDi5J/DkTHTwYP5X3kBJLa3xN7ub6J4eg==", + "dependencies": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/resources": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.13.0.tgz", + "integrity": "sha512-LMGqfSZkaMQXqewO0o1wvWr/2fQdCh4a3Sqlxka/UsJCe0cfLulh6x2aqnKLnsrSGiCq5rSCwvINd152i0nCqw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.39.1.tgz", + "integrity": "sha512-Pv5X8fbi6jD/RJBePyn7MnCSuE6MbPB6dl+7YYBWJ5RcMGYMwvLXjd4h2jWsPV2TSUg38H/RoSP0aXvQ06Y7iw==", + "dependencies": { + "@opentelemetry/core": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/core": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.13.0.tgz", + "integrity": "sha512-2dBX3Sj99H96uwJKvc2w9NOiNgbvAO6mOFJFramNkKfS9O4Um+VWgpnlAazoYjT6kUJ1MP70KQ5ngD4ed+4NUw==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.13.0.tgz", + "integrity": "sha512-LMGqfSZkaMQXqewO0o1wvWr/2fQdCh4a3Sqlxka/UsJCe0cfLulh6x2aqnKLnsrSGiCq5rSCwvINd152i0nCqw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.39.1.tgz", + "integrity": "sha512-u3ErFRQqQFKjjIMuwLWxz/tLPYInfmiAmSy//fGSCzCh2ZdJgqQjMOAxBgqFtCF2xFL+OmMhyuC2ThMzceGRWA==", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.13.0", + "@opentelemetry/otlp-exporter-base": "0.39.1", + "protobufjs": "^7.2.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base/node_modules/@opentelemetry/core": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.13.0.tgz", + "integrity": "sha512-2dBX3Sj99H96uwJKvc2w9NOiNgbvAO6mOFJFramNkKfS9O4Um+VWgpnlAazoYjT6kUJ1MP70KQ5ngD4ed+4NUw==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.13.0.tgz", + "integrity": "sha512-LMGqfSZkaMQXqewO0o1wvWr/2fQdCh4a3Sqlxka/UsJCe0cfLulh6x2aqnKLnsrSGiCq5rSCwvINd152i0nCqw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.39.1.tgz", + "integrity": "sha512-0hgVnXXz5efI382B/24NxD4b6Zxlh7nxCdJkxkdmQMbn0yRiwoq/ZT+QG8eUL6JNzsBAV1WJlF5aJNsL8skHvw==", + "dependencies": { + "@opentelemetry/api-logs": "0.39.1", + "@opentelemetry/core": "1.13.0", + "@opentelemetry/resources": "1.13.0", + "@opentelemetry/sdk-logs": "0.39.1", + "@opentelemetry/sdk-metrics": "1.13.0", + "@opentelemetry/sdk-trace-base": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/core": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.13.0.tgz", + "integrity": "sha512-2dBX3Sj99H96uwJKvc2w9NOiNgbvAO6mOFJFramNkKfS9O4Um+VWgpnlAazoYjT6kUJ1MP70KQ5ngD4ed+4NUw==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/resources": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.13.0.tgz", + "integrity": "sha512-euqjOkiN6xhjE//0vQYGvbStxoD/WWQRhDiO0OTLlnLBO9Yw2Gd/VoSx2H+svsebjzYk5OxLuREBmcdw6rbUNg==", + "dependencies": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.13.0.tgz", + "integrity": "sha512-moTiQtc0uPR1hQLt6gLDJH9IIkeBhgRb71OKjNHZPE1VF45fHtD6nBDi5J/DkTHTwYP5X3kBJLa3xN7ub6J4eg==", + "dependencies": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/resources": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.13.0.tgz", + "integrity": "sha512-LMGqfSZkaMQXqewO0o1wvWr/2fQdCh4a3Sqlxka/UsJCe0cfLulh6x2aqnKLnsrSGiCq5rSCwvINd152i0nCqw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.22.0.tgz", + "integrity": "sha512-qBItJm9ygg/jCB5rmivyGz1qmKZPsL/sX715JqPMFgq++Idm0x+N9sLQvWFHFt2+ZINnCSojw7FVBgFW6izcXA==", + "dependencies": { + "@opentelemetry/core": "1.22.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.22.0.tgz", + "integrity": "sha512-pMLgst3QIwrUfepraH5WG7xfpJ8J3CrPKrtINK0t7kBkuu96rn+HDYQ8kt3+0FXvrZI8YJE77MCQwnJWXIrgpA==", + "dependencies": { + "@opentelemetry/core": "1.22.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.22.0.tgz", + "integrity": "sha512-+vNeIFPH2hfcNL0AJk/ykJXoUCtR1YaDUZM+p3wZNU4Hq98gzq+7b43xbkXjadD9VhWIUQqEwXyY64q6msPj6A==", + "dependencies": { + "@opentelemetry/core": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.39.1.tgz", + "integrity": "sha512-/gmgKfZ1ZVFporKuwsewqIyvaUIGpv76JZ7lBpHQQPb37IMpaXO6pdqFI4ebHAWfNIm3akMyhmdtzivcgF3lgw==", + "dependencies": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/resources": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.5.0", + "@opentelemetry/api-logs": ">=0.38.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/core": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.13.0.tgz", + "integrity": "sha512-2dBX3Sj99H96uwJKvc2w9NOiNgbvAO6mOFJFramNkKfS9O4Um+VWgpnlAazoYjT6kUJ1MP70KQ5ngD4ed+4NUw==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/resources": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.13.0.tgz", + "integrity": "sha512-euqjOkiN6xhjE//0vQYGvbStxoD/WWQRhDiO0OTLlnLBO9Yw2Gd/VoSx2H+svsebjzYk5OxLuREBmcdw6rbUNg==", + "dependencies": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.13.0.tgz", + "integrity": "sha512-LMGqfSZkaMQXqewO0o1wvWr/2fQdCh4a3Sqlxka/UsJCe0cfLulh6x2aqnKLnsrSGiCq5rSCwvINd152i0nCqw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.13.0.tgz", + "integrity": "sha512-MOjZX6AnSOqLliCcZUrb+DQKjAWXBiGeICGbHAGe5w0BB18PJIeIo995lO5JSaFfHpmUMgJButTPfJJD27W3Vg==", + "dependencies": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/resources": "1.13.0", + "lodash.merge": "4.6.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/core": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.13.0.tgz", + "integrity": "sha512-2dBX3Sj99H96uwJKvc2w9NOiNgbvAO6mOFJFramNkKfS9O4Um+VWgpnlAazoYjT6kUJ1MP70KQ5ngD4ed+4NUw==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/resources": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.13.0.tgz", + "integrity": "sha512-euqjOkiN6xhjE//0vQYGvbStxoD/WWQRhDiO0OTLlnLBO9Yw2Gd/VoSx2H+svsebjzYk5OxLuREBmcdw6rbUNg==", + "dependencies": { + "@opentelemetry/core": "1.13.0", + "@opentelemetry/semantic-conventions": "1.13.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.13.0.tgz", + "integrity": "sha512-LMGqfSZkaMQXqewO0o1wvWr/2fQdCh4a3Sqlxka/UsJCe0cfLulh6x2aqnKLnsrSGiCq5rSCwvINd152i0nCqw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.22.0.tgz", + "integrity": "sha512-pfTuSIpCKONC6vkTpv6VmACxD+P1woZf4q0K46nSUvXFvOFqjBYKFaAMkKD3M1mlKUUh0Oajwj35qNjMl80m1Q==", + "dependencies": { + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.22.0.tgz", + "integrity": "sha512-gTGquNz7ue8uMeiWPwp3CU321OstQ84r7PCDtOaCicjbJxzvO8RZMlEC4geOipTeiF88kss5n6w+//A0MhP1lQ==", + "dependencies": { + "@opentelemetry/context-async-hooks": "1.22.0", + "@opentelemetry/core": "1.22.0", + "@opentelemetry/propagator-b3": "1.22.0", + "@opentelemetry/propagator-jaeger": "1.22.0", + "@opentelemetry/sdk-trace-base": "1.22.0", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.22.0.tgz", + "integrity": "sha512-CAOgFOKLybd02uj/GhCdEeeBjOS0yeoDeo/CA7ASBSmenpZHAKGB3iDm/rv3BQLcabb/OprDEsSQ1y0P8A7Siw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@panva/hkdf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz", + "integrity": "sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@pdf-lib/standard-fonts": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", + "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", + "dependencies": { + "pako": "^1.0.6" + } + }, + "node_modules/@pdf-lib/upng": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz", + "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", + "dependencies": { + "pako": "^1.0.10" + } + }, + "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==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@radix-ui/number": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", + "integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/react-accessible-icon": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.0.3.tgz", + "integrity": "sha512-duVGKeWPSUILr/MdlPxV+GeULTc2rS1aihGdQ3N2qCUPMgxYLxvAsHJM3mCVLF8d5eK+ympmB22mb1F3a5biNw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-visually-hidden": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.1.2.tgz", + "integrity": "sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collapsible": "1.0.3", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.0.5.tgz", + "integrity": "sha512-OrVIOcZL0tl6xibeuGt5/+UxoT2N27KCFOPjFyfXMnchxSHZ/OW7cCX2nGlIYJrbHK/fczPcFzAwvNBB6XBNMA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dialog": "1.0.5", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz", + "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.0.3.tgz", + "integrity": "sha512-fXR5kbMan9oQqMuacfzlGG/SQMcmMlZ4wrvpckv8SgUulD0MMpspxJrxg/Gp/ISV3JfV1AeSWTYK9GvxA4ySwA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.0.4.tgz", + "integrity": "sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz", + "integrity": "sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz", + "integrity": "sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz", + "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context-menu": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.1.5.tgz", + "integrity": "sha512-R5XaDj06Xul1KGb+WP8qiOh7tKJNz2durpLBXAGZjSVtctcRFCuEvy2gtMwRJGePwQQE5nV77gs4FwRi8T+r2g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-menu": "2.0.6", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", + "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz", + "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", + "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz", + "integrity": "sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-menu": "2.0.6", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", + "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", + "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.0.7.tgz", + "integrity": "sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-icons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz", + "integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==", + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x" + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", + "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.0.2.tgz", + "integrity": "sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz", + "integrity": "sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menubar": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.0.4.tgz", + "integrity": "sha512-bHgUo9gayKZfaQcWSSLr++LyS0rgh+MvD89DE4fJ6TkGHvjHgPaBZf44hdka7ogOxIOdj9163J+5xL2Dn4qzzg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-menu": "2.0.6", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.4.tgz", + "integrity": "sha512-Cc+seCS3PmWmjI51ufGG7zp1cAAIRqHVw7C9LOA2TZ+R4hG6rDvHcTqIsEEFLmZO3zNVH72jOOE7kKNy8W+RtA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz", + "integrity": "sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz", + "integrity": "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-rect": "1.0.1", + "@radix-ui/react-use-size": "1.0.1", + "@radix-ui/rect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", + "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", + "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", + "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.0.3.tgz", + "integrity": "sha512-5G6Om/tYSxjSeEdrb1VfKkfZfn/1IlPWd731h2RfPuSbIfNUgfqAwbKfJCg/PP6nuUCTrYzalwHSpSinoWoCag==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz", + "integrity": "sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", + "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.5.tgz", + "integrity": "sha512-b6PAgH4GQf9QEn8zbT2XUHpW5z8BzqEc7Kl11TwDrvuTrxlkcjTD5qa/bxgKr+nmuXKu4L/W5UZ4mlP/VG/5Gw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.1", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.0.0.tgz", + "integrity": "sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.1", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.0.3.tgz", + "integrity": "sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.1.2.tgz", + "integrity": "sha512-NKs15MJylfzVsCagVSWKhGGLNR1W9qWs+HtgbmjjVUB3B9+lb3PYoXxVju3kOrpf0VKyVCtZp+iTwVoqpa1Chw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.1", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.0.3.tgz", + "integrity": "sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz", + "integrity": "sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toast": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.1.5.tgz", + "integrity": "sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz", + "integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz", + "integrity": "sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-toggle": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz", + "integrity": "sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", + "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz", + "integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/rect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz", + "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz", + "integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", + "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@resvg/resvg-wasm": { + "version": "2.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/@resvg/resvg-wasm/-/resvg-wasm-2.0.0-alpha.4.tgz", + "integrity": "sha512-pWIG9a/x1ky8gXKRhPH1OPKpHFoMN1ISLbJ+O+gPXQHIAKhNd5I28RlWf7q576hAOQA9JZTlo3p/M2uyLzJmmw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.1.tgz", + "integrity": "sha512-S3Kq8e7LqxkA9s7HKLqXGTGck1uwis5vAXan3FnU5yw1Ec5hsSGnq4s/UCaSqABPOnOTg7zASLyst7+ohgWexg==", + "dev": true + }, + "node_modules/@shuding/opentype.js": { + "version": "1.4.0-beta.0", + "resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz", + "integrity": "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==", + "dependencies": { + "fflate": "^0.7.3", + "string.prototype.codepointat": "^0.2.1" + }, + "bin": { + "ot": "bin/ot" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tanstack/react-table": { + "version": "8.15.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.15.3.tgz", + "integrity": "sha512-aocQ4WpWiAh7R+yxNp+DGQYXeVACh5lv2kk96DjYgFiHDCB0cOFoYMT/pM6eDOzeMXR9AvPoLeumTgq8/0qX+w==", + "dependencies": { + "@tanstack/table-core": "8.15.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.15.3", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.15.3.tgz", + "integrity": "sha512-wOgV0HfEvuMOv8RlqdR9MdNNqq0uyvQtP39QOvGlggHvIObOE4exS+D5LGO8LZ3LUXxId2IlUKcHDHaGujWhUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/extend": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.4.tgz", + "integrity": "sha512-ArMouDUTJEz1SQRpFsT2rIw7DeqICFv5aaVzLSIYMYQSLcwcGOfT3VyglQs/p7K3F7fT4zxr0NWxYZIdifD6dA==", + "dev": true + }, + "node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", + "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", + "dev": true + }, + "node_modules/@types/lodash.template": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/@types/lodash.template/-/lodash.template-4.5.3.tgz", + "integrity": "sha512-Mo0UYKLu1oXgkV9TVoXZLlXXjyIXlW7ZQRxi/4gQJmzJr63dmicE8gG0OkPjYTKBrBic852q0JzqrtNUWLBIyA==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.12.tgz", + "integrity": "sha512-H9VZ9YqE+H28FQVchC83RCs5xQ2J7mAAv6qdDEaWmXEVl3OpdH+xfrSUzQ1lp7U7oSTRZ0RvW08ASPJsYBi7Cw==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/mustache": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.2.5.tgz", + "integrity": "sha512-PLwiVvTBg59tGFL/8VpcGvqOu3L4OuveNvPi0EYbWchRdEVP++yRUXJPFl+CApKEq13017/4Nf7aQ5lTtHUNsA==" + }, + "node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "node_modules/@types/papaparse": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.14.tgz", + "integrity": "sha512-LxJ4iEFcpqc6METwp9f6BV6VVc43m6MfH0VqFosHvrUgfXiFe6ww7R3itkOQ+TCK6Y+Iv/+RnnvtRZnkc5Kc9g==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "devOptional": true + }, + "node_modules/@types/react": { + "version": "18.2.73", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.73.tgz", + "integrity": "sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA==", + "devOptional": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-color": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.12.tgz", + "integrity": "sha512-pr3uKE3lSvf7GFo1Rn2K3QktiZQFFrSgSGJ/3iMvSOYWt2pPAJ97rVdVfhWxYJZ8prAEXzoP2XX//3qGSQgu7Q==", + "dev": true, + "dependencies": { + "@types/react": "*", + "@types/reactcss": "*" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.23", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.23.tgz", + "integrity": "sha512-ZQ71wgGOTmDYpnav2knkjr3qXdAFu0vsk8Ci5w3pGAIdj7/kKAyn+VsQDhXsmzzzepAiI9leWMmubXz690AI/A==", + "devOptional": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-pdf": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/react-pdf/-/react-pdf-7.0.0.tgz", + "integrity": "sha512-G0a+5UiKk3AvEauBP/Js7r9kGZNW3iBbS6kXkH0foGSaKWR6K3ElTe7Y4tlolc2VKbM9udmMxpkbxh/dtR2wXA==", + "deprecated": "This is a stub types definition. react-pdf provides its own type definitions, so you do not need this installed.", + "dependencies": { + "react-pdf": "*" + } + }, + "node_modules/@types/reactcss": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.12.tgz", + "integrity": "sha512-BrXUQ86/wbbFiZv8h/Q1/Q1XOsaHneYmCb/tHe9+M8XBAAUc2EHfdY0DY22ZZjVSaXr5ix7j+zsqO2eGZub8lQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==" + }, + "node_modules/@types/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" + }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "node_modules/@types/yoga-layout": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.2.tgz", + "integrity": "sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==" + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vercel/analytics": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.2.2.tgz", + "integrity": "sha512-X0rctVWkQV1e5Y300ehVNqpOfSOufo7ieA5PIdna8yX/U7Vjz0GFsGf4qvAhxV02uQ2CVt7GYcrFfddXXK2Y4A==", + "dependencies": { + "server-only": "^0.0.1" + }, + "peerDependencies": { + "next": ">= 13", + "react": "^18 || ^19" + }, + "peerDependenciesMeta": { + "next": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@vercel/og": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/@vercel/og/-/og-0.0.21.tgz", + "integrity": "sha512-WgMahG5c8UM7xtn/mT+ljUpDMSDnSlu8AXL52JtTwxb1odrd0GWqZg2N1X38wulPj+sCccNpDdFmmAuw0GLc+Q==", + "dependencies": { + "@resvg/resvg-wasm": "2.0.0-alpha.4", + "satori": "0.0.44", + "yoga-wasm-web": "0.1.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "peer": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "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==", + "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==" + }, + "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==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/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==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "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==" + }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-timsort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, + "node_modules/babel-plugin-styled-components": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==" + }, + "node_modules/bare-events": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", + "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.2.tgz", + "integrity": "sha512-X9IqgvyB0/VA5OZJyb5ZstoN62AzD7YxVGog13kkfYWYqJYcK0kcqLZ6TrmH5qr4/8//ejVcX4x/a0UvaogXmA==", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-os": "^2.0.0", + "bare-path": "^2.0.0", + "streamx": "^2.13.0" + } + }, + "node_modules/bare-os": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.2.1.tgz", + "integrity": "sha512-OwPyHgBBMkhC29Hl3O4/YfxW9n7mdTr2+SsO29XBWKKJsbgj3mnorDB80r5TiCQgQstgE5ga1qNYrpes6NvX2w==", + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.0.tgz", + "integrity": "sha512-DIIg7ts8bdRKwJRJrUMy/PICEaQZaPGZ26lsSx9MJSwIhSrcdHn7/C8W+XmnG/rKi6BaRcz+JO00CjZteybDtw==", + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "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" + } + ] + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "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==", + "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==", + "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==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "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" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001600", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", + "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "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/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "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/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", + "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", + "dependencies": { + "clsx": "2.0.0" + }, + "funding": { + "url": "https://joebell.co.uk" + } + }, + "node_modules/class-variance-authority/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/clipanion": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-3.2.1.tgz", + "integrity": "sha512-dYFdjLb7y1ajfxQopN05mylEpK9ZX0sO1/RfMXdfmwjlIsPkbh4p7A682x++zFPLDCo1x3p82dtljHf5cW2LKA==", + "dependencies": { + "typanion": "^3.8.0" + }, + "peerDependencies": { + "typanion": "*" + } + }, + "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==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/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==" + }, + "node_modules/cliui/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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/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==", + "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/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cmdk": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-0.2.1.tgz", + "integrity": "sha512-U6//9lQ6JvT47+6OF6Gi8BvkxYQ8SCRRSKIJkthIMsFsLZRG0cKvTtuTaefyIKMQb8rvvXy0wGdpTNq/jPtm+g==", + "dependencies": { + "@radix-ui/react-dialog": "1.0.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-dialog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.0.tgz", + "integrity": "sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.0", + "@radix-ui/react-focus-guards": "1.0.0", + "@radix-ui/react-focus-scope": "1.0.0", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-portal": "1.0.0", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.0", + "@radix-ui/react-slot": "1.0.0", + "@radix-ui/react-use-controllable-state": "1.0.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.4" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz", + "integrity": "sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.0", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-escape-keydown": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", + "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.0.tgz", + "integrity": "sha512-C4SWtsULLGf/2L4oGeIHlvWQx7Rf+7cX/vKOAD2dXW0A1b5QXwi3wWeaEgW+wn+SEVrraMUk05vLU9fZZz5HbQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.0", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", + "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-portal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.0.tgz", + "integrity": "sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", + "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-slot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", + "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", + "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz", + "integrity": "sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/cmdk/node_modules/react-remove-scroll": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.4.tgz", + "integrity": "sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "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==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/comment-json": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz", + "integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==", + "dependencies": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.3", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, + "node_modules/contentlayer": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/contentlayer/-/contentlayer-0.3.4.tgz", + "integrity": "sha512-FYDdTUFaN4yqep0waswrhcXjmMJnPD5iXDTtxcUCGdklfuIrXM2xLx51xl748cHmGA6IsC+27YZFxU6Ym13QIA==", + "hasInstallScript": true, + "dependencies": { + "@contentlayer/cli": "0.3.4", + "@contentlayer/client": "0.3.4", + "@contentlayer/core": "0.3.4", + "@contentlayer/source-files": "0.3.4", + "@contentlayer/source-remote-files": "0.3.4", + "@contentlayer/utils": "0.3.4" + }, + "bin": { + "contentlayer": "bin/cli.cjs" + }, + "engines": { + "node": ">=14.18" + } + }, + "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==", + "peer": true + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "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==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-background-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz", + "integrity": "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==" + }, + "node_modules/css-box-shadow": { + "version": "1.0.0-3", + "resolved": "https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz", + "integrity": "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==" + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "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/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dingbat-to-unicode": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz", + "integrity": "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w==" + }, + "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==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/duck": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/duck/-/duck-0.1.12.tgz", + "integrity": "sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg==", + "dependencies": { + "underscore": "^1.13.1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.722", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.722.tgz", + "integrity": "sha512-5nLE0TWFFpZ80Crhtp4pIp8LXCztjYX41yUcV6b+bKR2PqzjskTMOOlBi1VjBHlvHwS+4gar7kNKOrsbsewEZQ==" + }, + "node_modules/embla-carousel": { + "version": "8.0.0-rc15", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.0.0-rc15.tgz", + "integrity": "sha512-s7VPexK2h8VEYjEVQFnJAPcRnY5YqJYicFxKVVyWXP3Hk9FFDkT0kqVxMM1PcL187qHOUgmGVHOrfC8xWy3OKQ==", + "peer": true + }, + "node_modules/embla-carousel-autoplay": { + "version": "8.0.0-rc15", + "resolved": "https://registry.npmjs.org/embla-carousel-autoplay/-/embla-carousel-autoplay-8.0.0-rc15.tgz", + "integrity": "sha512-ABTbDJGNb9jzI9OV2vSpbUvxUA0ELmK0SI3yPm8Haj3ghssS+vElfahoDqp7zuFkWBRih6w3B51oMPKdF5J55A==", + "peerDependencies": { + "embla-carousel": "8.0.0-rc15" + } + }, + "node_modules/embla-carousel-react": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.0.0.tgz", + "integrity": "sha512-qT0dii8ZwoCtEIBE6ogjqU2+5IwnGfdt2teKjCzW88JRErflhlCpz8KjWnW8xoRZOP8g0clRtsMEFoAgS/elfA==", + "dependencies": { + "embla-carousel": "8.0.0", + "embla-carousel-reactive-utils": "8.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.1 || ^18.0.0" + } + }, + "node_modules/embla-carousel-react/node_modules/embla-carousel": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.0.0.tgz", + "integrity": "sha512-ecixcyqS6oKD2nh5Nj5MObcgoSILWNI/GtBxkidn5ytFaCCmwVHo2SecksaQZHcARMMpIR2dWOlSIdA1LkZFUA==" + }, + "node_modules/embla-carousel-react/node_modules/embla-carousel-reactive-utils": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.0.0.tgz", + "integrity": "sha512-JCw0CqCXI7tbHDRogBb9PoeMLyjEC1vpN0lDOzUjmlfVgtfF+ffLaOK8bVtXVUEbNs/3guGe3NSzA5J5aYzLzw==", + "peerDependencies": { + "embla-carousel": "8.0.0" + } + }, + "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==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-abstract": { + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", + "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", + "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz", + "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==", + "peer": true + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.1.tgz", + "integrity": "sha512-OLyw2oHzwE0M0EODGYMbjksDQKSshQWBzYY+Nkoxoe3+Q5G0lpb9EkekyDk7Foz9BMfotbYShJrgYoBEAVqU4Q==", + "dev": true, + "dependencies": { + "@next/eslint-plugin-next": "14.1.1", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.34.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", + "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlast": "^1.2.4", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.17", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7", + "object.hasown": "^1.1.3", + "object.values": "^1.1.7", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.10" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz", + "integrity": "sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz", + "integrity": "sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz", + "integrity": "sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz", + "integrity": "sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-1.3.0.tgz", + "integrity": "sha512-Y+ughcF9jSUJvncXwqRageavjrNPAI+1M/L3BI3PyLp1nmgYTGUXU6t5z1Y7OWuThoDdhPME07bQU+d5LxdJqw==", + "dependencies": { + "is-plain-obj": "^3.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/estree-util-visit": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-1.2.1.tgz", + "integrity": "sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "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==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==" + }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fflate": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", + "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==" + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "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/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/framer-motion": { + "version": "11.0.24", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.0.24.tgz", + "integrity": "sha512-l2iM8NR53qtcujgAqYvGPJJGModPNWEVUaATRDLfnaLvUoFpImovBm0AHalSSsY8tW6knP8mfJTW4WYGbnAe4w==", + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "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==" + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "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==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/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==" + }, + "node_modules/gauge/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==" + }, + "node_modules/gauge/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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/geist": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/geist/-/geist-1.3.0.tgz", + "integrity": "sha512-IoGBfcqVEYB4bEwsfHd35jF4+X9LHRPYZymHL4YOltHSs9LJa24DYs1Z7rEMQ/lsEvaAIc61Y9aUxgcJaQ8lrg==", + "peerDependencies": { + "next": ">=13.2.0 <15.0.0-0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "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==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "dev": true + }, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "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==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "peer": true + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "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==", + "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==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", + "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==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "node_modules/hash-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hash-obj/-/hash-obj-4.0.0.tgz", + "integrity": "sha512-FwO1BUVWkyHasWDW4S8o0ssQXjvyghLV2rfVhnN36b2bbcj45eGiuzdn9XOvOpjV3TKQD7Gm2BWNXdE9V4KKYg==", + "dev": true, + "dependencies": { + "is-obj": "^3.0.0", + "sort-keys": "^5.0.0", + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hash-obj/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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hash-wasm": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.11.0.tgz", + "integrity": "sha512-HVusNXlVqHe0fzIzdQOGolnFN6mX/fqcrSAOcTBXdvzrXVHwTz11vXeKRmkR5gTuwVpvHZEIyKoePDvuAR+XwQ==" + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-has-property": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-2.0.1.tgz", + "integrity": "sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-heading-rank": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-2.1.1.tgz", + "integrity": "sha512-iAuRp+ESgJoRFJbSyaqsfvJDY6zzmFoEnL1gtz1+U8gKtGGj1p0CVlysuUAUjq95qlZESHINLThwJzNGmgGZxA==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz", + "integrity": "sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", + "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz", + "integrity": "sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "estree-util-attach-comments": "^2.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "mdast-util-mdx-expression": "^1.0.0", + "mdast-util-mdxjs-esm": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.1", + "unist-util-position": "^4.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", + "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-raw": "^7.0.0", + "hast-util-whitespace": "^2.0.0", + "html-void-elements": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", + "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz", + "integrity": "sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/html-void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", + "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "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" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/imagescript": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/imagescript/-/imagescript-1.3.0.tgz", + "integrity": "sha512-lCYzQrWzdnA68K03oMj/BUlBJrVBnslzDOgGFymAp49NmdGEJxGeN7sHh5mCva0nQkq+kkKSuru2zLf1m04+3A==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-2.0.1.tgz", + "integrity": "sha512-wzkZHqpb4eGrOKBl34xy3umnYHx8Si5R1U4fwmdxLo5gdH6mEK8gclckTj/qWqy4Je0bsDYe/qazZYuO7xe3XQ==", + "engines": { + "node": ">=14.0.0" + } + }, + "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==", + "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==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==", + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-3.0.0.tgz", + "integrity": "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jose": { + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/jotai": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.7.2.tgz", + "integrity": "sha512-6Ft5kpNu8p93Ssf1Faoza3hYQZRIYp7rioK8MwTTFnbQKwUyZElwquPwl1h6U0uo9hC0jr+ghO3gcSjc6P35/Q==", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=17.0.0", + "react": ">=17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "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==" + }, + "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==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbi": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-4.3.0.tgz", + "integrity": "sha512-SnZNcinB4RIcnEyZqFPdGPVgrg2AcnykiBy0sHVJQKHYeaLUvi3Exj+iaPpLnFVkDPZIV4U0yvgC9/R4uEAZ9g==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "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==" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.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==", + "dev": true, + "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==" + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, + "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==" + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lop": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.1.tgz", + "integrity": "sha512-9xyho9why2A2tzm5aIcMWKvzqKsnxrf9B5I+8O30olh6lQU8PH978LqZoI4++37RBgS1Em5i54v1TFs/3wnmXQ==", + "dependencies": { + "duck": "^0.1.12", + "option": "~0.2.1", + "underscore": "^1.13.1" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lucide-react": { + "version": "0.344.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.344.0.tgz", + "integrity": "sha512-6YyBnn91GB45VuVT96bYCOKElbJzUHqp65vX8cDcu55MQL9T969v4dhGClpljamuI/+KMO9P6w9Acq1CVQGvIQ==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/make-cancellable-promise": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/make-cancellable-promise/-/make-cancellable-promise-1.3.2.tgz", + "integrity": "sha512-GCXh3bq/WuMbS+Ky4JBPW1hYTOU+znU+Q5m9Pu+pI8EoUqIHk9+tviOKC6/qhHh8C4/As3tzJ69IF32kdz85ww==", + "funding": { + "url": "https://github.com/wojtekmaj/make-cancellable-promise?sponsor=1" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-event-props": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/make-event-props/-/make-event-props-1.6.2.tgz", + "integrity": "sha512-iDwf7mA03WPiR8QxvcVHmVWEPfMY1RZXerDVNCRYW7dUr2ppH3J58Rwb39/WG39yTZdRSxr3x+2v22tvI0VEvA==", + "funding": { + "url": "https://github.com/wojtekmaj/make-event-props?sponsor=1" + } + }, + "node_modules/mammoth": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/mammoth/-/mammoth-1.7.1.tgz", + "integrity": "sha512-ckxfvNH5sUaJh+SbYbxpvB7urZTGS02jA91rFCNiL928CgE9FXXMyXxcJBY0n+CpmKE/eWh7qaV0+v+Dbwun3Q==", + "dependencies": { + "@xmldom/xmldom": "^0.8.6", + "argparse": "~1.0.3", + "base64-js": "^1.5.1", + "bluebird": "~3.4.0", + "dingbat-to-unicode": "^1.0.1", + "jszip": "^3.7.1", + "lop": "^0.4.1", + "path-is-absolute": "^1.0.0", + "underscore": "^1.13.1", + "xmlbuilder": "^10.0.0" + }, + "bin": { + "mammoth": "bin/mammoth" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/mammoth/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/markdown-extensions": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", + "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/markdown-wasm": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/markdown-wasm/-/markdown-wasm-1.2.0.tgz", + "integrity": "sha512-S12OTkyXCkOgI1n1rZY9cg4bK/PGu80Emjpvwp8BEjwCxhPV3yddF0U6+QhCitdBsI1tzWcoeahmW7k0Pq81OA==" + }, + "node_modules/mdast-util-definitions": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", + "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", + "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-1.0.1.tgz", + "integrity": "sha512-JjA2OjxRqAa8wEG8hloD0uTU0kdn8kbtOWpPP94NBkfAlbxn4S8gCGf/9DwFtEeGPXrDcNXdiDjVaRdUFqYokw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0", + "micromark-extension-frontmatter": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz", + "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==", + "dev": true, + "dependencies": { + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-gfm-autolink-literal": "^1.0.0", + "mdast-util-gfm-footnote": "^1.0.0", + "mdast-util-gfm-strikethrough": "^1.0.0", + "mdast-util-gfm-table": "^1.0.0", + "mdast-util-gfm-task-list-item": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz", + "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "ccount": "^2.0.0", + "mdast-util-find-and-replace": "^2.0.0", + "micromark-util-character": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz", + "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0", + "micromark-util-normalize-identifier": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz", + "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz", + "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz", + "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz", + "integrity": "sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==", + "dependencies": { + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-mdx-expression": "^1.0.0", + "mdast-util-mdx-jsx": "^2.0.0", + "mdast-util-mdxjs-esm": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz", + "integrity": "sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz", + "integrity": "sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "ccount": "^2.0.0", + "mdast-util-from-markdown": "^1.1.0", + "mdast-util-to-markdown": "^1.3.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^4.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz", + "integrity": "sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", + "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-definitions": "^5.0.0", + "micromark-util-sanitize-uri": "^1.1.0", + "trim-lines": "^3.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", + "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "micromark-util-decode-string": "^1.0.0", + "unist-util-visit": "^4.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-toc": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-6.1.1.tgz", + "integrity": "sha512-Er21728Kow8hehecK2GZtb7Ny3omcoPUVrmObiSUwmoRYVZaXLR751QROEFjR8W/vAQdHMLj49Lz20J55XaNpw==", + "dev": true, + "dependencies": { + "@types/extend": "^3.0.0", + "@types/mdast": "^3.0.0", + "extend": "^3.0.0", + "github-slugger": "^2.0.0", + "mdast-util-to-string": "^3.1.0", + "unist-util-is": "^5.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdx-bundler": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/mdx-bundler/-/mdx-bundler-9.2.1.tgz", + "integrity": "sha512-hWEEip1KU9MCNqeH2rqwzAZ1pdqPPbfkx9OTJjADqGPQz4t9BO85fhI7AP9gVYrpmfArf9/xJZUN0yBErg/G/Q==", + "dependencies": { + "@babel/runtime": "^7.16.3", + "@esbuild-plugins/node-resolve": "^0.1.4", + "@fal-works/esbuild-plugin-global-externals": "^2.1.2", + "@mdx-js/esbuild": "^2.0.0", + "gray-matter": "^4.0.3", + "remark-frontmatter": "^4.0.1", + "remark-mdx-frontmatter": "^1.1.1", + "uuid": "^8.3.2", + "vfile": "^5.3.2" + }, + "engines": { + "node": ">=14", + "npm": ">=6" + }, + "peerDependencies": { + "esbuild": "0.*" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-class-names": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/merge-class-names/-/merge-class-names-1.4.2.tgz", + "integrity": "sha512-bOl98VzwCGi25Gcn3xKxnR5p/WrhWFQB59MS/aGENcmUc6iSm96yrFDF0XSNurX9qN4LbJm0R9kfvsQ17i8zCw==", + "funding": { + "url": "https://github.com/wojtekmaj/merge-class-names?sponsor=1" + } + }, + "node_modules/merge-refs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.2.2.tgz", + "integrity": "sha512-RwcT7GsQR3KbuLw1rRuodq4Nt547BKEBkliZ0qqsrpyNne9bGTFtsFIsIpx82huWhcl3kOlOlH4H0xkPk/DqVw==", + "funding": { + "url": "https://github.com/wojtekmaj/merge-refs?sponsor=1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "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==", + "peer": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-extension-frontmatter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-1.1.1.tgz", + "integrity": "sha512-m2UH9a7n3W8VAH9JO9y01APpPKmNNNs71P0RbknEmYSaZU5Ghogv38BYO94AI5Xw6OYfxZRdHZZ2nYjs/Z+SZQ==", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz", + "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==", + "dev": true, + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^1.0.0", + "micromark-extension-gfm-footnote": "^1.0.0", + "micromark-extension-gfm-strikethrough": "^1.0.0", + "micromark-extension-gfm-table": "^1.0.0", + "micromark-extension-gfm-tagfilter": "^1.0.0", + "micromark-extension-gfm-task-list-item": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz", + "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==", + "dev": true, + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz", + "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==", + "dev": true, + "dependencies": { + "micromark-core-commonmark": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz", + "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==", + "dev": true, + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz", + "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==", + "dev": true, + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz", + "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==", + "dev": true, + "dependencies": { + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz", + "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==", + "dev": true, + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz", + "integrity": "sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "micromark-factory-mdx-expression": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-events-to-acorn": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz", + "integrity": "sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "micromark-factory-mdx-expression": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz", + "integrity": "sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==", + "dependencies": { + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz", + "integrity": "sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^1.0.0", + "micromark-extension-mdx-jsx": "^1.0.0", + "micromark-extension-mdx-md": "^1.0.0", + "micromark-extension-mdxjs-esm": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz", + "integrity": "sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==", + "dependencies": { + "@types/estree": "^1.0.0", + "micromark-core-commonmark": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-events-to-acorn": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-position-from-estree": "^1.1.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz", + "integrity": "sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-events-to-acorn": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-position-from-estree": "^1.0.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz", + "integrity": "sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^2.0.0", + "estree-util-visit": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "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==", + "peer": true, + "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==", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "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==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nan": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", + "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "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==", + "peer": true + }, + "node_modules/next": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.0.tgz", + "integrity": "sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==", + "dependencies": { + "@next/env": "14.1.0", + "@swc/helpers": "0.5.2", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.1.0", + "@next/swc-darwin-x64": "14.1.0", + "@next/swc-linux-arm64-gnu": "14.1.0", + "@next/swc-linux-arm64-musl": "14.1.0", + "@next/swc-linux-x64-gnu": "14.1.0", + "@next/swc-linux-x64-musl": "14.1.0", + "@next/swc-win32-arm64-msvc": "14.1.0", + "@next/swc-win32-ia32-msvc": "14.1.0", + "@next/swc-win32-x64-msvc": "14.1.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-auth": { + "version": "4.24.7", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.7.tgz", + "integrity": "sha512-iChjE8ov/1K/z98gdKbn2Jw+2vLgJtVV39X+rCP5SGnVQuco7QOr19FRNGMIrD8d3LYhHWV9j9sKLzq1aDWWQQ==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@panva/hkdf": "^1.0.2", + "cookie": "^0.5.0", + "jose": "^4.15.5", + "oauth": "^0.9.15", + "openid-client": "^5.4.0", + "preact": "^10.6.3", + "preact-render-to-string": "^5.1.19", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "next": "^12.2.5 || ^13 || ^14", + "nodemailer": "^6.6.5", + "react": "^17.0.2 || ^18", + "react-dom": "^17.0.2 || ^18" + }, + "peerDependenciesMeta": { + "nodemailer": { + "optional": true + } + } + }, + "node_modules/next-themes": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz", + "integrity": "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==", + "peerDependencies": { + "next": "*", + "react": "*", + "react-dom": "*" + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "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" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-abi": { + "version": "3.56.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz", + "integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.hasown": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/oidc-token-hash": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", + "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==", + "engines": { + "node": "^10.13.0 || >=12.0.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==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/oo-ascii-tree": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.96.0.tgz", + "integrity": "sha512-Brydgf51AsjF2Ojp9myMm05DhYXaazQWNpyWKsP6OWgUI6zBeYDintk0vtoxq5Xu3GxtxRcxlIIzPURq/da86g==", + "engines": { + "node": ">= 14.17.0" + } + }, + "node_modules/openid-client": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.5.tgz", + "integrity": "sha512-5P4qO9nGJzB5PI0LFlhj4Dzg3m4odt0qsJTfyEtZyOlkgpILwEioOhVVJOrS1iVH494S4Ee5OCjjg6Bf5WOj3w==", + "dependencies": { + "jose": "^4.15.5", + "lru-cache": "^6.0.0", + "object-hash": "^2.2.0", + "oidc-token-hash": "^5.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/option": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/option/-/option-0.2.4.tgz", + "integrity": "sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A==" + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/papaparse": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", + "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw==" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", + "dev": true + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.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==", + "dev": true, + "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==", + "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==", + "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==" + }, + "node_modules/path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "engines": { + "node": "14 || >=16.14" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path2d": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.1.1.tgz", + "integrity": "sha512-/+S03c8AGsDYKKBtRDqieTJv2GlkMb0bWjnqOgtF6MkjdUQ9a8ARAtxWf9NgKLGm2+WQr6+/tqJdU8HNGsIDoA==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path2d-polyfill": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.1.1.tgz", + "integrity": "sha512-4Rka5lN+rY/p0CdD8+E+BFv51lFaFvJOrlOhyQ+zjzyQrzyh3ozmxd1vVGGDdIbUFSBtIZLSnspxTgPT0iJhvA==", + "optional": true, + "dependencies": { + "path2d": "0.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/pdf-lib": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", + "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==", + "dependencies": { + "@pdf-lib/standard-fonts": "^1.0.0", + "@pdf-lib/upng": "^1.0.1", + "pako": "^1.0.11", + "tslib": "^1.11.1" + } + }, + "node_modules/pdf-lib/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/pdfjs-dist": { + "version": "2.4.456", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.4.456.tgz", + "integrity": "sha512-yckJEHq3F48hcp6wStEpbN9McOj328Ib09UrBlGAKxvN2k+qYPN5iq6TH6jD1C0pso7zTep+g/CKsYgdrQd5QA==" + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "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" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/preact": { + "version": "10.20.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.20.1.tgz", + "integrity": "sha512-JIFjgFg9B2qnOoGiYMVBtrcFxHqn+dNXbq76bVmcaHYJFYR4lW67AOcXgAYQQTDYXDOg/kTZrKPNCdRgJ2UJmw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", + "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/prebuild-install/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prebuild-install/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prebuild-install/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==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prebuild-install/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" + }, + "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==" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", + "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-loader": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", + "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "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/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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-day-picker": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.0.tgz", + "integrity": "sha512-mz+qeyrOM7++1NCb1ARXmkjMkzWVh2GL9YiPbRjKe0zHccvekk4HE+0MPOZOrosn8r8zTHIIeOUXTmXRqmkRmg==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/gpbl" + }, + "peerDependencies": { + "date-fns": "^2.28.0 || ^3.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-doc-viewer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/react-doc-viewer/-/react-doc-viewer-0.1.5.tgz", + "integrity": "sha512-hLhjSlc0Ffe/PUjfgvEhM/SEgZ9ql1ujFYnkOMlJquBLj7iHlSM0cGAENXPbI2VK03+r92nM2Re+vT0Dwfyifg==", + "dependencies": { + "pdfjs-dist": "2.4.456", + "react-pdf": "5.0.0", + "styled-components": "^5.1.1", + "wl-msg-reader": "^0.2.0" + } + }, + "node_modules/react-doc-viewer/node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "node_modules/react-doc-viewer/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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/react-doc-viewer/node_modules/react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-doc-viewer/node_modules/react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + }, + "peerDependencies": { + "react": "^16.14.0" + } + }, + "node_modules/react-doc-viewer/node_modules/react-pdf": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-5.0.0.tgz", + "integrity": "sha512-VpqZjpZGEevmotLYl6acU6GYQeJ0dxn9+5sth5QjWLFhKu0xy3zSZgt3U3m97zW6UWzQ/scvw5drfPyun5l4eA==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "make-cancellable-promise": "^1.0.0", + "make-event-props": "^1.1.0", + "merge-class-names": "^1.1.1", + "pdfjs-dist": "2.4.456", + "prop-types": "^15.6.2", + "worker-loader": "^3.0.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-pdf?sponsor=1" + }, + "peerDependencies": { + "react": "^16.3.0", + "react-dom": "^16.3.0" + } + }, + "node_modules/react-doc-viewer/node_modules/scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/react-doc-viewer/node_modules/styled-components": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", + "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^1.1.0", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0", + "react-is": ">= 16.8.0" + } + }, + "node_modules/react-doc-viewer/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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-hook-form": { + "version": "7.51.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.2.tgz", + "integrity": "sha512-y++lwaWjtzDt/XNnyGDQy6goHskFualmDlf+jzEZvjvz6KWDf7EboL7pUvRCzPTJd0EOPpdekYaQLEvvG6m6HA==", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-pdf": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-7.7.1.tgz", + "integrity": "sha512-cbbf/PuRtGcPPw+HLhMI1f6NSka8OJgg+j/yPWTe95Owf0fK6gmVY7OXpTxMeh92O3T3K3EzfE0ML0eXPGwR5g==", + "dependencies": { + "clsx": "^2.0.0", + "dequal": "^2.0.3", + "make-cancellable-promise": "^1.3.1", + "make-event-props": "^1.6.0", + "merge-refs": "^1.2.1", + "pdfjs-dist": "3.11.174", + "prop-types": "^15.6.2", + "tiny-invariant": "^1.0.0", + "warning": "^4.0.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-pdf?sponsor=1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-pdf/node_modules/pdfjs-dist": { + "version": "3.11.174", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", + "integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==", + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "canvas": "^2.11.2", + "path2d-polyfill": "^2.0.1" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", + "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-resizable-panels": { + "version": "0.0.55", + "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-0.0.55.tgz", + "integrity": "sha512-J/LTFzUEjJiqwSjVh8gjUXkQDA8MRPjARASfn++d2+KOgA+9UcRYUfE3QBJixer2vkk+ffQ4cq3QzWzzHgqYpQ==", + "peerDependencies": { + "react": "^16.14.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-smooth": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz", + "integrity": "sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/react-wrap-balancer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/react-wrap-balancer/-/react-wrap-balancer-0.4.1.tgz", + "integrity": "sha512-KbIwnnCBCxj5u4yr76NXKKriM94VL33LtO9bE0sedCp4yqdGYJD8TGU+2zlPxkguH5xxKxdapBtMYdMAODk/QQ==", + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "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==", + "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/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recharts": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.3.tgz", + "integrity": "sha512-vE/F7wTlokf5mtCqVDJlVKelCjliLSJ+DJxj79XlMREm7gpV7ljwbrwE3CfeaoDlOaLX+6iwHaVRn9587YkwIg==", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^16.10.2", + "react-smooth": "^4.0.0", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rehype": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.1.tgz", + "integrity": "sha512-ey6kAqwLM3X6QnMDILJthGvG1m1ULROS9NT4uG9IDCuv08SFyLlreSuvOa//DgEvbXx62DS6elGVqusWhRUbgw==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0", + "rehype-parse": "^8.0.0", + "rehype-stringify": "^9.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-autolink-headings": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-6.1.1.tgz", + "integrity": "sha512-NMYzZIsHM3sA14nC5rAFuUPIOfg+DFmf9EY1YMhaNlB7+3kK/ZlE6kqPfuxr1tsJ1XWkTrMtMoyHosU70d35mA==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0", + "extend": "^3.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-heading-rank": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.5.tgz", + "integrity": "sha512-Ds3RglaY/+clEX2U2mHflt7NlMA72KspZ0JLUJgBBLpRddBcEw3H8uYZQliQriku22NZpYMfjDdSgHcjxue24A==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-from-parse5": "^7.0.0", + "parse5": "^6.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-pretty-code": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.6.0.tgz", + "integrity": "sha512-VfntYoWYOBVURXYDdB8p/E1sZTm2W5ry89fJyY94WJAo1jUH/5sVhDC7cX5PPnksMyW9PYMxRLNfjkBpSgJrzQ==", + "dev": true, + "dependencies": { + "hash-obj": "^4.0.0", + "nanoid": "^4.0.0", + "parse-numeric-range": "^1.3.0" + }, + "engines": { + "node": "^12.16.0 || >=13.2.0" + }, + "peerDependencies": { + "shiki": "*" + } + }, + "node_modules/rehype-pretty-code/node_modules/nanoid": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz", + "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^14 || ^16 || >=18" + } + }, + "node_modules/rehype-slug": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-5.1.0.tgz", + "integrity": "sha512-Gf91dJoXneiorNEnn+Phx97CO7oRMrpi+6r155tTxzGuLtm+QrI4cTwCa9e1rtePdL4i9tSO58PeSS6HWfgsiw==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0", + "github-slugger": "^2.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-heading-rank": "^2.0.0", + "hast-util-to-string": "^2.0.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-9.0.4.tgz", + "integrity": "sha512-Uk5xu1YKdqobe5XpSskwPvo1XeHUUucWEQSl8hTrXt5selvca1e8K1EZ37E6YoZ4BT8BCqCdVfQW7OfHfthtVQ==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-to-html": "^8.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.3.tgz", + "integrity": "sha512-bfmJW1dmR2LvaMJuAnE88pZP9DktIFYXazkTfOIKZzi3Knk9lT0roItIA24ydOucI3bV/g/tXBA6hzqq3FV9Ew==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "remark-parse": "^10.0.0", + "remark-stringify": "^10.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-code-import": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remark-code-import/-/remark-code-import-1.2.0.tgz", + "integrity": "sha512-fgwLruqlZbVOIhCJFjY+JDwPZhA4/eK3InJzN8Ox8UDdtudpG212JwtRj6la+lAzJU7JmSEyewZSukVZdknt3Q==", + "dev": true, + "dependencies": { + "strip-indent": "^4.0.0", + "to-gatsby-remark-plugin": "^0.1.0", + "unist-util-visit": "^4.1.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/remark-frontmatter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-4.0.1.tgz", + "integrity": "sha512-38fJrB0KnmD3E33a5jZC/5+gGAC2WKNiPw1/fdXJvijBlhA7RCsvJklrYJakS0HedninvaCYW8lQGf9C918GfA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-frontmatter": "^1.0.0", + "micromark-extension-frontmatter": "^1.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", + "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-gfm": "^2.0.0", + "micromark-extension-gfm": "^2.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz", + "integrity": "sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==", + "dependencies": { + "mdast-util-mdx": "^2.0.0", + "micromark-extension-mdxjs": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx-frontmatter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/remark-mdx-frontmatter/-/remark-mdx-frontmatter-1.1.1.tgz", + "integrity": "sha512-7teX9DW4tI2WZkXS4DBxneYSY7NHiXl4AKdWDO9LXVweULlCT8OPWsOjLEnMIXViN1j+QcY8mfbq3k0EK6x3uA==", + "dependencies": { + "estree-util-is-identifier-name": "^1.0.0", + "estree-util-value-to-estree": "^1.0.0", + "js-yaml": "^4.0.0", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=12.2.0" + } + }, + "node_modules/remark-mdx-frontmatter/node_modules/estree-util-is-identifier-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-1.1.0.tgz", + "integrity": "sha512-OVJZ3fGGt9By77Ix9NhaRbzfbDV/2rx9EP7YIDJTmsZSEc5kYn2vWcNccYyahJL2uAQZK2a5Or2i0wtIKTPoRQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-parse": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", + "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", + "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-to-hast": "^12.1.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.3.tgz", + "integrity": "sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "engines": { + "node": ">=0.10" + } + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "dev": true, + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "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==" + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/satori": { + "version": "0.0.44", + "resolved": "https://registry.npmjs.org/satori/-/satori-0.0.44.tgz", + "integrity": "sha512-WKUxXC2qeyno6J3ucwwLozPL6j1HXOZiN5wIUf7iqAhlx1RUC/6ePIKHi7iPc3Cy6DYuZcJriZXxXkSdo2FQHg==", + "dependencies": { + "@shuding/opentype.js": "1.4.0-beta.0", + "css-background-parser": "^0.1.0", + "css-box-shadow": "1.0.0-3", + "css-to-react-native": "^3.0.0", + "emoji-regex": "^10.2.1", + "postcss-value-parser": "^4.2.0", + "yoga-layout-prebuilt": "^1.10.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/satori/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/server-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz", + "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==" + }, + "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==" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/sharp/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sharp/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sharp/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "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==", + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.12.1.tgz", + "integrity": "sha512-aieaV1m349rZINEBkjxh2QbBvFFQOlgqYTNtCal82hHj4dDZ76oMlQIX+C7ryerBTDiga3e5NfH6smjdJ02BbQ==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sonner": { + "version": "1.4.41", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.4.41.tgz", + "integrity": "sha512-uG511ggnnsw6gcn/X+YKkWPo5ep9il9wYi3QJxHsYe7yTZ4+cOd1wuodOUmOpFuXL+/RE3R04LczdNCDygTDgQ==", + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/sort-keys": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.0.0.tgz", + "integrity": "sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==", + "dev": true, + "dependencies": { + "is-plain-obj": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sort-keys/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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/streamx": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + }, + "optionalDependencies": { + "bare-events": "^2.2.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==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "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==", + "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/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==", + "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/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==" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.codepointat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", + "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==", + "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==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/styled-components": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.8.tgz", + "integrity": "sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==", + "dependencies": { + "@emotion/is-prop-valid": "1.2.1", + "@emotion/unitless": "0.8.0", + "@types/stylis": "4.2.0", + "css-to-react-native": "3.2.0", + "csstype": "3.1.2", + "postcss": "8.4.31", + "shallowequal": "1.1.0", + "stylis": "4.3.1", + "tslib": "2.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "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" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/stylis": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + }, + "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==", + "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/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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.2.tgz", + "integrity": "sha512-tWANXsnmJzgw6mQ07nE3aCDkCK4QdT3ThPMCzawoYA2Pws7vSTCvz3Vrjg61jVUGfFZPJzxEP+NimbcW+EdaDw==", + "dependencies": { + "@babel/runtime": "^7.24.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", + "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tailwindcss/node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "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/tar-fs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", + "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/terser": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.0.tgz", + "integrity": "sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw==", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/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==", + "peer": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "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==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-gatsby-remark-plugin": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/to-gatsby-remark-plugin/-/to-gatsby-remark-plugin-0.1.0.tgz", + "integrity": "sha512-blmhJ/gIrytWnWLgPSRCkhCPeki6UBK2daa3k9mGahN7GjwHu8KrS7F70MvwlsG7IE794JLgwAdCbi4hU4faFQ==", + "dev": true, + "dependencies": { + "to-vfile": "^6.1.0" + } + }, + "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==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-vfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-6.1.0.tgz", + "integrity": "sha512-BxX8EkCxOAZe+D/ToHdDsJcVI4HqQfmw0tCkp31zf3dNP/XWIAjU4CmeuSwsSoOzOTqHPOL0KUzyZqJplkD0Qw==", + "dev": true, + "dependencies": { + "is-buffer": "^2.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/to-vfile/node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/to-vfile/node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/to-vfile/node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.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==" + }, + "node_modules/ts-pattern": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-4.3.0.tgz", + "integrity": "sha512-pefrkcd4lmIVR0LA49Imjf9DYLK8vtWhqBPA3Ya1ir8xCW0O2yjL9dsCVvI7pCodLC5q7smNpEtDR2yVulQxOg==" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "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==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/typanion": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz", + "integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/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==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-builder": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-3.0.0.tgz", + "integrity": "sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-generated": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", + "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", + "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz", + "integrity": "sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz", + "integrity": "sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", + "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "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==" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vaul": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vaul/-/vaul-0.2.3.tgz", + "integrity": "sha512-BEMMkCAQ3ZQ3O2sgwnu7IuD3scBd7sVVr3IN57QpF1NjX+mjSaW2Rn76Dm98eEz3tXiukqRcVAiKE6F4tYwgCA==", + "dependencies": { + "@radix-ui/react-dialog": "^1.0.4" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/vfile": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", + "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", + "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "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==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/webpack": { + "version": "5.91.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", + "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.16.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wide-align/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==" + }, + "node_modules/wide-align/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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wl-msg-reader": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/wl-msg-reader/-/wl-msg-reader-0.2.1.tgz", + "integrity": "sha512-PFK8vjdaGUmj0EqBKL/ECSeSgxI/QBy2njuxX+UaCKjDaN6H0UYVLmmizmMJsrzkQ9QmDvsJiSE0H1o7wY4Zfg==" + }, + "node_modules/worker-loader": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz", + "integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "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==", + "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/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==", + "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/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==" + }, + "node_modules/wrap-ansi-cjs/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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/xmlbuilder": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz", + "integrity": "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "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==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/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==" + }, + "node_modules/yargs/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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoga-layout-prebuilt": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.10.0.tgz", + "integrity": "sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==", + "dependencies": { + "@types/yoga-layout": "1.9.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yoga-wasm-web": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yoga-wasm-web/-/yoga-wasm-web-0.1.2.tgz", + "integrity": "sha512-8SkgawHcA0RUbMrnhxbaQkZDBi8rMed8pQHixkFF9w32zGhAwZ9/cOHWlpYfr6RCx42Yp3siV45/jPEkJxsk6w==" + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/3 - PB/MVP/src/frontend/package.json b/3 - PB/MVP/src/frontend/package.json new file mode 100644 index 00000000..8063b999 --- /dev/null +++ b/3 - PB/MVP/src/frontend/package.json @@ -0,0 +1,109 @@ +{ + "name": "kmai", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@cyntler/react-doc-viewer": "^1.14.1", + "@hookform/resolvers": "^3.3.4", + "@radix-ui/react-accessible-icon": "^1.0.3", + "@radix-ui/react-accordion": "^1.1.2", + "@radix-ui/react-alert-dialog": "^1.0.5", + "@radix-ui/react-aspect-ratio": "^1.0.3", + "@radix-ui/react-avatar": "^1.0.3", + "@radix-ui/react-checkbox": "^1.0.4", + "@radix-ui/react-collapsible": "^1.0.3", + "@radix-ui/react-context-menu": "^2.1.5", + "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-dropdown-menu": "^2.0.5", + "@radix-ui/react-hover-card": "^1.0.7", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-menubar": "^1.0.4", + "@radix-ui/react-navigation-menu": "^1.1.3", + "@radix-ui/react-popover": "^1.0.6", + "@radix-ui/react-progress": "^1.0.3", + "@radix-ui/react-radio-group": "^1.1.3", + "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.0.3", + "@radix-ui/react-slider": "^1.1.2", + "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-switch": "^1.0.3", + "@radix-ui/react-tabs": "^1.0.4", + "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-toggle": "^1.0.3", + "@radix-ui/react-toggle-group": "^1.0.4", + "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-table": "^8.9.1", + "@types/react-pdf": "^7.0.0", + "@vercel/analytics": "^1.0.1", + "@vercel/og": "^0.0.21", + "canvas": "^2.11.2", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.0", + "cmdk": "^0.2.1", + "contentlayer": "0.3.4", + "date-fns": "^3.6.0", + "embla-carousel-autoplay": "8.0.0-rc15", + "embla-carousel-react": "^8.0.0-rc15", + "framer-motion": "^11.0.14", + "geist": "^1.1.0", + "jotai": "^2.7.1", + "lodash.template": "^4.5.0", + "lucide-react": "^0.344.0", + "mammoth": "^1.7.1", + "markdown-wasm": "^1.2.0", + "next": "14.1.0", + "next-auth": "^4.24.7", + "next-themes": "^0.2.1", + "pdf-lib": "^1.17.1", + "pretty-bytes": "^6.1.1", + "react": "^18", + "react-day-picker": "^8.10.0", + "react-doc-viewer": "^0.1.5", + "react-dom": "^18", + "react-hook-form": "^7.51.0", + "react-resizable-panels": "^0.0.55", + "react-wrap-balancer": "^0.4.1", + "recharts": "^2.6.2", + "sharp": "^0.32.6", + "sonner": "^1.4.41", + "tailwind-merge": "^2.2.1", + "tailwindcss-animate": "^1.0.7", + "vaul": "^0.2.3", + "zod": "^3.22.4" + }, + "devDependencies": { + "@types/lodash.template": "^4.5.1", + "@types/node": "^17.0.45", + "@types/react": "^18.2.7", + "@types/react-color": "^3.0.6", + "@types/react-dom": "^18.2.4", + "autoprefixer": "^10.0.1", + "eslint": "^8", + "eslint-config-next": "14.1.1", + "file-loader": "^6.2.0", + "mdast-util-toc": "^6.1.1", + "postcss": "^8", + "raw-loader": "^4.0.2", + "rehype": "^12.0.1", + "rehype-autolink-headings": "^6.1.1", + "rehype-pretty-code": "^0.6.0", + "rehype-slug": "^5.1.0", + "remark": "^14.0.3", + "remark-code-import": "^1.2.0", + "remark-gfm": "^3.0.1", + "rimraf": "^4.1.3", + "shiki": "^0.12.1", + "tailwindcss": "^3.3.0", + "typescript": "^5", + "unist-builder": "3.0.0", + "unist-util-visit": "^4.1.2" + } +} diff --git a/3 - PB/MVP/src/frontend/postcss.config.js b/3 - PB/MVP/src/frontend/postcss.config.js new file mode 100644 index 00000000..12a703d9 --- /dev/null +++ b/3 - PB/MVP/src/frontend/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/3 - PB/MVP/src/frontend/public/sweetcode-logo.svg b/3 - PB/MVP/src/frontend/public/sweetcode-logo.svg new file mode 100644 index 00000000..f8a0a032 --- /dev/null +++ b/3 - PB/MVP/src/frontend/public/sweetcode-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/3 - PB/MVP/src/frontend/src/app/chatbot/[chatId]/page.tsx b/3 - PB/MVP/src/frontend/src/app/chatbot/[chatId]/page.tsx new file mode 100644 index 00000000..fce9178a --- /dev/null +++ b/3 - PB/MVP/src/frontend/src/app/chatbot/[chatId]/page.tsx @@ -0,0 +1,9 @@ +import Chatbot from "../components/chatbot"; + +export default async function ChatPage({ params }: { params: { chatId: number } }) { + return ( +
+ +
+ ) +} diff --git a/3 - PB/MVP/src/frontend/src/app/chatbot/components/chat-content.tsx b/3 - PB/MVP/src/frontend/src/app/chatbot/components/chat-content.tsx new file mode 100644 index 00000000..b11f28c7 --- /dev/null +++ b/3 - PB/MVP/src/frontend/src/app/chatbot/components/chat-content.tsx @@ -0,0 +1,42 @@ +"use client" +import * as React from "react" + +import { Message } from "@/types/types" +import { MessageCard } from "./message-card"; +import { useEffect, useRef } from 'react'; + +interface ChatContentProps { + messages?: Message[]; +} + +export function ChatContent({ messages }: ChatContentProps) { + const messagesEndRef = useRef(null); + + const scrollToBottom = () => { + messagesEndRef.current?.scrollIntoView({ block: "end", behavior: "smooth" }); + }; + + useEffect(() => { + scrollToBottom() + }, [messages]); + + return ( + <> +
+ { + messages===undefined || messages?.length === 0 ? +
+ No messages yet. +
+ : + messages?.map((message, index) => ( + + )) + } +
+
+ + ) +} + + diff --git a/3 - PB/MVP/src/frontend/src/app/chatbot/components/chat-footer.tsx b/3 - PB/MVP/src/frontend/src/app/chatbot/components/chat-footer.tsx new file mode 100644 index 00000000..d90df7e9 --- /dev/null +++ b/3 - PB/MVP/src/frontend/src/app/chatbot/components/chat-footer.tsx @@ -0,0 +1,254 @@ +"use client" + +import { Button } from "@/components/ui/button"; +import { Form, FormField, FormItem } from "@/components/ui/form"; +import { Separator } from "@/components/ui/separator"; +import { Textarea } from "@/components/ui/textarea"; +import { Toggle } from "@/components/ui/toggle"; +import { askChatbot } from "@/lib/actions"; +import { AskChatbotFormValues, MessageResponse, askChatbotFormSchema } from "@/types/types"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { EraserIcon, MicIcon, PauseIcon, PlayIcon, SendIcon, StopCircleIcon } from "lucide-react"; +import { useRouter } from "next/navigation"; +import { useEffect, useRef, useState } from "react"; +import { SubmitHandler, useForm } from "react-hook-form"; +import { toast } from "sonner"; + +interface ChatFooterProps { + chatId?: number +} + +export default function ChatFooter({ chatId }: ChatFooterProps) { + const [isRecording, setIsRecording] = useState(false) + const [isPaused, setIsPaused] = useState(false) + const recognitionRef = useRef(null) + + const [isSpeechRecognitionSupported, setIsSpeechRecognitionSupported] = useState(false) + + const router = useRouter() + + const form = useForm({ + resolver: zodResolver(askChatbotFormSchema), + defaultValues: { + message: "" + }, + mode: "onChange", + }) + + const watchMessage = form.watch("message") + + const onSubmit: SubmitHandler = async (data) => { + setIsRecording(false) + setIsPaused(false) + + if (chatId !== undefined) { + data.chatId = chatId + } + + const toastId = toast.loading("Loading...", { + description: "Sending message.", + }) + + let result: MessageResponse + try { + result = await askChatbot(data) + } catch (e) { + toast.error("An error occurred", { + description: "Please try again later.", + id: toastId + }) + return + } + + if (!result || !result.status) { + toast.error("An error occurred", { + description: "Please try again later.", + id: toastId + }) + return + } + + toast.dismiss(toastId) + + if (chatId === undefined) + router.push(`/chatbot/${result.chatId}`) + form.reset({ message: "" }) + } + + useEffect(() => { + if (("webkitSpeechRecognition" in window)) { + return + } + setIsSpeechRecognitionSupported(true) + + recognitionRef.current = new (window as any).webkitSpeechRecognition() + const recognition = recognitionRef.current; + recognition.continuous = true; + recognition.interimResults = true; + recognition.lang = "it-IT"; + + recognition.onresult = (event: any) => { + console.log("onresult") + let interTranscript = ''; + for (let i = event.resultIndex; i < event.results.length; i++) { + const transcript = event.results[i][0].transcript; + if (event.results[i].isFinal) { + if (isRecording) { + form.setValue("message", transcript.trim()); + } + else { + const prevInput = form.getValues().message; + const trimmedPrevInput = prevInput ? prevInput.trim() : ''; + const trimmedTranscript = transcript.trim(); + form.setValue("message", trimmedPrevInput ? trimmedPrevInput + ' ' + trimmedTranscript : trimmedTranscript) + } + } + else { + interTranscript += transcript; + } + console.log(interTranscript) + } + } + + recognition.onend = () => { + console.log("onend") + pauseRecording() + } + + recognition.onerror = () => { + console.log("onerror") + pauseRecording() + } + + return () => { + if (recognition) { + recognition.stop() + } + } + }, []) + + const startRecording = () => { + console.log("startRecording") + if (recognitionRef.current) { + recognitionRef.current.start() + } + setIsRecording(true) + setIsPaused(false) + } + + const stopRecording = () => { + console.log("stopRecording") + if (recognitionRef.current) { + recognitionRef.current.stop(); + } + setIsRecording(false) + setIsPaused(false) + } + + const pauseRecording = () => { + console.log("pauseRecording") + if (recognitionRef.current) { + recognitionRef.current.stop(); + } + setIsPaused(true) + } + + const resumeRecording = () => { + console.log("resumeRecording") + if (recognitionRef.current) { + recognitionRef.current.start(); + } + setIsPaused(false) + } + + return ( +
+ + +
+ { + !isSpeechRecognitionSupported && ( +
+ + { + isRecording ? ( + { + e.preventDefault() + if (isPaused) { + resumeRecording(); + } else { + pauseRecording(); + } + } + } + > + {isPaused ? : } + + ) : null + } +
+ ) + } + ( + +