From f7d76eea1eba83d9508d1e8e8c5bcb6bbae68129 Mon Sep 17 00:00:00 2001 From: swve Date: Sat, 30 Dec 2023 16:48:57 +0000 Subject: [PATCH 01/18] feat: init ai activity chat session --- apps/api/config/config.py | 27 ++++++ apps/api/requirements.txt | 8 +- apps/api/src/db/courses.py | 2 +- apps/api/src/router.py | 12 +-- apps/api/src/routers/ai/ai.py | 25 ++++++ apps/api/src/services/ai/ai.py | 65 +++++++++++++++ apps/api/src/services/ai/base.py | 82 +++++++++++++++++++ apps/api/src/services/ai/schemas/ai.py | 12 +++ .../src/services/courses/activities/utils.py | 78 ++++++++++++++++++ apps/api/src/services/users/users.py | 2 +- 10 files changed, 305 insertions(+), 8 deletions(-) create mode 100644 apps/api/src/routers/ai/ai.py create mode 100644 apps/api/src/services/ai/ai.py create mode 100644 apps/api/src/services/ai/base.py create mode 100644 apps/api/src/services/ai/schemas/ai.py create mode 100644 apps/api/src/services/courses/activities/utils.py diff --git a/apps/api/config/config.py b/apps/api/config/config.py index 30d579a8..d23d5ada 100644 --- a/apps/api/config/config.py +++ b/apps/api/config/config.py @@ -1,6 +1,7 @@ from typing import Literal, Optional from pydantic import BaseModel import os +from dotenv import load_dotenv import yaml @@ -23,6 +24,11 @@ class SecurityConfig(BaseModel): auth_jwt_secret_key: str +class AIConfig(BaseModel): + openai_api_key: str | None + is_ai_enabled: bool | None + + class S3ApiConfig(BaseModel): bucket_name: str | None endpoint_url: str | None @@ -58,9 +64,13 @@ class LearnHouseConfig(BaseModel): hosting_config: HostingConfig database_config: DatabaseConfig security_config: SecurityConfig + ai_config: AIConfig def get_learnhouse_config() -> LearnHouseConfig: + + load_dotenv() + # Get the YAML file yaml_path = os.path.join(os.path.dirname(__file__), "config.yaml") @@ -173,6 +183,16 @@ def get_learnhouse_config() -> LearnHouseConfig: "mongo_connection_string" ) + # AI Config + env_openai_api_key = os.environ.get("LEARNHOUSE_OPENAI_API_KEY") + env_is_ai_enabled = os.environ.get("LEARNHOUSE_IS_AI_ENABLED") + openai_api_key = env_openai_api_key or yaml_config.get("ai_config", {}).get( + "openai_api_key" + ) + is_ai_enabled = env_is_ai_enabled or yaml_config.get("ai_config", {}).get( + "is_ai_enabled" + ) + # Sentry config # check if the sentry config is provided in the YAML file sentry_config_verif = ( @@ -217,6 +237,12 @@ def get_learnhouse_config() -> LearnHouseConfig: mongo_connection_string=mongo_connection_string, ) + # AI Config + ai_config = AIConfig( + openai_api_key=openai_api_key, + is_ai_enabled=bool(is_ai_enabled), + ) + # Create LearnHouseConfig object config = LearnHouseConfig( site_name=site_name, @@ -228,6 +254,7 @@ def get_learnhouse_config() -> LearnHouseConfig: hosting_config=hosting_config, database_config=database_config, security_config=SecurityConfig(auth_jwt_secret_key=auth_jwt_secret_key), + ai_config=ai_config, ) return config diff --git a/apps/api/requirements.txt b/apps/api/requirements.txt index 72b85d35..0d25add8 100644 --- a/apps/api/requirements.txt +++ b/apps/api/requirements.txt @@ -17,4 +17,10 @@ faker requests pyyaml sentry-sdk[fastapi] -pydantic[email]>=1.8.0,<2.0.0 \ No newline at end of file +pydantic[email]>=1.8.0,<2.0.0 +langchain +tiktoken +openai +chromadb +sentence-transformers +python-dotenv diff --git a/apps/api/src/db/courses.py b/apps/api/src/db/courses.py index fade9b48..7623aa1f 100644 --- a/apps/api/src/db/courses.py +++ b/apps/api/src/db/courses.py @@ -40,7 +40,7 @@ class CourseUpdate(CourseBase): class CourseRead(CourseBase): id: int org_id: int = Field(default=None, foreign_key="organization.id") - authors: List[UserRead] + authors: Optional[List[UserRead]] course_uuid: str creation_date: str update_date: str diff --git a/apps/api/src/router.py b/apps/api/src/router.py index 6931d66b..2908d7ae 100644 --- a/apps/api/src/router.py +++ b/apps/api/src/router.py @@ -1,5 +1,6 @@ from fastapi import APIRouter, Depends from src.routers import blocks, dev, trail, users, auth, orgs, roles +from src.routers.ai import ai from src.routers.courses import chapters, collections, courses, activities from src.routers.install import install from src.services.dev.dev import isDevModeEnabledOrRaise @@ -18,14 +19,16 @@ v1_router.include_router(blocks.router, prefix="/blocks", tags=["blocks"]) v1_router.include_router(courses.router, prefix="/courses", tags=["courses"]) v1_router.include_router(chapters.router, prefix="/chapters", tags=["chapters"]) v1_router.include_router(activities.router, prefix="/activities", tags=["activities"]) -v1_router.include_router( - collections.router, prefix="/collections", tags=["collections"] -) +v1_router.include_router(collections.router, prefix="/collections", tags=["collections"]) v1_router.include_router(trail.router, prefix="/trail", tags=["trail"]) +v1_router.include_router(ai.router, prefix="/ai", tags=["ai"]) # Dev Routes v1_router.include_router( - dev.router, prefix="/dev", tags=["dev"], dependencies=[Depends(isDevModeEnabledOrRaise)] + dev.router, + prefix="/dev", + tags=["dev"], + dependencies=[Depends(isDevModeEnabledOrRaise)], ) # Install Routes @@ -35,4 +38,3 @@ v1_router.include_router( tags=["install"], dependencies=[Depends(isInstallModeEnabled)], ) - diff --git a/apps/api/src/routers/ai/ai.py b/apps/api/src/routers/ai/ai.py new file mode 100644 index 00000000..a48626d0 --- /dev/null +++ b/apps/api/src/routers/ai/ai.py @@ -0,0 +1,25 @@ +from fastapi import APIRouter, Depends, Request +from sqlmodel import Session +from src.services.ai.ai import ai_start_activity_chat_session +from src.services.ai.schemas.ai import StartActivityAIChatSession +from src.core.events.database import get_db_session +from src.db.users import PublicUser +from src.security.auth import get_current_user + + +router = APIRouter() + + +@router.post("/start/activity_chat_session") +async def api_ai_start_activity_chat_session( + request: Request, + chat_session_object: StartActivityAIChatSession, + current_user: PublicUser = Depends(get_current_user), + db_session: Session = Depends(get_db_session), +): + """ + Start a new AI Chat session with a Course Activity + """ + return ai_start_activity_chat_session( + request, chat_session_object, current_user, db_session + ) diff --git a/apps/api/src/services/ai/ai.py b/apps/api/src/services/ai/ai.py new file mode 100644 index 00000000..058598b0 --- /dev/null +++ b/apps/api/src/services/ai/ai.py @@ -0,0 +1,65 @@ +from fastapi import Depends, HTTPException, Request +from sqlmodel import Session, select +from src.db.courses import Course, CourseRead +from src.core.events.database import get_db_session +from src.db.users import PublicUser +from src.db.activities import Activity, ActivityRead +from src.security.auth import get_current_user +from src.services.ai.base import ask_ai + +from src.services.ai.schemas.ai import StartActivityAIChatSession +from src.services.courses.activities.utils import ( + serialize_activity_text_to_ai_comprehensible_text, + structure_activity_content_by_type, +) + + +def ai_start_activity_chat_session( + request: Request, + chat_session_object: StartActivityAIChatSession, + current_user: PublicUser = Depends(get_current_user), + db_session: Session = Depends(get_db_session), +): + """ + Start a new AI Chat session with a Course Activity + """ + # Get the Activity + statement = select(Activity).where( + Activity.activity_uuid == chat_session_object.activity_uuid + ) + activity = db_session.exec(statement).first() + + activity = ActivityRead.from_orm(activity) + + # Get the Course + statement = select(Course).join(Activity).where( + Activity.activity_uuid == chat_session_object.activity_uuid + ) + course = db_session.exec(statement).first() + course = CourseRead.from_orm(course) + + + if not activity: + raise HTTPException( + status_code=404, + detail="Activity not found", + ) + + # Get Activity Content Blocks + content = activity.content + + # Serialize Activity Content Blocks to a text comprehensible by the AI + structured = structure_activity_content_by_type(content) + ai_friendly_text = serialize_activity_text_to_ai_comprehensible_text(structured,course,activity) + + response = ask_ai( + chat_session_object.message, + [], + ai_friendly_text, + "You are a helpful Education Assistant, and you are helping a student with the associated Course. " + "Use the available tools to get context about this question even if the question is not specific enough." + "For context, this is the Course name :" + course.name + " and this is the Lecture name :" + activity.name + "." + "Use your knowledge to help the student." + ) + + return response['output'] diff --git a/apps/api/src/services/ai/base.py b/apps/api/src/services/ai/base.py new file mode 100644 index 00000000..cc5fb140 --- /dev/null +++ b/apps/api/src/services/ai/base.py @@ -0,0 +1,82 @@ +from langchain.agents import AgentExecutor +from langchain.text_splitter import CharacterTextSplitter +from langchain.embeddings.sentence_transformer import SentenceTransformerEmbeddings +from langchain.vectorstores import Chroma +from langchain_core.messages import BaseMessage +from langchain.agents.openai_functions_agent.base import OpenAIFunctionsAgent +from langchain.prompts import MessagesPlaceholder +from langchain.memory import ConversationBufferMemory +from langchain_core.messages import SystemMessage +from langchain.agents.openai_functions_agent.agent_token_buffer_memory import ( + AgentTokenBufferMemory, +) +from langchain.chat_models import ChatOpenAI +from langchain.agents.agent_toolkits import ( + create_retriever_tool, +) + +import chromadb + +from config.config import get_learnhouse_config + +client = chromadb.Client() + + +chat_history = [] + + +def ask_ai( + question: str, + chat_history: list[BaseMessage], + text_reference: str, + message_for_the_prompt: str, +): + # Get API Keys + LH_CONFIG = get_learnhouse_config() + openai_api_key = LH_CONFIG.ai_config.openai_api_key + + # split it into chunks + text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) + documents = text_splitter.create_documents([text_reference]) + texts = text_splitter.split_documents(documents) + + # create the open-source embedding function + embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2") + + # load it into Chroma and use it as a retriever + db = Chroma.from_documents(texts, embedding_function) + tool = create_retriever_tool( + db.as_retriever(), + "find_context_text", + "Find associated text to get context about a course or a lecture", + ) + tools = [tool] + + llm = ChatOpenAI( + temperature=0, api_key=openai_api_key + ) + + memory_key = "history" + + memory = AgentTokenBufferMemory(memory_key=memory_key, llm=llm) + + + system_message = SystemMessage(content=(message_for_the_prompt)) + + prompt = OpenAIFunctionsAgent.create_prompt( + system_message=system_message, + extra_prompt_messages=[MessagesPlaceholder(variable_name=memory_key)], + ) + + agent = OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt) + + + agent_executor = AgentExecutor( + agent=agent, + tools=tools, + memory=memory, + verbose=True, + return_intermediate_steps=True, + ) + + return agent_executor({"input": question}) diff --git a/apps/api/src/services/ai/schemas/ai.py b/apps/api/src/services/ai/schemas/ai.py new file mode 100644 index 00000000..7e7ae3fc --- /dev/null +++ b/apps/api/src/services/ai/schemas/ai.py @@ -0,0 +1,12 @@ +from pydantic import BaseModel + + +class StartActivityAIChatSession(BaseModel): + activity_uuid: str + message: str + + +class SendActivityAIChatMessage(BaseModel): + aichat_uuid: str + activity_uuid: str + message: str diff --git a/apps/api/src/services/courses/activities/utils.py b/apps/api/src/services/courses/activities/utils.py new file mode 100644 index 00000000..8e036b8e --- /dev/null +++ b/apps/api/src/services/courses/activities/utils.py @@ -0,0 +1,78 @@ +from src.db.activities import ActivityRead +from src.db.courses import CourseRead + +def structure_activity_content_by_type(activity): + ### Get Headings, Texts, Callouts, Answers and Paragraphs from the activity as a big list of strings (text only) and return it + + # Get Headings + headings = [] + for item in activity["content"]: + if item["type"] == "heading": + headings.append(item["content"][0]["text"]) + + # Get Callouts + callouts = [] + for item in activity["content"]: + if item["type"] == "calloutInfo": + # Get every type of text in the callout + text = "" + for text_item in item["content"]: + text += text_item["text"] + callouts.append(text) + + # Get Paragraphs + paragraphs = [] + for item in activity["content"]: + if item["type"] == "paragraph": + paragraphs.append(item["content"][0]["text"]) + + # TODO: Get Questions and Answers (if any) + + data_array = [] + + # Add Headings + data_array.append({"Headings": headings}) + + # Add Callouts + data_array.append({"Callouts": callouts}) + + # Add Paragraphs + data_array.append({"Paragraphs": paragraphs}) + + return data_array + + +def serialize_activity_text_to_ai_comprehensible_text(data_array, course: CourseRead, activity: ActivityRead): + ### Serialize the text to a format that is comprehensible by the AI + + # Serialize Headings + serialized_headings = "" + for heading in data_array[0]["Headings"]: + serialized_headings += heading + " " + + # Serialize Callouts + serialized_callouts = "" + + for callout in data_array[1]["Callouts"]: + serialized_callouts += callout + " " + + # Serialize Paragraphs + serialized_paragraphs = "" + for paragraph in data_array[2]["Paragraphs"]: + serialized_paragraphs += paragraph + " " + + # Get a text that is comprehensible by the AI + text = ( + 'Use this as a context ' + + 'This is a course about "' + course.name + '". ' + + 'This is a lecture about "' + activity.name + '". ' + 'These are the headings: "' + + serialized_headings + + '" These are the callouts: "' + + serialized_callouts + + '" These are the paragraphs: "' + + serialized_paragraphs + + '"' + ) + + return text diff --git a/apps/api/src/services/users/users.py b/apps/api/src/services/users/users.py index cc6fbca5..bce3301b 100644 --- a/apps/api/src/services/users/users.py +++ b/apps/api/src/services/users/users.py @@ -7,7 +7,7 @@ from src.db.roles import Role, RoleRead from src.security.rbac.rbac import ( authorization_verify_based_on_roles_and_authorship, authorization_verify_if_user_is_anon, -) +) from src.db.organizations import Organization, OrganizationRead from src.db.users import ( AnonymousUser, From cf681b2260fab39695145d8fd530a370ab9273f1 Mon Sep 17 00:00:00 2001 From: swve Date: Sun, 31 Dec 2023 16:31:43 +0000 Subject: [PATCH 02/18] feat: init memory into ai chat messaging --- .devcontainer/devcontainer.json | 1 + apps/api/config/config.py | 11 +++ apps/api/config/config.yaml | 3 + apps/api/requirements.txt | 1 + apps/api/src/routers/ai/ai.py | 20 ++++- apps/api/src/services/ai/ai.py | 105 ++++++++++++++++++++++--- apps/api/src/services/ai/base.py | 34 ++++++-- apps/api/src/services/ai/schemas/ai.py | 5 ++ docker-compose.yml | 5 ++ 9 files changed, 163 insertions(+), 22 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index fa53814b..ff600b2a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,6 +8,7 @@ "extensions": [ "eamodio.gitlens", "ms-python.python", + "ms-python.black-formatter", "ms-python.vscode-pylance", "styled-components.vscode-styled-components", "dbaeumer.vscode-eslint", diff --git a/apps/api/config/config.py b/apps/api/config/config.py index d23d5ada..765eebac 100644 --- a/apps/api/config/config.py +++ b/apps/api/config/config.py @@ -55,6 +55,8 @@ class DatabaseConfig(BaseModel): sql_connection_string: Optional[str] mongo_connection_string: Optional[str] +class RedisConfig(BaseModel): + redis_connection_string: Optional[str] class LearnHouseConfig(BaseModel): site_name: str @@ -63,6 +65,7 @@ class LearnHouseConfig(BaseModel): general_config: GeneralConfig hosting_config: HostingConfig database_config: DatabaseConfig + redis_config: RedisConfig security_config: SecurityConfig ai_config: AIConfig @@ -183,6 +186,13 @@ def get_learnhouse_config() -> LearnHouseConfig: "mongo_connection_string" ) + # Redis config + env_redis_connection_string = os.environ.get("LEARNHOUSE_REDIS_CONNECTION_STRING") + redis_connection_string = env_redis_connection_string or yaml_config.get( + "redis_config", {} + ).get("redis_connection_string") + + # AI Config env_openai_api_key = os.environ.get("LEARNHOUSE_OPENAI_API_KEY") env_is_ai_enabled = os.environ.get("LEARNHOUSE_IS_AI_ENABLED") @@ -255,6 +265,7 @@ def get_learnhouse_config() -> LearnHouseConfig: database_config=database_config, security_config=SecurityConfig(auth_jwt_secret_key=auth_jwt_secret_key), ai_config=ai_config, + redis_config=RedisConfig(redis_connection_string=redis_connection_string), ) return config diff --git a/apps/api/config/config.yaml b/apps/api/config/config.yaml index 17bea379..923cc3ac 100644 --- a/apps/api/config/config.yaml +++ b/apps/api/config/config.yaml @@ -27,3 +27,6 @@ hosting_config: database_config: sql_connection_string: postgresql://learnhouse:learnhouse@db:5432/learnhouse mongo_connection_string: mongodb://learnhouse:learnhouse@mongo:27017/ + +redis_config: + redis_connection_string: redis://redis:6379/learnhouse diff --git a/apps/api/requirements.txt b/apps/api/requirements.txt index 0d25add8..5e21e2f0 100644 --- a/apps/api/requirements.txt +++ b/apps/api/requirements.txt @@ -24,3 +24,4 @@ openai chromadb sentence-transformers python-dotenv +redis diff --git a/apps/api/src/routers/ai/ai.py b/apps/api/src/routers/ai/ai.py index a48626d0..d66bb6f8 100644 --- a/apps/api/src/routers/ai/ai.py +++ b/apps/api/src/routers/ai/ai.py @@ -1,7 +1,7 @@ from fastapi import APIRouter, Depends, Request from sqlmodel import Session -from src.services.ai.ai import ai_start_activity_chat_session -from src.services.ai.schemas.ai import StartActivityAIChatSession +from src.services.ai.ai import ai_send_activity_chat_message, ai_start_activity_chat_session +from src.services.ai.schemas.ai import ActivityAIChatSessionResponse, SendActivityAIChatMessage, StartActivityAIChatSession from src.core.events.database import get_db_session from src.db.users import PublicUser from src.security.auth import get_current_user @@ -16,10 +16,24 @@ async def api_ai_start_activity_chat_session( chat_session_object: StartActivityAIChatSession, current_user: PublicUser = Depends(get_current_user), db_session: Session = Depends(get_db_session), -): +)-> ActivityAIChatSessionResponse: """ Start a new AI Chat session with a Course Activity """ return ai_start_activity_chat_session( request, chat_session_object, current_user, db_session ) + +@router.post("/send/activity_chat_message") +async def api_ai_send_activity_chat_message( + request: Request, + chat_session_object: SendActivityAIChatMessage, + current_user: PublicUser = Depends(get_current_user), + db_session: Session = Depends(get_db_session), +)-> ActivityAIChatSessionResponse: + """ + Send a message to an AI Chat session with a Course Activity + """ + return ai_send_activity_chat_message( + request, chat_session_object, current_user, db_session + ) \ No newline at end of file diff --git a/apps/api/src/services/ai/ai.py b/apps/api/src/services/ai/ai.py index 058598b0..bc776962 100644 --- a/apps/api/src/services/ai/ai.py +++ b/apps/api/src/services/ai/ai.py @@ -1,13 +1,20 @@ +from uuid import uuid4 from fastapi import Depends, HTTPException, Request +from requests import session from sqlmodel import Session, select from src.db.courses import Course, CourseRead from src.core.events.database import get_db_session from src.db.users import PublicUser from src.db.activities import Activity, ActivityRead from src.security.auth import get_current_user -from src.services.ai.base import ask_ai +from langchain.memory.chat_message_histories import RedisChatMessageHistory +from src.services.ai.base import ask_ai, get_chat_session_history -from src.services.ai.schemas.ai import StartActivityAIChatSession +from src.services.ai.schemas.ai import ( + ActivityAIChatSessionResponse, + SendActivityAIChatMessage, + StartActivityAIChatSession, +) from src.services.courses.activities.utils import ( serialize_activity_text_to_ai_comprehensible_text, structure_activity_content_by_type, @@ -19,7 +26,7 @@ def ai_start_activity_chat_session( chat_session_object: StartActivityAIChatSession, current_user: PublicUser = Depends(get_current_user), db_session: Session = Depends(get_db_session), -): +) -> ActivityAIChatSessionResponse: """ Start a new AI Chat session with a Course Activity """ @@ -32,13 +39,14 @@ def ai_start_activity_chat_session( activity = ActivityRead.from_orm(activity) # Get the Course - statement = select(Course).join(Activity).where( - Activity.activity_uuid == chat_session_object.activity_uuid + statement = ( + select(Course) + .join(Activity) + .where(Activity.activity_uuid == chat_session_object.activity_uuid) ) course = db_session.exec(statement).first() course = CourseRead.from_orm(course) - if not activity: raise HTTPException( status_code=404, @@ -50,16 +58,91 @@ def ai_start_activity_chat_session( # Serialize Activity Content Blocks to a text comprehensible by the AI structured = structure_activity_content_by_type(content) - ai_friendly_text = serialize_activity_text_to_ai_comprehensible_text(structured,course,activity) + ai_friendly_text = serialize_activity_text_to_ai_comprehensible_text( + structured, course, activity + ) + + chat_session = get_chat_session_history() response = ask_ai( chat_session_object.message, - [], + chat_session['message_history'], ai_friendly_text, "You are a helpful Education Assistant, and you are helping a student with the associated Course. " "Use the available tools to get context about this question even if the question is not specific enough." - "For context, this is the Course name :" + course.name + " and this is the Lecture name :" + activity.name + "." - "Use your knowledge to help the student." + "For context, this is the Course name :" + + course.name + + " and this is the Lecture name :" + + activity.name + + "." + "Use your knowledge to help the student.", ) - return response['output'] + return ActivityAIChatSessionResponse( + aichat_uuid=chat_session['aichat_uuid'], + activity_uuid=activity.activity_uuid, + message=response["output"], + ) + +def ai_send_activity_chat_message( + request: Request, + chat_session_object: SendActivityAIChatMessage, + current_user: PublicUser = Depends(get_current_user), + db_session: Session = Depends(get_db_session), +) -> ActivityAIChatSessionResponse: + """ + Start a new AI Chat session with a Course Activity + """ + # Get the Activity + statement = select(Activity).where( + Activity.activity_uuid == chat_session_object.activity_uuid + ) + activity = db_session.exec(statement).first() + + activity = ActivityRead.from_orm(activity) + + # Get the Course + statement = ( + select(Course) + .join(Activity) + .where(Activity.activity_uuid == chat_session_object.activity_uuid) + ) + course = db_session.exec(statement).first() + course = CourseRead.from_orm(course) + + if not activity: + raise HTTPException( + status_code=404, + detail="Activity not found", + ) + + # Get Activity Content Blocks + content = activity.content + + # Serialize Activity Content Blocks to a text comprehensible by the AI + structured = structure_activity_content_by_type(content) + ai_friendly_text = serialize_activity_text_to_ai_comprehensible_text( + structured, course, activity + ) + + chat_session = get_chat_session_history(chat_session_object.aichat_uuid) + + response = ask_ai( + chat_session_object.message, + chat_session['message_history'], + ai_friendly_text, + "You are a helpful Education Assistant, and you are helping a student with the associated Course. " + "Use the available tools to get context about this question even if the question is not specific enough." + "For context, this is the Course name :" + + course.name + + " and this is the Lecture name :" + + activity.name + + "." + "Use your knowledge to help the student if the context is not enough.", + ) + + return ActivityAIChatSessionResponse( + aichat_uuid=chat_session['aichat_uuid'], + activity_uuid=activity.activity_uuid, + message=response["output"], + ) diff --git a/apps/api/src/services/ai/base.py b/apps/api/src/services/ai/base.py index cc5fb140..02674e92 100644 --- a/apps/api/src/services/ai/base.py +++ b/apps/api/src/services/ai/base.py @@ -1,3 +1,5 @@ +from typing import Optional +from uuid import uuid4 from langchain.agents import AgentExecutor from langchain.text_splitter import CharacterTextSplitter from langchain.embeddings.sentence_transformer import SentenceTransformerEmbeddings @@ -5,7 +7,7 @@ from langchain.vectorstores import Chroma from langchain_core.messages import BaseMessage from langchain.agents.openai_functions_agent.base import OpenAIFunctionsAgent from langchain.prompts import MessagesPlaceholder -from langchain.memory import ConversationBufferMemory +from langchain.memory.chat_message_histories import RedisChatMessageHistory from langchain_core.messages import SystemMessage from langchain.agents.openai_functions_agent.agent_token_buffer_memory import ( AgentTokenBufferMemory, @@ -27,7 +29,7 @@ chat_history = [] def ask_ai( question: str, - chat_history: list[BaseMessage], + message_history, text_reference: str, message_for_the_prompt: str, ): @@ -52,14 +54,13 @@ def ask_ai( ) tools = [tool] - llm = ChatOpenAI( - temperature=0, api_key=openai_api_key - ) + llm = ChatOpenAI(temperature=0, api_key=openai_api_key) memory_key = "history" - memory = AgentTokenBufferMemory(memory_key=memory_key, llm=llm) - + memory = AgentTokenBufferMemory( + memory_key=memory_key, llm=llm, chat_memory=message_history + ) system_message = SystemMessage(content=(message_for_the_prompt)) @@ -70,7 +71,6 @@ def ask_ai( agent = OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt) - agent_executor = AgentExecutor( agent=agent, tools=tools, @@ -80,3 +80,21 @@ def ask_ai( ) return agent_executor({"input": question}) + + +def get_chat_session_history(aichat_uuid: Optional[str] = None): + # Init Message History + session_id = aichat_uuid if aichat_uuid else f"aichat_{uuid4()}" + + LH_CONFIG = get_learnhouse_config() + redis_conn_string = LH_CONFIG.redis_config.redis_connection_string + + if redis_conn_string: + message_history = RedisChatMessageHistory( + url=redis_conn_string, ttl=2160000, session_id=session_id + ) + else: + print("Redis connection string not found, using local memory") + message_history = [] + + return {"message_history": message_history, "aichat_uuid": session_id} diff --git a/apps/api/src/services/ai/schemas/ai.py b/apps/api/src/services/ai/schemas/ai.py index 7e7ae3fc..d63601a5 100644 --- a/apps/api/src/services/ai/schemas/ai.py +++ b/apps/api/src/services/ai/schemas/ai.py @@ -5,6 +5,11 @@ class StartActivityAIChatSession(BaseModel): activity_uuid: str message: str +class ActivityAIChatSessionResponse(BaseModel): + aichat_uuid: str + activity_uuid: str + message: str + class SendActivityAIChatMessage(BaseModel): aichat_uuid: str diff --git a/docker-compose.yml b/docker-compose.yml index a1bd0ef5..1bf90dea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,11 @@ services: - POSTGRES_USER=learnhouse - POSTGRES_PASSWORD=learnhouse - POSTGRES_DB=learnhouse + redis: + image: redis:7.2.3 + restart: always + ports: + - "6379:6379" mongo: image: mongo:5.0 restart: always From 19d8db9a20310809fb28ff33ac298e51cf33301c Mon Sep 17 00:00:00 2001 From: swve Date: Mon, 1 Jan 2024 18:13:17 +0100 Subject: [PATCH 03/18] feat: add activity ai chatbot UI and functionality --- apps/web/app/layout.tsx | 2 + .../activity/[activityid]/activity.tsx | 39 +-- apps/web/components/AI/AIActivityAsk.tsx | 222 ++++++++++++++++++ apps/web/components/Objects/Menu/Menu.tsx | 2 +- apps/web/package-lock.json | 84 ++----- apps/web/package.json | 1 + apps/web/public/learnhouse_ai_black_logo.png | Bin 0 -> 32914 bytes apps/web/public/learnhouse_ai_simple.png | Bin 0 -> 8699 bytes apps/web/services/ai/ai.ts | 23 ++ apps/web/tailwind.config.js | 4 +- pnpm-lock.yaml | 49 +--- 11 files changed, 312 insertions(+), 114 deletions(-) create mode 100644 apps/web/components/AI/AIActivityAsk.tsx create mode 100644 apps/web/public/learnhouse_ai_black_logo.png create mode 100644 apps/web/public/learnhouse_ai_simple.png create mode 100644 apps/web/services/ai/ai.ts diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 84c73f3a..e4dea8d8 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,6 +1,8 @@ "use client"; import "../styles/globals.css"; import StyledComponentsRegistry from "../components/Utils/libs/styled-registry"; +import { GeistSans } from 'geist/font/sans'; + import { motion } from "framer-motion"; export default function RootLayout({ children }: { children: React.ReactNode }) { diff --git a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx index 9a052d06..b490df4d 100644 --- a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx +++ b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx @@ -3,7 +3,7 @@ import Link from "next/link"; import { getUriWithOrg } from "@services/config/config"; import Canva from "@components/Objects/Activities/DynamicCanva/DynamicCanva"; import VideoActivity from "@components/Objects/Activities/Video/Video"; -import { Check } from "lucide-react"; +import { Check, MoreVertical } from "lucide-react"; import { markActivityAsComplete } from "@services/courses/activity"; import DocumentPdfActivity from "@components/Objects/Activities/DocumentPdf/DocumentPdf"; import ActivityIndicators from "@components/Pages/Courses/ActivityIndicators"; @@ -13,6 +13,7 @@ import AuthenticatedClientElement from "@components/Security/AuthenticatedClient import { getCourseThumbnailMediaDirectory } from "@services/media/media"; import { useOrg } from "@components/Contexts/OrgContext"; import { CourseProvider } from "@components/Contexts/CourseContext"; +import AIActivityAsk from "@components/AI/AIActivityAsk"; interface ActivityClientProps { activityid: string; @@ -31,14 +32,17 @@ function ActivityClient(props: ActivityClientProps) { const course = props.course; const org = useOrg() as any; - function getChapterName(chapterId: string) { - let chapterName = ""; - course.chapters.forEach((chapter: any) => { - if (chapter.id === chapterId) { - chapterName = chapter.name; + function getChapterNameByActivityId(course: any, activity_id: any) { + for (let i = 0; i < course.chapters.length; i++) { + let chapter = course.chapters[i]; + for (let j = 0; j < chapter.activities.length; j++) { + let activity = chapter.activities[j]; + if (activity.id === activity_id) { + return chapter.name; + } } - }); - return chapterName; + } + return null; // return null if no matching activity is found } @@ -63,13 +67,14 @@ function ActivityClient(props: ActivityClientProps) {
-

Chapter : {getChapterName(activity.coursechapter_id)}

+

Chapter : {getChapterNameByActivityId(course, activity.id)}

{activity.name}

-
+
+ + -
@@ -114,19 +119,19 @@ export function MarkStatus(props: { activity: any, activityid: string, course: a return ( <>{isActivityCompleted() ? ( -
+
- + {" "} - Already completed + Already completed
) : ( -
+
{" "} - + {" "} - Mark as complete + Mark as complete
)} ) diff --git a/apps/web/components/AI/AIActivityAsk.tsx b/apps/web/components/AI/AIActivityAsk.tsx new file mode 100644 index 00000000..75281795 --- /dev/null +++ b/apps/web/components/AI/AIActivityAsk.tsx @@ -0,0 +1,222 @@ +import { useSession } from '@components/Contexts/SessionContext' +import { sendActivityAIChatMessage, startActivityAIChatSession } from '@services/ai/ai'; +import Avvvatars from 'avvvatars-react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { FlaskConical, Keyboard, Sparkle, Sparkles, X } from 'lucide-react' +import Image from 'next/image'; +import { send } from 'process'; +import learnhouseAI_icon from "public/learnhouse_ai_simple.png"; +import learnhouseAI_logo_black from "public/learnhouse_ai_black_logo.png"; +import React, { useEffect, useRef } from 'react' + + +type AIActivityAskProps = { + activity: any; +} + + +function AIActivityAsk(props: AIActivityAskProps) { + const [isAIModalOpen, setIsAIModalOpen] = React.useState(false); + + + return ( +
+ +
setIsAIModalOpen(true)} + style={{ + background: 'conic-gradient(from 32deg at 53.75% 50%, rgb(35, 40, 93) 4deg, rgba(20, 0, 52, 0.95) 59deg, rgba(164, 45, 238, 0.88) 281deg)', + }} + className="rounded-full px-5 drop-shadow-md flex items-center space-x-1 p-2.5 text-sm text-white hover:cursor-pointer transition delay-150 duration-300 ease-in-out hover:scale-105"> + {" "} + + + {" "} + Ask AI +
+
+ ) +} + +type Message = { + sender: string; + message: any; + type: 'ai' | 'user'; +} + +type ActivityChatMessageBoxProps = { + activity: any; + isAIModalOpen?: boolean; + setIsAIModalOpen?: any; +} + +function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { + const session = useSession() as any; + const [messages, setMessages] = React.useState([]) as [Message[], any]; + const [aichat_uuid, setAichat_uuid] = React.useState(''); + const [isWaitingForResponse, setIsWaitingForResponse] = React.useState(false); + const [chatInputValue, setChatInputValue] = React.useState('') as [string, any]; + + // TODO : come up with a better way to handle this + const inputClass = isWaitingForResponse + ? 'ring-1 ring-inset ring-white/10 bg-transparent w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30 opacity-30' + : 'ring-1 ring-inset ring-white/10 bg-transparent w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30'; + + React.useEffect(() => { + + }, [session]); + + function handleKeyDown(event: React.KeyboardEvent) { + if (event.key === 'Enter') { + // Perform the sending action here + sendMessage(event.currentTarget.value); + } + } + + const handleChange = (event: React.ChangeEvent) => { + setChatInputValue(event.target.value); + } + + const sendMessage = async (message: string) => { + if (aichat_uuid) { + setMessages((messages: any) => [...messages, { sender: session.user.user_uuid, message: message, type: 'user' }]); + setIsWaitingForResponse(true); + const response = await sendActivityAIChatMessage(message, aichat_uuid, props.activity.activity_uuid) + setIsWaitingForResponse(false); + setChatInputValue(''); + setMessages((messages: any) => [...messages, { sender: 'ai', message: response.message, type: 'ai' }]); + } else { + setMessages((messages: any) => [...messages, { sender: session.user.user_uuid, message: message, type: 'user' }]); + setIsWaitingForResponse(true); + const response = await startActivityAIChatSession(message, props.activity.activity_uuid) + setAichat_uuid(response.aichat_uuid); + setIsWaitingForResponse(false); + setChatInputValue(''); + setMessages((messages: any) => [...messages, { sender: 'ai', message: response.message, type: 'ai' }]); + } + } + + function closeModal() { + props.setIsAIModalOpen(false); + } + + const messagesEndRef = useRef(null); + + useEffect(() => { + if (messagesEndRef.current) { + messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }); + } + + }, [messages, session]); + + + if (props.isAIModalOpen) { + return ( + +
+
+
+ +
+
+ + Learnhouse AI +
+
+ + Experimental +
+ +
+
+ {messages.length > 0 ? ( +
+ {messages.map((message: Message, index: number) => { + return ( + + ) + })} +
+
+ ) : ( + + )} +
+
+ +
+
+ + +
+
+
+ + ) + } +} + +type AIMessageProps = { + message: Message; + animated: boolean; +} + +function AIMessage(props: AIMessageProps) { + const session = useSession() as any; + + const words = props.message.message.split(' '); + + return ( +
+
+ +
+
+

+ + {words.map((word: string, i: number) => ( + + {word + ' '} + + ))} + +

+
+
+ ) +} + +const AIMessagePlaceHolder = () => { + return ( +
+
+ +

How can we help today ?

+
+ Explain in simple examples + Generate flashcards + Break down in concepts +
+
+
+ ) +} + + +export default AIActivityAsk \ No newline at end of file diff --git a/apps/web/components/Objects/Menu/Menu.tsx b/apps/web/components/Objects/Menu/Menu.tsx index 4a933f26..af38aa01 100644 --- a/apps/web/components/Objects/Menu/Menu.tsx +++ b/apps/web/components/Objects/Menu/Menu.tsx @@ -1,5 +1,5 @@ 'use client'; -import React, { use, useEffect } from "react"; +import React, { useEffect } from "react"; import Link from "next/link"; import { getAPIUrl, getUriWithOrg } from "@services/config/config"; import { getOrganizationContextInfo, getOrganizationContextInfoWithoutCredentials } from "@services/organizations/orgs"; diff --git a/apps/web/package-lock.json b/apps/web/package-lock.json index e6daccda..0f9ded12 100644 --- a/apps/web/package-lock.json +++ b/apps/web/package-lock.json @@ -42,6 +42,7 @@ "styled-components": "^6.0.0-beta.9", "swr": "^2.2.4", "tailwind-merge": "^1.14.0", + "tailwind-scrollbar": "^3.0.5", "uuid": "^9.0.0", "y-indexeddb": "^9.0.9", "y-webrtc": "^10.2.3", @@ -77,7 +78,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, "engines": { "node": ">=10" }, @@ -2446,7 +2446,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2459,7 +2458,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -2468,7 +2466,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -4263,14 +4260,12 @@ "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==", - "dev": true + "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==", - "devOptional": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4282,8 +4277,7 @@ "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==", - "dev": true + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "node_modules/argparse": { "version": "2.0.1", @@ -4606,7 +4600,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true, "engines": { "node": ">=8" } @@ -4624,7 +4617,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "devOptional": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -4723,7 +4715,6 @@ "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==", - "dev": true, "engines": { "node": ">= 6" } @@ -4783,7 +4774,6 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "devOptional": true, "funding": [ { "type": "individual", @@ -4810,7 +4800,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -4935,7 +4924,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -5049,8 +5037,7 @@ "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, "node_modules/dir-glob": { "version": "3.0.1", @@ -5067,8 +5054,7 @@ "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "node_modules/doctrine": { "version": "3.0.0", @@ -5704,7 +5690,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5720,7 +5705,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -5744,7 +5728,6 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -5765,7 +5748,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "devOptional": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5937,6 +5919,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/geist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/geist/-/geist-1.2.0.tgz", + "integrity": "sha512-RZsgCkGnSi1IV1Ozg3s6Ou4r/jzLff9+47ChjpJ5yX8ncEC/RwdStGwhdFzDcnSv0xU0+9J/fTX5Kht0NajTXA==", + "peerDependencies": { + "next": "^13.2 || ^14" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -6023,7 +6013,6 @@ "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" }, @@ -6379,7 +6368,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -6457,7 +6445,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -6493,7 +6480,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -6526,7 +6512,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true, "engines": { "node": ">=0.12.0" } @@ -6737,7 +6722,6 @@ "version": "1.20.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==", - "dev": true, "bin": { "jiti": "bin/jiti.js" } @@ -6897,7 +6881,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, "engines": { "node": ">=10" } @@ -6905,8 +6888,7 @@ "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==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/linkify-it": { "version": "4.0.1", @@ -7079,7 +7061,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "engines": { "node": ">= 8" } @@ -7088,7 +7069,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -7136,7 +7116,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -7240,7 +7219,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -7266,7 +7244,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, "engines": { "node": ">= 6" } @@ -7545,7 +7522,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, "engines": { "node": ">= 6" } @@ -7581,7 +7557,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -7598,7 +7573,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, "dependencies": { "camelcase-css": "^2.0.1" }, @@ -7617,7 +7591,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", - "dev": true, "dependencies": { "lilconfig": "^2.0.5", "yaml": "^2.1.1" @@ -7646,7 +7619,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.11" }, @@ -7665,7 +7637,6 @@ "version": "6.0.13", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", - "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -8173,7 +8144,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, "dependencies": { "pify": "^2.3.0" } @@ -8182,7 +8152,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -8204,7 +8173,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -8359,7 +8327,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -8424,7 +8391,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -8841,7 +8807,6 @@ "version": "3.34.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -8863,7 +8828,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, "engines": { "node": ">= 6" } @@ -8872,7 +8836,6 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -8931,11 +8894,21 @@ "url": "https://github.com/sponsors/dcastil" } }, + "node_modules/tailwind-scrollbar": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tailwind-scrollbar/-/tailwind-scrollbar-3.0.5.tgz", + "integrity": "sha512-0ZwxTivevqq9BY9fRP9zDjHl7Tu+J5giBGbln+0O1R/7nHtBUKnjQcA1aTIhK7Oyjp6Uc/Dj6/dn8Dq58k5Uww==", + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "tailwindcss": "3.x" + } + }, "node_modules/tailwindcss": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", - "dev": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -8987,7 +8960,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, "dependencies": { "any-promise": "^1.0.0" } @@ -8996,7 +8968,6 @@ "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==", - "dev": true, "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -9043,7 +9014,6 @@ "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==", - "devOptional": true, "dependencies": { "is-number": "^7.0.0" }, @@ -9071,8 +9041,7 @@ "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==", - "dev": true + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "node_modules/tsconfig-paths": { "version": "3.14.2", @@ -9622,7 +9591,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", - "dev": true, "engines": { "node": ">= 14" } diff --git a/apps/web/package.json b/apps/web/package.json index 27561c3e..ac6a098e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -43,6 +43,7 @@ "styled-components": "^6.0.0-beta.9", "swr": "^2.2.4", "tailwind-merge": "^1.14.0", + "tailwind-scrollbar": "^3.0.5", "uuid": "^9.0.0", "y-indexeddb": "^9.0.9", "y-webrtc": "^10.2.3", diff --git a/apps/web/public/learnhouse_ai_black_logo.png b/apps/web/public/learnhouse_ai_black_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c0685c378c96e903c161fc5d79ec059f0a50d6f6 GIT binary patch literal 32914 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 N002ovPDHLkV1mbm)2aXf literal 0 HcmV?d00001 diff --git a/apps/web/public/learnhouse_ai_simple.png b/apps/web/public/learnhouse_ai_simple.png new file mode 100644 index 0000000000000000000000000000000000000000..3ea2de53c441d225390b0df73a6d4879fb9d5d59 GIT binary patch literal 8699 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'} - dev: true /@ampproject/remapping@2.2.1: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} @@ -1756,12 +1758,10 @@ packages: dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: true /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} @@ -1769,7 +1769,6 @@ packages: dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 - dev: true /@popperjs/core@2.11.8: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -3127,7 +3126,6 @@ packages: /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - dev: true /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} @@ -3138,7 +3136,6 @@ packages: /arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - dev: true /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -3392,7 +3389,6 @@ packages: /camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - dev: true /camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} @@ -3535,7 +3531,6 @@ packages: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true - dev: true /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} @@ -3629,7 +3624,6 @@ packages: /didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - dev: true /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -3640,7 +3634,6 @@ packages: /dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - dev: true /doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} @@ -4070,7 +4063,6 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: true /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -4084,7 +4076,6 @@ packages: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: reusify: 1.0.4 - dev: true /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} @@ -4244,7 +4235,6 @@ packages: engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 - dev: true /glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} @@ -4259,7 +4249,6 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true /glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} @@ -4660,7 +4649,6 @@ packages: /jiti@1.20.0: resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==} hasBin: true - dev: true /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -4766,11 +4754,9 @@ packages: /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} - dev: true /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true /linkify-it@4.0.1: resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} @@ -4887,7 +4873,6 @@ packages: /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - dev: true /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} @@ -4895,7 +4880,6 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: true /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -4936,7 +4920,6 @@ packages: any-promise: 1.3.0 object-assign: 4.1.1 thenify-all: 1.6.0 - dev: true /nanoid@3.3.6: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} @@ -5018,7 +5001,6 @@ packages: /object-hash@3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} - dev: true /object-inspect@1.12.3: resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} @@ -5170,7 +5152,6 @@ packages: /pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} - dev: true /pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} @@ -5180,7 +5161,6 @@ packages: /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - dev: true /postcss-import@15.1.0(postcss@8.4.31): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} @@ -5192,7 +5172,6 @@ packages: postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 - dev: true /postcss-js@4.0.1(postcss@8.4.31): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} @@ -5202,7 +5181,6 @@ packages: dependencies: camelcase-css: 2.0.1 postcss: 8.4.31 - dev: true /postcss-load-config@4.0.1(postcss@8.4.31): resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} @@ -5219,7 +5197,6 @@ packages: lilconfig: 2.1.0 postcss: 8.4.31 yaml: 2.3.2 - dev: true /postcss-nested@6.0.1(postcss@8.4.31): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} @@ -5229,7 +5206,6 @@ packages: dependencies: postcss: 8.4.31 postcss-selector-parser: 6.0.13 - dev: true /postcss-selector-parser@6.0.13: resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} @@ -5237,7 +5213,6 @@ packages: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - dev: true /postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -5632,7 +5607,6 @@ packages: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} dependencies: pify: 2.3.0 - dev: true /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} @@ -5744,7 +5718,6 @@ packages: /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} @@ -5769,7 +5742,6 @@ packages: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 - dev: true /safe-array-concat@1.0.1: resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} @@ -6025,7 +5997,6 @@ packages: mz: 2.7.0 pirates: 4.0.6 ts-interface-checker: 0.1.13 - dev: true /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -6058,6 +6029,15 @@ packages: resolution: {integrity: sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==} dev: false + /tailwind-scrollbar@3.0.5(tailwindcss@3.3.3): + resolution: {integrity: sha512-0ZwxTivevqq9BY9fRP9zDjHl7Tu+J5giBGbln+0O1R/7nHtBUKnjQcA1aTIhK7Oyjp6Uc/Dj6/dn8Dq58k5Uww==} + engines: {node: '>=12.13.0'} + peerDependencies: + tailwindcss: 3.x + dependencies: + tailwindcss: 3.3.3 + dev: false + /tailwindcss@3.3.3: resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==} engines: {node: '>=14.0.0'} @@ -6087,7 +6067,6 @@ packages: sucrase: 3.34.0 transitivePeerDependencies: - ts-node - dev: true /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} @@ -6103,13 +6082,11 @@ packages: engines: {node: '>=0.8'} dependencies: thenify: 3.3.1 - dev: true /thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} dependencies: any-promise: 1.3.0 - dev: true /throttle-debounce@3.0.1: resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} @@ -6156,7 +6133,6 @@ packages: /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - dev: true /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} @@ -6573,7 +6549,6 @@ packages: /yaml@2.3.2: resolution: {integrity: sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==} engines: {node: '>= 14'} - dev: true /yjs@13.6.8: resolution: {integrity: sha512-ZPq0hpJQb6f59B++Ngg4cKexDJTvfOgeiv0sBc4sUm8CaBWH7OQC4kcCgrqbjJ/B2+6vO49exvTmYfdlPtcjbg==} From a9d038e5e31d2ab3aaa91897d82efa8ffb2c7c88 Mon Sep 17 00:00:00 2001 From: swve Date: Mon, 1 Jan 2024 19:16:18 +0100 Subject: [PATCH 04/18] fix: overflow bug & improve style --- apps/web/components/AI/AIActivityAsk.tsx | 46 ++++++++++++++---------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/apps/web/components/AI/AIActivityAsk.tsx b/apps/web/components/AI/AIActivityAsk.tsx index 75281795..bc21baeb 100644 --- a/apps/web/components/AI/AIActivityAsk.tsx +++ b/apps/web/components/AI/AIActivityAsk.tsx @@ -2,7 +2,7 @@ import { useSession } from '@components/Contexts/SessionContext' import { sendActivityAIChatMessage, startActivityAIChatSession } from '@services/ai/ai'; import Avvvatars from 'avvvatars-react'; import { motion, AnimatePresence } from 'framer-motion'; -import { FlaskConical, Keyboard, Sparkle, Sparkles, X } from 'lucide-react' +import { FlaskConical, Keyboard, MessageCircle, Sparkle, Sparkles, X } from 'lucide-react' import Image from 'next/image'; import { send } from 'process'; import learnhouseAI_icon from "public/learnhouse_ai_simple.png"; @@ -19,8 +19,9 @@ function AIActivityAsk(props: AIActivityAskProps) { const [isAIModalOpen, setIsAIModalOpen] = React.useState(false); + return ( -
+
setIsAIModalOpen(true)} @@ -59,12 +60,16 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { // TODO : come up with a better way to handle this const inputClass = isWaitingForResponse - ? 'ring-1 ring-inset ring-white/10 bg-transparent w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30 opacity-30' + ? 'ring-1 ring-inset ring-white/10 bg-transparent w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30 opacity-30 ' : 'ring-1 ring-inset ring-white/10 bg-transparent w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30'; - React.useEffect(() => { - - }, [session]); + useEffect(() => { + if (props.isAIModalOpen) { + document.body.style.overflow = 'hidden'; + } else { + document.body.style.overflow = 'unset'; + } + }, [props.isAIModalOpen]); function handleKeyDown(event: React.KeyboardEvent) { if (event.key === 'Enter') { @@ -106,7 +111,7 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { if (messagesEndRef.current) { messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }); } - + }, [messages, session]); @@ -116,11 +121,12 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { initial={{ y: 20, opacity: 0.3, filter: 'blur(5px)' }} animate={{ y: 0, opacity: 1, filter: 'blur(0px)' }} transition={{ type: "spring", bounce: 0.35, duration: 1.7, mass: 0.2, velocity: 2 }} - className='fixed top-0 left-0 w-full h-full z-50 flex justify-center items-center' + className='fixed top-0 left-0 w-full h-full z-50 flex justify-center items-center ' + style={{ pointerEvents: 'none' }} >
@@ -149,9 +155,9 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) {
) : ( - + )} -
+
@@ -159,6 +165,9 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) {
+
+ sendMessage(chatInputValue)} /> +
@@ -202,16 +211,17 @@ function AIMessage(props: AIMessageProps) { ) } -const AIMessagePlaceHolder = () => { +const AIMessagePlaceHolder = (props : {activity_uuid : string, sendMessage : any}) => { + const session = useSession() as any; return (
-
+
-

How can we help today ?

-
- Explain in simple examples - Generate flashcards - Break down in concepts +

Hello {session.user.username}, How can we help today ?

+
+ props.sendMessage('Explain this Course in Simple examples.')} className='py-1.5 px-6 text-xs font-semibold text-white/30 rounded-full shadow-2xl bg-black/20 mb-3 outline outline-gray-400/5 cursor-pointer'>Explain in simple examples + props.sendMessage('Generate flashcards about this course and this lecture.')} className='py-1.5 px-6 text-xs font-semibold text-white/30 rounded-full shadow-2xl bg-black/20 mb-3 outline outline-gray-400/5 cursor-pointer'>Generate flashcards + props.sendMessage('Break down this Course in concepts.')} className='py-1.5 px-6 text-xs font-semibold text-white/30 rounded-full shadow-2xl bg-black/20 mb-3 outline outline-gray-400/5 cursor-pointer'>Break down in concepts
From 582e322155554b933977b6e0acb4773ded73b245 Mon Sep 17 00:00:00 2001 From: swve Date: Mon, 1 Jan 2024 21:44:16 +0100 Subject: [PATCH 05/18] feat: add exit chatbot ui animation --- apps/web/components/AI/AIActivityAsk.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/web/components/AI/AIActivityAsk.tsx b/apps/web/components/AI/AIActivityAsk.tsx index bc21baeb..1411dd06 100644 --- a/apps/web/components/AI/AIActivityAsk.tsx +++ b/apps/web/components/AI/AIActivityAsk.tsx @@ -115,11 +115,13 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { }, [messages, session]); - if (props.isAIModalOpen) { - return ( + return ( + + {props.isAIModalOpen && (
- ) - } + )} + + ) } type AIMessageProps = { @@ -211,14 +214,14 @@ function AIMessage(props: AIMessageProps) { ) } -const AIMessagePlaceHolder = (props : {activity_uuid : string, sendMessage : any}) => { +const AIMessagePlaceHolder = (props: { activity_uuid: string, sendMessage: any }) => { const session = useSession() as any; return (
- +

Hello {session.user.username}, How can we help today ?

-
+
props.sendMessage('Explain this Course in Simple examples.')} className='py-1.5 px-6 text-xs font-semibold text-white/30 rounded-full shadow-2xl bg-black/20 mb-3 outline outline-gray-400/5 cursor-pointer'>Explain in simple examples props.sendMessage('Generate flashcards about this course and this lecture.')} className='py-1.5 px-6 text-xs font-semibold text-white/30 rounded-full shadow-2xl bg-black/20 mb-3 outline outline-gray-400/5 cursor-pointer'>Generate flashcards props.sendMessage('Break down this Course in concepts.')} className='py-1.5 px-6 text-xs font-semibold text-white/30 rounded-full shadow-2xl bg-black/20 mb-3 outline outline-gray-400/5 cursor-pointer'>Break down in concepts From a05b298c91d36a46f3e944488afc7d779c662c5a Mon Sep 17 00:00:00 2001 From: swve Date: Thu, 4 Jan 2024 23:12:27 +0100 Subject: [PATCH 06/18] feat: init in-course AI features --- .../activity/[activityid]/activity.tsx | 83 +++--- apps/web/components/AI/AIActivityAsk.tsx | 238 +++++++++++------- .../Contexts/AI/AIChatBotContext.tsx | 69 +++++ .../Contexts/Editor/EditorContext.tsx | 31 +++ .../Activities/DynamicCanva/DynamicCanva.tsx | 54 +++- .../DynamicCanva/Elements/AICanvaToolkit.tsx | 109 ++++++++ apps/web/components/Objects/Editor/Editor.tsx | 2 +- .../Extensions/NoTextInput/NoTextInput.tsx | 21 ++ apps/web/package.json | 2 +- pnpm-lock.yaml | 8 +- 10 files changed, 471 insertions(+), 146 deletions(-) create mode 100644 apps/web/components/Contexts/AI/AIChatBotContext.tsx create mode 100644 apps/web/components/Contexts/Editor/EditorContext.tsx create mode 100644 apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx create mode 100644 apps/web/components/Objects/Editor/Extensions/NoTextInput/NoTextInput.tsx diff --git a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx index b490df4d..8119781b 100644 --- a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx +++ b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx @@ -14,6 +14,7 @@ import { getCourseThumbnailMediaDirectory } from "@services/media/media"; import { useOrg } from "@components/Contexts/OrgContext"; import { CourseProvider } from "@components/Contexts/CourseContext"; import AIActivityAsk from "@components/AI/AIActivityAsk"; +import AIChatBotProvider from "@components/Contexts/AI/AIChatBotContext"; interface ActivityClientProps { activityid: string; @@ -50,48 +51,50 @@ function ActivityClient(props: ActivityClientProps) { return ( <> - -
-
-
- - - -
-
-

Course

-

{course.name}

-
-
- - -
-
-

Chapter : {getChapterNameByActivityId(course, activity.id)}

-

{activity.name}

-
-
- - - - - -
-
- - {activity ? ( -
-
- {activity.activity_type == "TYPE_DYNAMIC" && } - {/* todo : use apis & streams instead of this */} - {activity.activity_type == "TYPE_VIDEO" && } - {activity.activity_type == "TYPE_DOCUMENT" && } + + +
+
+
+ + + +
+
+

Course

+

{course.name}

- ) : (
)} - {
} -
-
+ + +
+
+

Chapter : {getChapterNameByActivityId(course, activity.id)}

+

{activity.name}

+
+
+ + + + + +
+
+ + {activity ? ( +
+
+ {activity.activity_type == "TYPE_DYNAMIC" && } + {/* todo : use apis & streams instead of this */} + {activity.activity_type == "TYPE_VIDEO" && } + {activity.activity_type == "TYPE_DOCUMENT" && } +
+
+ ) : (
)} + {
} +
+ + ); diff --git a/apps/web/components/AI/AIActivityAsk.tsx b/apps/web/components/AI/AIActivityAsk.tsx index 1411dd06..6ae62c49 100644 --- a/apps/web/components/AI/AIActivityAsk.tsx +++ b/apps/web/components/AI/AIActivityAsk.tsx @@ -1,13 +1,17 @@ import { useSession } from '@components/Contexts/SessionContext' import { sendActivityAIChatMessage, startActivityAIChatSession } from '@services/ai/ai'; +import { BadgeInfo, NotebookTabs } from 'lucide-react'; import Avvvatars from 'avvvatars-react'; import { motion, AnimatePresence } from 'framer-motion'; -import { FlaskConical, Keyboard, MessageCircle, Sparkle, Sparkles, X } from 'lucide-react' +import { FlaskConical, Keyboard, MessageCircle, MessageSquareIcon, Sparkle, Sparkles, X } from 'lucide-react' import Image from 'next/image'; import { send } from 'process'; import learnhouseAI_icon from "public/learnhouse_ai_simple.png"; import learnhouseAI_logo_black from "public/learnhouse_ai_black_logo.png"; import React, { useEffect, useRef } from 'react' +import { AIChatBotStateTypes, useAIChatBot, useAIChatBotDispatch } from '@components/Contexts/AI/AIChatBotContext'; +import FeedbackModal from '@components/Objects/Modals/Feedback/Feedback'; +import Modal from '@components/StyledElements/Modal/Modal'; type AIActivityAskProps = { @@ -16,15 +20,14 @@ type AIActivityAskProps = { function AIActivityAsk(props: AIActivityAskProps) { - const [isAIModalOpen, setIsAIModalOpen] = React.useState(false); - + const dispatchAIChatBot = useAIChatBotDispatch() as any; return (
- +
setIsAIModalOpen(true)} + onClick={() => dispatchAIChatBot({ type: 'setIsModalOpen' })} style={{ background: 'conic-gradient(from 32deg at 53.75% 50%, rgb(35, 40, 93) 4deg, rgba(20, 0, 52, 0.95) 59deg, rgba(164, 45, 238, 0.88) 281deg)', }} @@ -39,7 +42,7 @@ function AIActivityAsk(props: AIActivityAskProps) { ) } -type Message = { +export type AIMessage = { sender: string; message: any; type: 'ai' | 'user'; @@ -47,29 +50,25 @@ type Message = { type ActivityChatMessageBoxProps = { activity: any; - isAIModalOpen?: boolean; - setIsAIModalOpen?: any; } function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { const session = useSession() as any; - const [messages, setMessages] = React.useState([]) as [Message[], any]; - const [aichat_uuid, setAichat_uuid] = React.useState(''); - const [isWaitingForResponse, setIsWaitingForResponse] = React.useState(false); - const [chatInputValue, setChatInputValue] = React.useState('') as [string, any]; + const aiChatBotState = useAIChatBot() as AIChatBotStateTypes; + const dispatchAIChatBot = useAIChatBotDispatch() as any; // TODO : come up with a better way to handle this - const inputClass = isWaitingForResponse + const inputClass = aiChatBotState.isWaitingForResponse ? 'ring-1 ring-inset ring-white/10 bg-transparent w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30 opacity-30 ' : 'ring-1 ring-inset ring-white/10 bg-transparent w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30'; useEffect(() => { - if (props.isAIModalOpen) { + if (aiChatBotState.isModalOpen) { document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = 'unset'; } - }, [props.isAIModalOpen]); + }, [aiChatBotState.isModalOpen]); function handleKeyDown(event: React.KeyboardEvent) { if (event.key === 'Enter') { @@ -78,31 +77,33 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { } } - const handleChange = (event: React.ChangeEvent) => { - setChatInputValue(event.target.value); + const handleChange = async (event: React.ChangeEvent) => { + await dispatchAIChatBot({ type: 'setChatInputValue', payload: event.currentTarget.value }); + } const sendMessage = async (message: string) => { - if (aichat_uuid) { - setMessages((messages: any) => [...messages, { sender: session.user.user_uuid, message: message, type: 'user' }]); - setIsWaitingForResponse(true); - const response = await sendActivityAIChatMessage(message, aichat_uuid, props.activity.activity_uuid) - setIsWaitingForResponse(false); - setChatInputValue(''); - setMessages((messages: any) => [...messages, { sender: 'ai', message: response.message, type: 'ai' }]); + if (aiChatBotState.aichat_uuid) { + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); + await dispatchAIChatBot({ type: 'setIsWaitingForResponse' }); + const response = await sendActivityAIChatMessage(message, aiChatBotState.aichat_uuid, props.activity.activity_uuid) + await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' }); + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); + } else { - setMessages((messages: any) => [...messages, { sender: session.user.user_uuid, message: message, type: 'user' }]); - setIsWaitingForResponse(true); + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); + await dispatchAIChatBot({ type: 'setIsWaitingForResponse' }); const response = await startActivityAIChatSession(message, props.activity.activity_uuid) - setAichat_uuid(response.aichat_uuid); - setIsWaitingForResponse(false); - setChatInputValue(''); - setMessages((messages: any) => [...messages, { sender: 'ai', message: response.message, type: 'ai' }]); + await dispatchAIChatBot({ type: 'setAichat_uuid', payload: response.aichat_uuid }); + await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' }); + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); } } function closeModal() { - props.setIsAIModalOpen(false); + dispatchAIChatBot({ type: 'setIsModalClose' }); } const messagesEndRef = useRef(null); @@ -112,74 +113,78 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }); } - }, [messages, session]); + }, [aiChatBotState.messages, session]); return ( - {props.isAIModalOpen && ( - -
-
-
- -
-
- - Learnhouse AI -
-
- - Experimental -
+ {aiChatBotState.isModalOpen && ( + <> + +
+
+
-
-
- {messages.length > 0 ? ( -
- {messages.map((message: Message, index: number) => { - return ( - - ) - })} -
-
- ) : ( - - )} -
-
- -
-
- + +
+
+ + AI +
+
+ + Experimental +
+ +
+
+ {aiChatBotState.messages.length > 0 ? ( +
+ {aiChatBotState.messages.map((message: AIMessage, index: number) => { + return ( + + ) + })} +
+
+ ) : ( + + )} +
+
+ +
+
+ + +
+
+ sendMessage(aiChatBotState.chatInputValue)} /> +
+
-
- sendMessage(chatInputValue)} /> -
-
-
- + + )} ) } type AIMessageProps = { - message: Message; + message: AIMessage; animated: boolean; } @@ -189,7 +194,7 @@ function AIMessage(props: AIMessageProps) { const words = props.message.message.split(' '); return ( -
+
@@ -216,20 +221,65 @@ function AIMessage(props: AIMessageProps) { const AIMessagePlaceHolder = (props: { activity_uuid: string, sendMessage: any }) => { const session = useSession() as any; + + const [feedbackModal, setFeedbackModal] = React.useState(false); return (
- -

Hello {session.user.username}, How can we help today ?

-
- props.sendMessage('Explain this Course in Simple examples.')} className='py-1.5 px-6 text-xs font-semibold text-white/30 rounded-full shadow-2xl bg-black/20 mb-3 outline outline-gray-400/5 cursor-pointer'>Explain in simple examples - props.sendMessage('Generate flashcards about this course and this lecture.')} className='py-1.5 px-6 text-xs font-semibold text-white/30 rounded-full shadow-2xl bg-black/20 mb-3 outline outline-gray-400/5 cursor-pointer'>Generate flashcards - props.sendMessage('Break down this Course in concepts.')} className='py-1.5 px-6 text-xs font-semibold text-white/30 rounded-full shadow-2xl bg-black/20 mb-3 outline outline-gray-400/5 cursor-pointer'>Break down in concepts -
+ + + +

+ Hello + + {session.user.username}, + + how can we help today ? +

+
+ + + + +
) } +const AIChatPredefinedQuestion = (props: { sendMessage: any, label: string }) => { + function getQuestion(label: string) { + if (label === 'about') { + return `What is this Activity about ?` + } else if (label === 'flashcards') { + return `Generate flashcards about this Activity` + } else if (label === 'examples') { + return `Explain this Activity in practical examples` + } + } + + return ( +
props.sendMessage(getQuestion(props.label))} className='flex space-x-1.5 items-center bg-white/5 cursor-pointer px-4 py-1.5 rounded-xl outline outline-1 outline-neutral-100/10 text-xs font-semibold text-white/40 hover:text-white/60 hover:bg-white/10 hover:outline-neutral-200/40 delay-75 ease-linear transition-all'> + {props.label === 'about' && } + {props.label === 'flashcards' && } + {props.label === 'examples' &&
Ex
} + {getQuestion(props.label)} +
+ ) +} + export default AIActivityAsk \ No newline at end of file diff --git a/apps/web/components/Contexts/AI/AIChatBotContext.tsx b/apps/web/components/Contexts/AI/AIChatBotContext.tsx new file mode 100644 index 00000000..e7bd9cc3 --- /dev/null +++ b/apps/web/components/Contexts/AI/AIChatBotContext.tsx @@ -0,0 +1,69 @@ +import { AIMessage } from '@components/AI/AIActivityAsk'; +import React, { createContext, useContext, useReducer } from 'react' + + + +export const AIChatBotContext = createContext(null) as any; +export const AIChatBotDispatchContext = createContext(null) as any; + +export type AIChatBotStateTypes = { + + messages: AIMessage[], + isModalOpen: boolean, + aichat_uuid: string, + isWaitingForResponse: boolean, + chatInputValue: string +} + +function AIChatBotProvider({ children }: { children: React.ReactNode }) { + const [aiChatBotState, dispatchAIChatBot] = useReducer(aiChatBotReducer, + { + messages: [] as AIMessage[], + isModalOpen: false, + aichat_uuid: null, + isWaitingForResponse: false, + chatInputValue: '' + } + ); + return ( + + + {children} + + + ) +} + +export default AIChatBotProvider + +export function useAIChatBot() { + return useContext(AIChatBotContext); +} + +export function useAIChatBotDispatch() { + return useContext(AIChatBotDispatchContext); +} + +function aiChatBotReducer(state: any, action: any) { + switch (action.type) { + case 'setMessages': + return { ...state, messages: action.payload }; + case 'addMessage': + return { ...state, messages: [...state.messages, action.payload] }; + case 'setIsModalOpen': + return { ...state, isModalOpen: true }; + case 'setIsModalClose': + return { ...state, isModalOpen: false }; + case 'setAichat_uuid': + return { ...state, aichat_uuid: action.payload }; + case 'setIsWaitingForResponse': + return { ...state, isWaitingForResponse: true }; + case 'setIsNoLongerWaitingForResponse': + return { ...state, isWaitingForResponse: false }; + case 'setChatInputValue': + return { ...state, chatInputValue: action.payload }; + + default: + throw new Error(`Unhandled action type: ${action.type}`) + } +} \ No newline at end of file diff --git a/apps/web/components/Contexts/Editor/EditorContext.tsx b/apps/web/components/Contexts/Editor/EditorContext.tsx new file mode 100644 index 00000000..f38f08ff --- /dev/null +++ b/apps/web/components/Contexts/Editor/EditorContext.tsx @@ -0,0 +1,31 @@ +import React, { useState } from 'react' + + +export const EditorProviderContext = React.createContext(null) as any; + +type EditorProviderProps = { + children: React.ReactNode + options: EditorProviderState +} + +type EditorProviderState = { + isEditable: boolean +} + +function EditorOptionsProvider({ children, options }: EditorProviderProps) { + const [editorOptions, setEditorOptions] = useState(options); + + return ( + + {children} + + ) +} + +export default EditorOptionsProvider + +export function useEditorProvider() { + return React.useContext(EditorProviderContext); +} + + diff --git a/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx b/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx index 8c354034..8d2546f3 100644 --- a/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx +++ b/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx @@ -1,4 +1,4 @@ -import { useEditor, EditorContent } from "@tiptap/react"; +import { useEditor, EditorContent, BubbleMenu, EditorProvider } from "@tiptap/react"; import StarterKit from "@tiptap/starter-kit"; import styled from "styled-components" import Youtube from "@tiptap/extension-youtube"; @@ -22,16 +22,24 @@ import ts from 'highlight.js/lib/languages/typescript' import html from 'highlight.js/lib/languages/xml' import python from 'highlight.js/lib/languages/python' import java from 'highlight.js/lib/languages/java' +import { NoTextInput } from "@components/Objects/Editor/Extensions/NoTextInput/NoTextInput"; +import EditorOptionsProvider from "@components/Contexts/Editor/EditorContext"; +import AICanvaToolkit from "./Elements/AICanvaToolkit"; interface Editor { content: string; activity: any; - //course: any; } function Canva(props: Editor) { - const isEditable = false; + /** + * Important Note : This is a workaround to enable user interaction features to be implemented easily, like text selection, AI features and other planned features, this is set to true but otherwise it should be set to false. + * Another workaround is implemented below to disable the editor from being edited by the user by setting the caret-color to transparent and using a custom extension to filter out transactions that add/edit/remove text. + * To let the various Custom Extensions know that the editor is not editable, React context (EditorOptionsProvider) will be used instead of props.extension.options.editable. + */ + const isEditable = true; + // Code Block Languages for Lowlight lowlight.register('html', html) @@ -46,6 +54,7 @@ function Canva(props: Editor) { editable: isEditable, extensions: [ StarterKit, + NoTextInput, // Custom Extensions InfoCallout.configure({ editable: isEditable, @@ -87,21 +96,54 @@ function Canva(props: Editor) { content: props.content, }); + return ( - - - + + + + + + + + ); } + + const CanvaWrapper = styled.div` width: 100%; margin: 0 auto; + .bubble-menu { + display: flex; + background-color: #0D0D0D; + padding: 0.2rem; + border-radius: 0.5rem; + + button { + border: none; + background: none; + color: #FFF; + font-size: 0.85rem; + font-weight: 500; + padding: 0 0.2rem; + opacity: 0.6; + + &:hover, + &.is-active { + opacity: 1; + } + } +} + // disable chrome outline .ProseMirror { + // Workaround to disable editor from being edited by the user. + caret-color: transparent; + h1 { font-size: 30px; font-weight: 600; diff --git a/apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx b/apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx new file mode 100644 index 00000000..5619bae9 --- /dev/null +++ b/apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx @@ -0,0 +1,109 @@ +import React from 'react' +import { Editor } from '@tiptap/core'; +import learnhouseAI_icon from "public/learnhouse_ai_simple.png"; +import Image from 'next/image'; +import { BookOpen, FormInput, Languages, MoreVertical } from 'lucide-react'; +import { BubbleMenu } from '@tiptap/react'; +import ToolTip from '@components/StyledElements/Tooltip/Tooltip'; +import { AIChatBotStateTypes, useAIChatBot, useAIChatBotDispatch } from '@components/Contexts/AI/AIChatBotContext'; +import { sendActivityAIChatMessage, startActivityAIChatSession } from '@services/ai/ai'; + + + +type AICanvaToolkitProps = { + editor: Editor, + activity: any +} + +function AICanvaToolkit(props: AICanvaToolkitProps) { + return ( + +
+
AI
+
+ +
+
+ + + + +
+
+
+ ) +} + +function AIActionButton(props: { editor: Editor, label: string, activity: any }) { + const dispatchAIChatBot = useAIChatBotDispatch() as any; + const aiChatBotState = useAIChatBot() as AIChatBotStateTypes; + const [aichat_uuid, setAichat_uuid] = React.useState(''); + + async function handleAction(label: string) { + const selection = getTipTapEditorSelectedText(); + const prompt = getPrompt(label, selection); + dispatchAIChatBot({ type: 'setIsModalOpen' }); + await sendMessage(prompt); + + + } + + const getTipTapEditorSelectedText = () => { + const selection = props.editor.state.selection; + const from = selection.from; + const to = selection.to; + const text = props.editor.state.doc.textBetween(from, to); + return text; + } + + const getPrompt = (label: string, selection: string) => { + if (label === 'Explain') { + return `Explain this part of the course "${selection}" keep this course context in mind.` + } else if (label === 'Summarize') { + return `Summarize this "${selection}" with the course context in mind.` + } else if (label === 'Translate') { + return `Translate "${selection}" to another language.` + } else { + return `Give examples to understand "${selection}" better, if possible give context in the course.` + } + } + + const sendMessage = async (message: string) => { + if (aiChatBotState.aichat_uuid) { + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); + await dispatchAIChatBot({ type: 'setIsWaitingForResponse' }); + const response = await sendActivityAIChatMessage(message, aiChatBotState.aichat_uuid, props.activity.activity_uuid) + await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' }); + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); + + } else { + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); + await dispatchAIChatBot({ type: 'setIsWaitingForResponse' }); + const response = await startActivityAIChatSession(message, props.activity.activity_uuid) + await dispatchAIChatBot({ type: 'setAichat_uuid', payload: response.aichat_uuid }); + await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' }); + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); + } + } + + const tooltipLabel = props.label === 'Explain' ? 'Explain a word or a sentence with AI' : props.label === 'Summarize' ? 'Summarize a long paragraph or text with AI' : props.label === 'Translate' ? 'Translate to different languages with AI' : 'Give examples to understand better with AI' + return ( +
+ + + +
+ ) +} + +export default AICanvaToolkit \ No newline at end of file diff --git a/apps/web/components/Objects/Editor/Editor.tsx b/apps/web/components/Objects/Editor/Editor.tsx index 5d9028dd..93cac96b 100644 --- a/apps/web/components/Objects/Editor/Editor.tsx +++ b/apps/web/components/Objects/Editor/Editor.tsx @@ -1,6 +1,6 @@ 'use client'; import React from "react"; -import { useEditor, EditorContent } from "@tiptap/react"; +import { useEditor, EditorContent, BubbleMenu } from "@tiptap/react"; import StarterKit from "@tiptap/starter-kit"; import learnhouseIcon from "public/learnhouse_icon.png"; import { ToolbarButtons } from "./Toolbar/ToolbarButtons"; diff --git a/apps/web/components/Objects/Editor/Extensions/NoTextInput/NoTextInput.tsx b/apps/web/components/Objects/Editor/Extensions/NoTextInput/NoTextInput.tsx new file mode 100644 index 00000000..a9e5116b --- /dev/null +++ b/apps/web/components/Objects/Editor/Extensions/NoTextInput/NoTextInput.tsx @@ -0,0 +1,21 @@ +import { Extension } from '@tiptap/core'; +import { Plugin, PluginKey } from 'prosemirror-state'; + +export const NoTextInput = Extension.create({ + name: 'noTextInput', + + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey('noTextInput'), + filterTransaction: (transaction) => { + // If the transaction is adding text, stop it + return !transaction.docChanged || transaction.steps.every((step) => { + const { slice } = step.toJSON(); + return !slice || !slice.content.some((node: { type: string; }) => node.type === 'text'); + }); + }, + }), + ]; + }, + }); \ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index ac6a098e..54d55a89 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -29,7 +29,7 @@ "formik": "^2.2.9", "framer-motion": "^10.16.1", "lowlight": "^3.0.0", - "lucide-react": "^0.268.0", + "lucide-react": "^0.307.0", "next": "14.0.4", "re-resizable": "^6.9.9", "react": "^18.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 186be655..7c9c1e5b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -81,8 +81,8 @@ importers: specifier: ^3.0.0 version: 3.1.0 lucide-react: - specifier: ^0.268.0 - version: 0.268.0(react@18.2.0) + specifier: ^0.307.0 + version: 0.307.0(react@18.2.0) next: specifier: 14.0.4 version: 14.0.4(@babel/core@7.23.2)(react-dom@18.2.0)(react@18.2.0) @@ -4824,8 +4824,8 @@ packages: yallist: 4.0.0 dev: true - /lucide-react@0.268.0(react@18.2.0): - resolution: {integrity: sha512-XP/xY3ASJAViqNqVnDRcEfdxfRB7uNST8sqTLwZhL983ikmHMQ7qQak7ZxrnXOVhB3QDBawdr3ANq0P+iWHP/g==} + /lucide-react@0.307.0(react@18.2.0): + resolution: {integrity: sha512-+vZ+vUiWPZTMnLHURg4aoIaz6NHOWXVVcVd8iLROu1k4LbyjcnHIKmbjXHCmulz7XAYLWRVXzhJJgIr+Aq3vOg==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 dependencies: From 21f1f2fd9455a175061be92ee8cc57eefceefa7a Mon Sep 17 00:00:00 2001 From: swve Date: Sun, 7 Jan 2024 18:15:32 +0100 Subject: [PATCH 07/18] fix: use editable workaround for blocks --- .../[courseid]/activity/[activityuuid]/edit/page.tsx | 5 +++-- apps/web/components/Contexts/Editor/EditorContext.tsx | 1 + .../Extensions/Callout/Info/InfoCalloutComponent.tsx | 8 ++++++-- .../Editor/Extensions/Callout/Warning/WarningCallout.ts | 2 -- .../Callout/Warning/WarningCalloutComponent.tsx | 8 ++++++-- .../Editor/Extensions/Image/ImageBlockComponent.tsx | 8 ++++++-- .../MathEquation/MathEquationBlockComponent.tsx | 4 +++- .../Objects/Editor/Extensions/PDF/PDFBlockComponent.tsx | 5 ++++- .../Objects/Editor/Extensions/Quiz/QuizBlockComponent.tsx | 4 +++- .../Editor/Extensions/Video/VideoBlockComponent.tsx | 5 ++++- 10 files changed, 36 insertions(+), 14 deletions(-) diff --git a/apps/web/app/editor/course/[courseid]/activity/[activityuuid]/edit/page.tsx b/apps/web/app/editor/course/[courseid]/activity/[activityuuid]/edit/page.tsx index 06483373..672002a1 100644 --- a/apps/web/app/editor/course/[courseid]/activity/[activityuuid]/edit/page.tsx +++ b/apps/web/app/editor/course/[courseid]/activity/[activityuuid]/edit/page.tsx @@ -7,6 +7,7 @@ import { getActivityWithAuthHeader } from "@services/courses/activities"; import { getAccessTokenFromRefreshTokenCookie, getNewAccessTokenUsingRefreshTokenServer } from "@services/auth/auth"; import { getOrganizationContextInfo, getOrganizationContextInfoWithId } from "@services/organizations/orgs"; import SessionProvider from "@components/Contexts/SessionContext"; +import EditorOptionsProvider from "@components/Contexts/Editor/EditorContext"; type MetadataProps = { params: { orgslug: string, courseid: string, activityid: string }; @@ -38,11 +39,11 @@ const EditActivity = async (params: any) => { console.log('courseInfo', courseInfo) return ( -
+ -
+ ); } diff --git a/apps/web/components/Contexts/Editor/EditorContext.tsx b/apps/web/components/Contexts/Editor/EditorContext.tsx index f38f08ff..f39bf2a4 100644 --- a/apps/web/components/Contexts/Editor/EditorContext.tsx +++ b/apps/web/components/Contexts/Editor/EditorContext.tsx @@ -1,3 +1,4 @@ +'use client'; import React, { useState } from 'react' diff --git a/apps/web/components/Objects/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx b/apps/web/components/Objects/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx index e6037a5c..914f1a04 100644 --- a/apps/web/components/Objects/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx +++ b/apps/web/components/Objects/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx @@ -1,13 +1,17 @@ +import { useEditorProvider } from "@components/Contexts/Editor/EditorContext"; import { NodeViewContent, NodeViewWrapper } from "@tiptap/react"; import { AlertCircle } from "lucide-react"; import React from "react"; import styled from "styled-components"; function InfoCalloutComponent(props: any) { + const editorState = useEditorProvider() as any; + const isEditable = editorState.isEditable; + return ( - - + + ); diff --git a/apps/web/components/Objects/Editor/Extensions/Callout/Warning/WarningCallout.ts b/apps/web/components/Objects/Editor/Extensions/Callout/Warning/WarningCallout.ts index 526e417c..e7911cac 100644 --- a/apps/web/components/Objects/Editor/Extensions/Callout/Warning/WarningCallout.ts +++ b/apps/web/components/Objects/Editor/Extensions/Callout/Warning/WarningCallout.ts @@ -8,8 +8,6 @@ export default Node.create({ group: "block", draggable: true, content: "text*", - marks: "", - defining: true, // TODO : multi line support diff --git a/apps/web/components/Objects/Editor/Extensions/Callout/Warning/WarningCalloutComponent.tsx b/apps/web/components/Objects/Editor/Extensions/Callout/Warning/WarningCalloutComponent.tsx index d168350c..14338f97 100644 --- a/apps/web/components/Objects/Editor/Extensions/Callout/Warning/WarningCalloutComponent.tsx +++ b/apps/web/components/Objects/Editor/Extensions/Callout/Warning/WarningCalloutComponent.tsx @@ -1,13 +1,17 @@ +import { useEditorProvider } from "@components/Contexts/Editor/EditorContext"; import { NodeViewContent, NodeViewWrapper } from "@tiptap/react"; import { AlertTriangle } from "lucide-react"; import React from "react"; import styled from "styled-components"; function WarningCalloutComponent(props: any) { + const editorState = useEditorProvider() as any; + const isEditable = editorState.isEditable; + return ( - - + + ); diff --git a/apps/web/components/Objects/Editor/Extensions/Image/ImageBlockComponent.tsx b/apps/web/components/Objects/Editor/Extensions/Image/ImageBlockComponent.tsx index e34d59f0..7e6ed2ed 100644 --- a/apps/web/components/Objects/Editor/Extensions/Image/ImageBlockComponent.tsx +++ b/apps/web/components/Objects/Editor/Extensions/Image/ImageBlockComponent.tsx @@ -8,10 +8,14 @@ import { UploadIcon } from "@radix-ui/react-icons"; import { getActivityBlockMediaDirectory } from "@services/media/media"; import { useOrg } from "@components/Contexts/OrgContext"; import { useCourse } from "@components/Contexts/CourseContext"; +import { useEditorProvider } from "@components/Contexts/Editor/EditorContext"; function ImageBlockComponent(props: any) { const org = useOrg() as any; const course = useCourse() as any; + const editorState = useEditorProvider() as any; + + const isEditable = editorState.isEditable; const [image, setImage] = React.useState(null); const [isLoading, setIsLoading] = React.useState(false); const [blockObject, setblockObject] = React.useState(props.node.attrs.blockObject); @@ -39,8 +43,8 @@ function ImageBlockComponent(props: any) { return ( - {!blockObject && props.extension.options.editable && ( - + {!blockObject && isEditable && ( + {isLoading ? ( ) : ( diff --git a/apps/web/components/Objects/Editor/Extensions/MathEquation/MathEquationBlockComponent.tsx b/apps/web/components/Objects/Editor/Extensions/MathEquation/MathEquationBlockComponent.tsx index 4c2938cb..d7fe11c0 100644 --- a/apps/web/components/Objects/Editor/Extensions/MathEquation/MathEquationBlockComponent.tsx +++ b/apps/web/components/Objects/Editor/Extensions/MathEquation/MathEquationBlockComponent.tsx @@ -5,11 +5,13 @@ import "katex/dist/katex.min.css"; import { InlineMath, BlockMath } from "react-katex"; import { Edit, Save } from "lucide-react"; import Link from "next/link"; +import { useEditorProvider } from "@components/Contexts/Editor/EditorContext"; function MathEquationBlockComponent(props: any) { const [equation, setEquation] = React.useState(props.node.attrs.math_equation); const [isEditing, setIsEditing] = React.useState(true); - const isEditable = props.extension.options.editable; + const editorState = useEditorProvider() as any; + const isEditable = editorState.isEditable; const handleEquationChange = (event: React.ChangeEvent) => { setEquation(event.target.value); diff --git a/apps/web/components/Objects/Editor/Extensions/PDF/PDFBlockComponent.tsx b/apps/web/components/Objects/Editor/Extensions/PDF/PDFBlockComponent.tsx index b55f935f..4946f762 100644 --- a/apps/web/components/Objects/Editor/Extensions/PDF/PDFBlockComponent.tsx +++ b/apps/web/components/Objects/Editor/Extensions/PDF/PDFBlockComponent.tsx @@ -8,6 +8,7 @@ import { UploadIcon } from "@radix-ui/react-icons"; import { getActivityBlockMediaDirectory } from "@services/media/media"; import { useOrg } from "@components/Contexts/OrgContext"; import { useCourse } from "@components/Contexts/CourseContext"; +import { useEditorProvider } from "@components/Contexts/Editor/EditorContext"; function PDFBlockComponent(props: any) { const org = useOrg() as any; @@ -16,6 +17,8 @@ function PDFBlockComponent(props: any) { const [isLoading, setIsLoading] = React.useState(false); const [blockObject, setblockObject] = React.useState(props.node.attrs.blockObject); const fileId = blockObject ? `${blockObject.content.file_id}.${blockObject.content.file_format}` : null; + const editorState = useEditorProvider() as any; + const isEditable = editorState.isEditable; const handlePDFChange = (event: React.ChangeEvent) => { setPDF(event.target.files[0]); @@ -39,7 +42,7 @@ function PDFBlockComponent(props: any) { return ( {!blockObject && ( - + {isLoading ? ( ) : ( diff --git a/apps/web/components/Objects/Editor/Extensions/Quiz/QuizBlockComponent.tsx b/apps/web/components/Objects/Editor/Extensions/Quiz/QuizBlockComponent.tsx index c3e350f2..d0cc0db0 100644 --- a/apps/web/components/Objects/Editor/Extensions/Quiz/QuizBlockComponent.tsx +++ b/apps/web/components/Objects/Editor/Extensions/Quiz/QuizBlockComponent.tsx @@ -4,6 +4,7 @@ import { twJoin, twMerge } from 'tailwind-merge' import React from "react"; import { BadgeHelp, Check, Info, Minus, MoreVertical, Plus, RefreshCcw, X } from "lucide-react"; import ReactConfetti from "react-confetti"; +import { useEditorProvider } from "@components/Contexts/Editor/EditorContext"; interface Answer { answer_id: string; @@ -22,7 +23,8 @@ function QuizBlockComponent(props: any) { const [userAnswers, setUserAnswers] = React.useState([]) as [any[], any]; const [submitted, setSubmitted] = React.useState(false) as [boolean, any]; const [submissionMessage, setSubmissionMessage] = React.useState("") as [string, any]; - const isEditable = props.extension.options.editable; + const editorState = useEditorProvider() as any; + const isEditable = editorState.isEditable; const handleAnswerClick = (question_id: string, answer_id: string) => { // if the quiz is submitted, do nothing diff --git a/apps/web/components/Objects/Editor/Extensions/Video/VideoBlockComponent.tsx b/apps/web/components/Objects/Editor/Extensions/Video/VideoBlockComponent.tsx index 7f5a0b3d..1b597ac8 100644 --- a/apps/web/components/Objects/Editor/Extensions/Video/VideoBlockComponent.tsx +++ b/apps/web/components/Objects/Editor/Extensions/Video/VideoBlockComponent.tsx @@ -8,10 +8,13 @@ import { getActivityBlockMediaDirectory } from "@services/media/media"; import { UploadIcon } from "@radix-ui/react-icons"; import { useOrg } from "@components/Contexts/OrgContext"; import { useCourse } from "@components/Contexts/CourseContext"; +import { useEditorProvider } from "@components/Contexts/Editor/EditorContext"; function VideoBlockComponents(props: any) { const org = useOrg() as any; const course = useCourse() as any; + const editorState = useEditorProvider() as any; + const isEditable = editorState.isEditable; const [video, setVideo] = React.useState(null); const [isLoading, setIsLoading] = React.useState(false); const [blockObject, setblockObject] = React.useState(props.node.attrs.blockObject); @@ -39,7 +42,7 @@ function VideoBlockComponents(props: any) { return ( {!blockObject && ( - + {isLoading ? ( ) : ( From 5b79cbed8934f351365ab53696c7c9aa079f3887 Mon Sep 17 00:00:00 2001 From: swve Date: Thu, 11 Jan 2024 01:39:43 +0100 Subject: [PATCH 08/18] feat: init ai editor writer and continue writing feature --- apps/api/src/services/ai/ai.py | 2 +- apps/api/src/services/ai/base.py | 3 +- .../activity/[activityuuid]/edit/page.tsx | 11 +- apps/web/components/AI/AIActivityAsk.tsx | 10 +- .../Contexts/AI/AIChatBotContext.tsx | 4 +- .../Contexts/AI/AIEditorContext.tsx | 82 +++++ .../Activities/DynamicCanva/DynamicCanva.tsx | 2 +- .../DynamicCanva/Elements/AICanvaToolkit.tsx | 6 +- .../Objects/Editor/AI/AIEditorToolkit.tsx | 308 ++++++++++++++++++ apps/web/components/Objects/Editor/Editor.tsx | 41 ++- .../Objects/Editor/Toolbar/ToolbarButtons.tsx | 6 +- .../public/learnhouse_ai_simple_colored.png | Bin 0 -> 29183 bytes 12 files changed, 446 insertions(+), 29 deletions(-) create mode 100644 apps/web/components/Contexts/AI/AIEditorContext.tsx create mode 100644 apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx create mode 100644 apps/web/public/learnhouse_ai_simple_colored.png diff --git a/apps/api/src/services/ai/ai.py b/apps/api/src/services/ai/ai.py index bc776962..e0e21e3e 100644 --- a/apps/api/src/services/ai/ai.py +++ b/apps/api/src/services/ai/ai.py @@ -117,7 +117,7 @@ def ai_send_activity_chat_message( ) # Get Activity Content Blocks - content = activity.content + content = activity.content # Serialize Activity Content Blocks to a text comprehensible by the AI structured = structure_activity_content_by_type(content) diff --git a/apps/api/src/services/ai/base.py b/apps/api/src/services/ai/base.py index 02674e92..f2356fa2 100644 --- a/apps/api/src/services/ai/base.py +++ b/apps/api/src/services/ai/base.py @@ -59,7 +59,7 @@ def ask_ai( memory_key = "history" memory = AgentTokenBufferMemory( - memory_key=memory_key, llm=llm, chat_memory=message_history + memory_key=memory_key, llm=llm, chat_memory=message_history, max_tokens=1000 ) system_message = SystemMessage(content=(message_for_the_prompt)) @@ -77,6 +77,7 @@ def ask_ai( memory=memory, verbose=True, return_intermediate_steps=True, + handle_parsing_errors=True, ) return agent_executor({"input": question}) diff --git a/apps/web/app/editor/course/[courseid]/activity/[activityuuid]/edit/page.tsx b/apps/web/app/editor/course/[courseid]/activity/[activityuuid]/edit/page.tsx index 672002a1..f648cd84 100644 --- a/apps/web/app/editor/course/[courseid]/activity/[activityuuid]/edit/page.tsx +++ b/apps/web/app/editor/course/[courseid]/activity/[activityuuid]/edit/page.tsx @@ -8,6 +8,8 @@ import { getAccessTokenFromRefreshTokenCookie, getNewAccessTokenUsingRefreshToke import { getOrganizationContextInfo, getOrganizationContextInfoWithId } from "@services/organizations/orgs"; import SessionProvider from "@components/Contexts/SessionContext"; import EditorOptionsProvider from "@components/Contexts/Editor/EditorContext"; +import AIChatBotProvider from "@components/Contexts/AI/AIChatBotContext"; +import AIEditorProvider from "@components/Contexts/AI/AIEditorContext"; type MetadataProps = { params: { orgslug: string, courseid: string, activityid: string }; @@ -36,13 +38,14 @@ const EditActivity = async (params: any) => { const courseInfo = await getCourseMetadataWithAuthHeader(courseid, { revalidate: 0, tags: ['courses'] }, access_token ? access_token : null) const activity = await getActivityWithAuthHeader(activityuuid, { revalidate: 0, tags: ['activities'] }, access_token ? access_token : null) const org = await getOrganizationContextInfoWithId(courseInfo.org_id, { revalidate: 1800, tags: ['organizations'] }); - console.log('courseInfo', courseInfo) return ( - - - + + + + + ); } diff --git a/apps/web/components/AI/AIActivityAsk.tsx b/apps/web/components/AI/AIActivityAsk.tsx index 6ae62c49..c30f315d 100644 --- a/apps/web/components/AI/AIActivityAsk.tsx +++ b/apps/web/components/AI/AIActivityAsk.tsx @@ -31,10 +31,10 @@ function AIActivityAsk(props: AIActivityAskProps) { style={{ background: 'conic-gradient(from 32deg at 53.75% 50%, rgb(35, 40, 93) 4deg, rgba(20, 0, 52, 0.95) 59deg, rgba(164, 45, 238, 0.88) 281deg)', }} - className="rounded-full px-5 drop-shadow-md flex items-center space-x-1 p-2.5 text-sm text-white hover:cursor-pointer transition delay-150 duration-300 ease-in-out hover:scale-105"> + className="rounded-full px-5 drop-shadow-md flex items-center space-x-1.5 p-2.5 text-sm text-white hover:cursor-pointer transition delay-150 duration-300 ease-in-out hover:scale-105"> {" "} - + {" "} Ask AI
@@ -59,8 +59,8 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { // TODO : come up with a better way to handle this const inputClass = aiChatBotState.isWaitingForResponse - ? 'ring-1 ring-inset ring-white/10 bg-transparent w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30 opacity-30 ' - : 'ring-1 ring-inset ring-white/10 bg-transparent w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30'; + ? 'ring-1 ring-inset ring-white/10 bg-gray-950/40 w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30 opacity-30 ' + : 'ring-1 ring-inset ring-white/10 bg-gray-950/40 w-full rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30'; useEffect(() => { if (aiChatBotState.isModalOpen) { @@ -141,7 +141,7 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) {
- + AI
diff --git a/apps/web/components/Contexts/AI/AIChatBotContext.tsx b/apps/web/components/Contexts/AI/AIChatBotContext.tsx index e7bd9cc3..d39d93e7 100644 --- a/apps/web/components/Contexts/AI/AIChatBotContext.tsx +++ b/apps/web/components/Contexts/AI/AIChatBotContext.tsx @@ -1,8 +1,6 @@ +'use client'; import { AIMessage } from '@components/AI/AIActivityAsk'; import React, { createContext, useContext, useReducer } from 'react' - - - export const AIChatBotContext = createContext(null) as any; export const AIChatBotDispatchContext = createContext(null) as any; diff --git a/apps/web/components/Contexts/AI/AIEditorContext.tsx b/apps/web/components/Contexts/AI/AIEditorContext.tsx new file mode 100644 index 00000000..aa314032 --- /dev/null +++ b/apps/web/components/Contexts/AI/AIEditorContext.tsx @@ -0,0 +1,82 @@ +'use client'; +import { AIMessage } from '@components/AI/AIActivityAsk'; +import React, { createContext, useContext, useReducer } from 'react' +export const AIEditorContext = createContext(null) as any; +export const AIEditorDispatchContext = createContext(null) as any; + +export type AIEditorStateTypes = { + + messages: AIMessage[], + isModalOpen: boolean, + isFeedbackModalOpen: boolean, + aichat_uuid: string, + isWaitingForResponse: boolean, + chatInputValue: string, + selectedTool: 'Writer' | 'ContinueWriting' | 'MakeLonger' | 'GenerateQuiz' | 'Translate' + isUserInputEnabled: boolean +} + +function AIEditorProvider({ children }: { children: React.ReactNode }) { + const [aIEditorState, dispatchAIEditor] = useReducer(aIEditorReducer, + { + messages: [] as AIMessage[], + isModalOpen: false, + isFeedbackModalOpen: false, + aichat_uuid: null, + isWaitingForResponse: false, + chatInputValue: '', + selectedTool: 'Writer', + isUserInputEnabled: true + } + ); + return ( + + + {children} + + + ) +} + +export default AIEditorProvider + +export function useAIEditor() { + return useContext(AIEditorContext); +} + +export function useAIEditorDispatch() { + return useContext(AIEditorDispatchContext); +} + +function aIEditorReducer(state: any, action: any) { + switch (action.type) { + case 'setMessages': + return { ...state, messages: action.payload }; + case 'addMessage': + return { ...state, messages: [...state.messages, action.payload] }; + case 'setIsModalOpen': + return { ...state, isModalOpen: true }; + case 'setIsModalClose': + return { ...state, isModalOpen: false }; + case 'setAichat_uuid': + return { ...state, aichat_uuid: action.payload }; + case 'setIsWaitingForResponse': + return { ...state, isWaitingForResponse: true }; + case 'setIsNoLongerWaitingForResponse': + return { ...state, isWaitingForResponse: false }; + case 'setChatInputValue': + return { ...state, chatInputValue: action.payload }; + case 'setSelectedTool': + return { ...state, selectedTool: action.payload }; + case 'setIsFeedbackModalOpen': + return { ...state, isFeedbackModalOpen: true }; + case 'setIsFeedbackModalClose': + return { ...state, isFeedbackModalOpen: false }; + case 'setIsUserInputEnabled': + return { ...state, isUserInputEnabled: action.payload }; + + + default: + throw new Error(`Unhandled action type: ${action.type}`) + } +} \ No newline at end of file diff --git a/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx b/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx index 8d2546f3..d4685919 100644 --- a/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx +++ b/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx @@ -101,7 +101,7 @@ function Canva(props: Editor) { - + diff --git a/apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx b/apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx index 5619bae9..4d53d921 100644 --- a/apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx +++ b/apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx @@ -21,7 +21,7 @@ function AICanvaToolkit(props: AICanvaToolkitProps) {
-
AI
+
AI
@@ -39,15 +39,13 @@ function AICanvaToolkit(props: AICanvaToolkitProps) { function AIActionButton(props: { editor: Editor, label: string, activity: any }) { const dispatchAIChatBot = useAIChatBotDispatch() as any; const aiChatBotState = useAIChatBot() as AIChatBotStateTypes; - const [aichat_uuid, setAichat_uuid] = React.useState(''); async function handleAction(label: string) { const selection = getTipTapEditorSelectedText(); const prompt = getPrompt(label, selection); dispatchAIChatBot({ type: 'setIsModalOpen' }); await sendMessage(prompt); - - + } const getTipTapEditorSelectedText = () => { diff --git a/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx new file mode 100644 index 00000000..46a01045 --- /dev/null +++ b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx @@ -0,0 +1,308 @@ +import React from 'react' +import learnhouseAI_icon from "public/learnhouse_ai_simple.png"; +import { motion, AnimatePresence } from 'framer-motion'; +import Image from 'next/image'; +import { BetweenHorizontalStart, FastForward, Feather, FileStack, HelpCircle, Languages, MessageCircle, MoreVertical, Pen, X } from 'lucide-react'; +import { Editor } from '@tiptap/react'; +import { AIChatBotStateTypes, useAIChatBot, useAIChatBotDispatch } from '@components/Contexts/AI/AIChatBotContext'; +import { AIEditorStateTypes, useAIEditor, useAIEditorDispatch } from '@components/Contexts/AI/AIEditorContext'; +import { sendActivityAIChatMessage, startActivityAIChatSession } from '@services/ai/ai'; + +type AIEditorToolkitProps = { + editor: Editor, + activity: any +} + +type AIPromptsLabels = { + label: 'Writer' | 'ContinueWriting' | 'MakeLonger' | 'GenerateQuiz' | 'Translate', + selection: string + +} + +function AIEditorToolkit(props: AIEditorToolkitProps) { + const dispatchAIEditor = useAIEditorDispatch() as any; + const aiEditorState = useAIEditor() as AIEditorStateTypes; + + + return ( + + {aiEditorState.isModalOpen && + <> + {aiEditorState.isFeedbackModalOpen && } +
+
+
+
+ +
AI Editor
+ +
+
+
+ + + + + +
+
+ Promise.all([dispatchAIEditor({ type: 'setIsModalClose' }), dispatchAIEditor({ type: 'setIsFeedbackModalClose' })])} size={20} className='text-white/50 hover:cursor-pointer bg-white/10 p-1 rounded-full items-center' /> +
+
+
+
} +
+ ) +} + + +const UserFeedbackModal = (props: AIEditorToolkitProps) => { + const dispatchAIEditor = useAIEditorDispatch() as any; + const aiEditorState = useAIEditor() as AIEditorStateTypes; + + const handleChange = async (event: React.ChangeEvent) => { + await dispatchAIEditor({ type: 'setChatInputValue', payload: event.currentTarget.value }); + + } + + const sendReqWithMessage = async (message: string) => { + if (aiEditorState.aichat_uuid) { + await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); + await dispatchAIEditor({ type: 'setIsWaitingForResponse' }); + const response = await sendActivityAIChatMessage(message, aiEditorState.aichat_uuid, props.activity.activity_uuid) + await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIEditor({ type: 'setChatInputValue', payload: '' }); + await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); + return response.message; + + } else { + await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); + await dispatchAIEditor({ type: 'setIsWaitingForResponse' }); + const response = await startActivityAIChatSession(message, props.activity.activity_uuid) + await dispatchAIEditor({ type: 'setAichat_uuid', payload: response.aichat_uuid }); + await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIEditor({ type: 'setChatInputValue', payload: '' }); + await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); + return response.message; + } + } + + const handleKeyPress = async (event: React.KeyboardEvent) => { + if (event.key === 'Enter') { + await handleOperation(aiEditorState.selectedTool, aiEditorState.chatInputValue); + } + } + + const handleOperation = async (label: 'Writer' | 'ContinueWriting' | 'MakeLonger' | 'GenerateQuiz' | 'Translate', message: string) => { + // Set selected tool + await dispatchAIEditor({ type: 'setSelectedTool', payload: label }); + + // Check what operation that was + if (label === 'Writer') { + let ai_message = ''; + let prompt = getPrompt({ label: label, selection: message }); + if (prompt) { + ai_message = await sendReqWithMessage(prompt); + await fillEditorWithText(ai_message); + } + } else if (label === 'ContinueWriting') { + let ai_message = ''; + let text_selection = getTipTapEditorSelectedText(); + let prompt = getPrompt({ label: label, selection: text_selection }); + if (prompt) { + ai_message = await sendReqWithMessage(prompt); + const message_without_original_text = await removeSentences(text_selection, ai_message); + await fillEditorWithText(message_without_original_text); + } + } else if (label === 'MakeLonger') { + // Send message to AI + // Wait for response + // Add response to editor + // Close modal + + } else if (label === 'GenerateQuiz') { + // Send message to AI + // Wait for response + // Add response to editor + // Close modal + } else if (label === 'Translate') { + // Send message to AI + // Wait for response + // Add response to editor + // Close modal + } + } + + const removeSentences = async (textToRemove: string, originalText: string) => { + const phrase = textToRemove.toLowerCase(); + const original = originalText.toLowerCase(); + + if (original.includes(phrase)) { + const regex = new RegExp(phrase, 'g'); + const newText = original.replace(regex, ''); + return newText; + } else { + return originalText; + } + } + + async function fillEditorWithText(text: string) { + const words = text.split(' '); + + for (let i = 0; i < words.length; i++) { + const textNode = { + type: 'text', + text: words[i], + }; + + props.editor.chain().focus().insertContent(textNode).run(); + + // Add a space after each word except the last one + if (i < words.length - 1) { + const spaceNode = { + type: 'text', + text: ' ', + }; + + props.editor.chain().focus().insertContent(spaceNode).run(); + } + + // Wait for 0.3 seconds before adding the next word + await new Promise(resolve => setTimeout(resolve, 120)); + } + } + + const getPrompt = (args: AIPromptsLabels) => { + const { label, selection } = args; + + if (label === 'Writer') { + return `Write 3 sentences about ${selection}`; + } else if (label === 'ContinueWriting') { + return `Continue writing 3 more sentences based on "${selection}"`; + } else if (label === 'MakeLonger') { + return `Make longer this paragraph "${selection}"`; + } else if (label === 'GenerateQuiz') { + return `Generate a quiz about "${selection}", only return an array of objects, every object should respect the following interface: + interface Answer { + answer_id: string; + answer: string; + correct: boolean; + } + interface Question { + question_id: string; + question: string; + type: "multiple_choice" + answers: Answer[]; + } + " `; + } else if (label === 'Translate') { + return `Translate ${selection} to selected language`; + } + } + + const getTipTapEditorSelectedText = () => { + const pos = props.editor.state.selection.$from.pos; // get the cursor position + const resolvedPos = props.editor.state.doc.resolve(pos); // resolve the position in the document + const start = resolvedPos.before(1); // get the start position of the node + const end = resolvedPos.after(1); // get the end position of the node + const paragraph = props.editor.state.doc.textBetween(start, end, '\n', '\n'); // get the text of the node + return paragraph; + } + + + return ( + +
+
+ +
+
+
+ +
+
+ {aiEditorState.isUserInputEnabled &&
+ +
+ +
+
} +
+
+ ) +} + +const AiEditorToolButton = (props: any) => { + const dispatchAIEditor = useAIEditorDispatch() as any; + const aiEditorState = useAIEditor() as AIEditorStateTypes; + + const handleToolButtonClick = async (label: 'Writer' | 'ContinueWriting' | 'MakeLonger' | 'GenerateQuiz' | 'Translate') => { + if (label === 'Writer') { + await dispatchAIEditor({ type: 'setSelectedTool', payload: label }); + await dispatchAIEditor({ type: 'setIsUserInputEnabled', payload: true }); + await dispatchAIEditor({ type: 'setIsFeedbackModalOpen' }); + } + if (label === 'ContinueWriting') { + await dispatchAIEditor({ type: 'setSelectedTool', payload: label }); + await dispatchAIEditor({ type: 'setIsUserInputEnabled', payload: false }); + await dispatchAIEditor({ type: 'setIsFeedbackModalOpen' }); + } + } + + return ( + + ) +} + +const AiEditorActionScreen = ({ handleOperation }: { handleOperation: any }) => { + const dispatchAIEditor = useAIEditorDispatch() as any; + const aiEditorState = useAIEditor() as AIEditorStateTypes; + return ( +
+ {aiEditorState.selectedTool === 'Writer' && +
+ Write about... +
} + {aiEditorState.selectedTool === 'ContinueWriting' && +
{ + handleOperation(aiEditorState.selectedTool, aiEditorState.chatInputValue) + }} className='flex cursor-pointer space-x-1.5 p-4 items-center bg-white/10 rounded-md outline outline-1 outline-neutral-200/20 text-2xl font-semibold text-white/70 hover:bg-white/20 hover:outline-neutral-200/40 delay-75 ease-linear transition-all'> + +
} +
+ ) +} + + +export default AIEditorToolkit \ No newline at end of file diff --git a/apps/web/components/Objects/Editor/Editor.tsx b/apps/web/components/Objects/Editor/Editor.tsx index 93cac96b..6da8402e 100644 --- a/apps/web/components/Objects/Editor/Editor.tsx +++ b/apps/web/components/Objects/Editor/Editor.tsx @@ -9,6 +9,9 @@ import Image from "next/image"; import styled from "styled-components"; import { DividerVerticalIcon, SlashIcon } from "@radix-ui/react-icons"; import Avvvatars from "avvvatars-react"; +import learnhouseAI_icon from "public/learnhouse_ai_simple.png"; +import { AIEditorStateTypes, useAIEditor, useAIEditorDispatch } from "@components/Contexts/AI/AIEditorContext"; + // extensions import InfoCallout from "./Extensions/Callout/Info/InfoCallout"; import WarningCallout from "./Extensions/Callout/Warning/WarningCallout"; @@ -38,6 +41,8 @@ import java from 'highlight.js/lib/languages/java' import { CourseProvider } from "@components/Contexts/CourseContext"; import { OrgProvider } from "@components/Contexts/OrgContext"; import { useSession } from "@components/Contexts/SessionContext"; +import AIEditorTools from "./AI/AIEditorToolkit"; +import AIEditorToolkit from "./AI/AIEditorToolkit"; interface Editor { @@ -52,6 +57,9 @@ interface Editor { function Editor(props: Editor) { const session = useSession() as any; + const dispatchAIEditor = useAIEditorDispatch() as any; + const aiEditorState = useAIEditor() as AIEditorStateTypes; + // remove course_ from course_uuid const course_uuid = props.course.course_uuid.substring(7); @@ -156,19 +164,30 @@ function Editor(props: Editor) { {" "} {props.course.name} {props.activity.name}{" "} - - - - {!session.isAuthenticated && Loading} - {session.isAuthenticated && } - + +
+
+
dispatchAIEditor({ type: aiEditorState.isModalOpen ? 'setIsModalClose' : 'setIsModalOpen' })} + style={{ + background: 'conic-gradient(from 32deg at 53.75% 50%, rgb(35, 40, 93) 4deg, rgba(20, 0, 52, 0.95) 59deg, rgba(164, 45, 238, 0.88) 281deg)', + }} + className="rounded-md px-3 py-2 drop-shadow-md flex items-center space-x-1.5 text-sm text-white hover:cursor-pointer transition delay-150 duration-300 ease-in-out hover:scale-105"> + {" "} + + + {" "} + AI Editor +
+
+
- +
props.setContent(editor.getJSON())}> Save
@@ -178,6 +197,13 @@ function Editor(props: Editor) {
+ + + + {!session.isAuthenticated && Loading} + {session.isAuthenticated && } + +
@@ -193,6 +219,7 @@ function Editor(props: Editor) { exit={{ opacity: 0 }} > + diff --git a/apps/web/components/Objects/Editor/Toolbar/ToolbarButtons.tsx b/apps/web/components/Objects/Editor/Toolbar/ToolbarButtons.tsx index 3e910195..65e53b23 100644 --- a/apps/web/components/Objects/Editor/Toolbar/ToolbarButtons.tsx +++ b/apps/web/components/Objects/Editor/Toolbar/ToolbarButtons.tsx @@ -1,15 +1,15 @@ import styled from "styled-components"; -import { FontBoldIcon, FontItalicIcon, StrikethroughIcon, ArrowLeftIcon, ArrowRightIcon, OpacityIcon, DividerVerticalIcon, ListBulletIcon } from "@radix-ui/react-icons"; -import { AlertCircle, AlertTriangle, BadgeHelp, Code, FileText, GraduationCap, HelpCircle, ImagePlus, Info, ListChecks, Sigma, Video, Youtube } from "lucide-react"; +import { FontBoldIcon, FontItalicIcon, StrikethroughIcon, ArrowLeftIcon, ArrowRightIcon, DividerVerticalIcon, ListBulletIcon } from "@radix-ui/react-icons"; +import { AlertCircle, AlertTriangle, BadgeHelp, Code, FileText, ImagePlus, Sigma, Video, Youtube } from "lucide-react"; import ToolTip from "@components/StyledElements/Tooltip/Tooltip"; export const ToolbarButtons = ({ editor, props }: any) => { + if (!editor) { return null; } // YouTube extension - const addYoutubeVideo = () => { const url = prompt("Enter YouTube URL"); diff --git a/apps/web/public/learnhouse_ai_simple_colored.png b/apps/web/public/learnhouse_ai_simple_colored.png new file mode 100644 index 0000000000000000000000000000000000000000..af78fbc415c86369f0da7a26ad23893947e96ad9 GIT binary patch literal 29183 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

*?!Y*(f;y%C*~Aj0c7!Vw(d9 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 a?SBA}`wr}dr~jn@0000 Date: Thu, 11 Jan 2024 21:52:42 +0100 Subject: [PATCH 09/18] feat: add ai makelonger + translating features --- .../Objects/Editor/AI/AIEditorToolkit.tsx | 165 +++++++++++++++--- 1 file changed, 138 insertions(+), 27 deletions(-) diff --git a/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx index 46a01045..b4a7824b 100644 --- a/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx +++ b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx @@ -54,7 +54,7 @@ function AIEditorToolkit(props: AIEditorToolkitProps) { - +

@@ -113,42 +113,58 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => { if (label === 'Writer') { let ai_message = ''; let prompt = getPrompt({ label: label, selection: message }); + await dispatchAIEditor({ type: 'setIsUserInputEnabled', payload: true }); if (prompt) { + await dispatchAIEditor({ type: 'setIsUserInputEnabled', payload: false }); + await dispatchAIEditor({ type: 'setIsWaitingForResponse' }); ai_message = await sendReqWithMessage(prompt); await fillEditorWithText(ai_message); + await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIEditor({ type: 'setIsUserInputEnabled', payload: true }); } } else if (label === 'ContinueWriting') { + let ai_message = ''; + let text_selection = getTipTapEditorSelectedTextGlobal(); + let prompt = getPrompt({ label: label, selection: text_selection }); + if (prompt) { + await dispatchAIEditor({ type: 'setIsWaitingForResponse' }); + ai_message = await sendReqWithMessage(prompt); + const message_without_original_text = await removeSentences(text_selection, ai_message); + await fillEditorWithText(message_without_original_text); + await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); + } + } else if (label === 'MakeLonger') { let ai_message = ''; let text_selection = getTipTapEditorSelectedText(); let prompt = getPrompt({ label: label, selection: text_selection }); if (prompt) { + await dispatchAIEditor({ type: 'setIsWaitingForResponse' }); ai_message = await sendReqWithMessage(prompt); - const message_without_original_text = await removeSentences(text_selection, ai_message); - await fillEditorWithText(message_without_original_text); + await replaceSelectedTextWithText(ai_message); + await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); } - } else if (label === 'MakeLonger') { - // Send message to AI - // Wait for response - // Add response to editor - // Close modal - } else if (label === 'GenerateQuiz') { // Send message to AI // Wait for response // Add response to editor // Close modal } else if (label === 'Translate') { - // Send message to AI - // Wait for response - // Add response to editor - // Close modal + let ai_message = ''; + let text_selection = getTipTapEditorSelectedText(); + let prompt = getPrompt({ label: label, selection: text_selection }); + if (prompt) { + await dispatchAIEditor({ type: 'setIsWaitingForResponse' }); + ai_message = await sendReqWithMessage(prompt); + await replaceSelectedTextWithText(ai_message); + await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); + } } } const removeSentences = async (textToRemove: string, originalText: string) => { const phrase = textToRemove.toLowerCase(); const original = originalText.toLowerCase(); - + if (original.includes(phrase)) { const regex = new RegExp(phrase, 'g'); const newText = original.replace(regex, ''); @@ -184,6 +200,35 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => { } } + async function replaceSelectedTextWithText(text: string) { + const words = text.split(' '); + + // Delete the selected text + props.editor.chain().focus().deleteSelection().run(); + + for (let i = 0; i < words.length; i++) { + const textNode = { + type: 'text', + text: words[i], + }; + + props.editor.chain().focus().insertContent(textNode).run(); + + // Add a space after each word except the last one + if (i < words.length - 1) { + const spaceNode = { + type: 'text', + text: ' ', + }; + + props.editor.chain().focus().insertContent(spaceNode).run(); + } + + // Wait for 0.3 seconds before adding the next word + await new Promise(resolve => setTimeout(resolve, 120)); + } + } + const getPrompt = (args: AIPromptsLabels) => { const { label, selection } = args; @@ -192,7 +237,7 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => { } else if (label === 'ContinueWriting') { return `Continue writing 3 more sentences based on "${selection}"`; } else if (label === 'MakeLonger') { - return `Make longer this paragraph "${selection}"`; + return `Make longer this text longer : "${selection}"`; } else if (label === 'GenerateQuiz') { return `Generate a quiz about "${selection}", only return an array of objects, every object should respect the following interface: interface Answer { @@ -208,11 +253,12 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => { } " `; } else if (label === 'Translate') { - return `Translate ${selection} to selected language`; + return `Translate "${selection}" to the ` + aiEditorState.chatInputValue + ` language`; } } - const getTipTapEditorSelectedText = () => { + const getTipTapEditorSelectedTextGlobal = () => { + // Get the entire node/paragraph that the user is in const pos = props.editor.state.selection.$from.pos; // get the cursor position const resolvedPos = props.editor.state.doc.resolve(pos); // resolve the position in the document const start = resolvedPos.before(1); // get the start position of the node @@ -221,6 +267,14 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => { return paragraph; } + const getTipTapEditorSelectedText = () => { + const selection = props.editor.state.selection; + const from = selection.from; + const to = selection.to; + const text = props.editor.state.doc.textBetween(from, to); + return text; + } + return ( { animate={{ y: 0, opacity: 1, filter: 'blur(0px)' }} exit={{ y: 50, opacity: 0, filter: 'blur(3px)' }} transition={{ type: "spring", bounce: 0.35, duration: 1.7, mass: 0.2, velocity: 2 }} - className='fixed top-0 left-0 w-full h-full z-50 flex justify-center items-center ' + className='backdrop-blur-md fixed top-0 left-0 w-full h-full z-50 flex justify-center items-center ' style={{ pointerEvents: 'none' }} >
+ className="backdrop-blur-md z-50 rounded-2xl max-w-screen-2xl my-10 mx-auto w-[500px] h-[200px] fixed bottom-16 left-1/2 transform -translate-x-1/2 shadow-xl ring-1 ring-inset ring-white/10 text-white p-3 flex-col-reverse">
@@ -271,6 +325,21 @@ const AiEditorToolButton = (props: any) => { await dispatchAIEditor({ type: 'setIsUserInputEnabled', payload: false }); await dispatchAIEditor({ type: 'setIsFeedbackModalOpen' }); } + if (label === 'MakeLonger') { + await dispatchAIEditor({ type: 'setSelectedTool', payload: label }); + await dispatchAIEditor({ type: 'setIsUserInputEnabled', payload: false }); + await dispatchAIEditor({ type: 'setIsFeedbackModalOpen' }); + } + if (label === 'GenerateQuiz') { + await dispatchAIEditor({ type: 'setSelectedTool', payload: label }); + await dispatchAIEditor({ type: 'setIsUserInputEnabled', payload: false }); + await dispatchAIEditor({ type: 'setIsFeedbackModalOpen' }); + } + if (label === 'Translate') { + await dispatchAIEditor({ type: 'setSelectedTool', payload: label }); + await dispatchAIEditor({ type: 'setIsUserInputEnabled', payload: false }); + await dispatchAIEditor({ type: 'setIsFeedbackModalOpen' }); + } } return ( @@ -288,18 +357,60 @@ const AiEditorToolButton = (props: any) => { const AiEditorActionScreen = ({ handleOperation }: { handleOperation: any }) => { const dispatchAIEditor = useAIEditorDispatch() as any; const aiEditorState = useAIEditor() as AIEditorStateTypes; + + const handleChange = async (event: React.ChangeEvent) => { + await dispatchAIEditor({ type: 'setChatInputValue', payload: event.currentTarget.value }); + + } + return (
- {aiEditorState.selectedTool === 'Writer' && -
+ {aiEditorState.selectedTool === 'Writer' && !aiEditorState.isWaitingForResponse && +
Write about...
} - {aiEditorState.selectedTool === 'ContinueWriting' && -
{ - handleOperation(aiEditorState.selectedTool, aiEditorState.chatInputValue) - }} className='flex cursor-pointer space-x-1.5 p-4 items-center bg-white/10 rounded-md outline outline-1 outline-neutral-200/20 text-2xl font-semibold text-white/70 hover:bg-white/20 hover:outline-neutral-200/40 delay-75 ease-linear transition-all'> - + {aiEditorState.selectedTool === 'ContinueWriting' && !aiEditorState.isWaitingForResponse && +
+

Place your cursor at the end of a sentence to continue writing

+
{ + handleOperation(aiEditorState.selectedTool, aiEditorState.chatInputValue) + }} className='flex cursor-pointer space-x-1.5 p-4 mt-4 items-center bg-white/10 rounded-md outline outline-1 outline-neutral-200/20 text-2xl font-semibold text-white/70 hover:bg-white/20 hover:outline-neutral-200/40 delay-75 ease-linear transition-all'> + + +
} + {aiEditorState.selectedTool === 'MakeLonger' && !aiEditorState.isWaitingForResponse && +
+

Select text to make longer

+
{ + handleOperation(aiEditorState.selectedTool, aiEditorState.chatInputValue) + }} className='flex cursor-pointer space-x-1.5 p-4 mt-4 items-center bg-white/10 rounded-md outline outline-1 outline-neutral-200/20 text-2xl font-semibold text-white/70 hover:bg-white/20 hover:outline-neutral-200/40 delay-75 ease-linear transition-all'> + + +
+
} + {aiEditorState.selectedTool === 'Translate' && !aiEditorState.isWaitingForResponse && +
+
+

Translate selected text to

+ +
+
{ + handleOperation(aiEditorState.selectedTool, aiEditorState.chatInputValue) + }} className='flex cursor-pointer space-x-1.5 p-4 mt-4 items-center bg-white/10 rounded-md outline outline-1 outline-neutral-200/20 text-2xl font-semibold text-white/70 hover:bg-white/20 hover:outline-neutral-200/40 delay-75 ease-linear transition-all'> + + +
+
} + {aiEditorState.isWaitingForResponse &&
+ + + + + +

Thinking...

+
} +
) } From f96540ea255aba90c110258052936e1a4390f032 Mon Sep 17 00:00:00 2001 From: swve Date: Thu, 11 Jan 2024 22:59:00 +0100 Subject: [PATCH 10/18] chore: use poetry as the backend package manager --- apps/api/Dockerfile | 7 +- apps/api/poetry.lock | 4427 +++++++++++++++++++++++++++++++++++++ apps/api/pyproject.toml | 41 + apps/api/requirements.txt | 3 +- 4 files changed, 4476 insertions(+), 2 deletions(-) create mode 100644 apps/api/poetry.lock diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index 5f75d2ff..baad3124 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -1,6 +1,9 @@ # FROM python:3.11 +# poetry +RUN pip install poetry + # WORKDIR /usr/learnhouse/apps/api @@ -8,7 +11,9 @@ WORKDIR /usr/learnhouse/apps/api COPY ./requirements.txt /usr/learnhouse/requirements.txt # -RUN pip install --no-cache-dir --upgrade -r /usr/learnhouse/requirements.txt +RUN poetry config virtualenvs.create false \ + && pip install --upgrade pip \ + && pip install -r /usr/learnhouse/requirements.txt # COPY ./ /usr/learnhouse diff --git a/apps/api/poetry.lock b/apps/api/poetry.lock new file mode 100644 index 00000000..6b19a34b --- /dev/null +++ b/apps/api/poetry.lock @@ -0,0 +1,4427 @@ +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. + +[[package]] +name = "aiohttp" +version = "3.9.1" +description = "Async http client/server framework (asyncio)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1f80197f8b0b846a8d5cf7b7ec6084493950d0882cc5537fb7b96a69e3c8590"}, + {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72444d17777865734aa1a4d167794c34b63e5883abb90356a0364a28904e6c0"}, + {file = "aiohttp-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9b05d5cbe9dafcdc733262c3a99ccf63d2f7ce02543620d2bd8db4d4f7a22f83"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c4fa235d534b3547184831c624c0b7c1e262cd1de847d95085ec94c16fddcd5"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:289ba9ae8e88d0ba16062ecf02dd730b34186ea3b1e7489046fc338bdc3361c4"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bff7e2811814fa2271be95ab6e84c9436d027a0e59665de60edf44e529a42c1f"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81b77f868814346662c96ab36b875d7814ebf82340d3284a31681085c051320f"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b9c7426923bb7bd66d409da46c41e3fb40f5caf679da624439b9eba92043fa6"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8d44e7bf06b0c0a70a20f9100af9fcfd7f6d9d3913e37754c12d424179b4e48f"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22698f01ff5653fe66d16ffb7658f582a0ac084d7da1323e39fd9eab326a1f26"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ca7ca5abfbfe8d39e653870fbe8d7710be7a857f8a8386fc9de1aae2e02ce7e4"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:8d7f98fde213f74561be1d6d3fa353656197f75d4edfbb3d94c9eb9b0fc47f5d"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5216b6082c624b55cfe79af5d538e499cd5f5b976820eac31951fb4325974501"}, + {file = "aiohttp-3.9.1-cp310-cp310-win32.whl", hash = "sha256:0e7ba7ff228c0d9a2cd66194e90f2bca6e0abca810b786901a569c0de082f489"}, + {file = "aiohttp-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:c7e939f1ae428a86e4abbb9a7c4732bf4706048818dfd979e5e2839ce0159f23"}, + {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:df9cf74b9bc03d586fc53ba470828d7b77ce51b0582d1d0b5b2fb673c0baa32d"}, + {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ecca113f19d5e74048c001934045a2b9368d77b0b17691d905af18bd1c21275e"}, + {file = "aiohttp-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8cef8710fb849d97c533f259103f09bac167a008d7131d7b2b0e3a33269185c0"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bea94403a21eb94c93386d559bce297381609153e418a3ffc7d6bf772f59cc35"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91c742ca59045dce7ba76cab6e223e41d2c70d79e82c284a96411f8645e2afff"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c93b7c2e52061f0925c3382d5cb8980e40f91c989563d3d32ca280069fd6a87"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee2527134f95e106cc1653e9ac78846f3a2ec1004cf20ef4e02038035a74544d"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11ff168d752cb41e8492817e10fb4f85828f6a0142b9726a30c27c35a1835f01"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b8c3a67eb87394386847d188996920f33b01b32155f0a94f36ca0e0c635bf3e3"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c7b5d5d64e2a14e35a9240b33b89389e0035e6de8dbb7ffa50d10d8b65c57449"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:69985d50a2b6f709412d944ffb2e97d0be154ea90600b7a921f95a87d6f108a2"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:c9110c06eaaac7e1f5562caf481f18ccf8f6fdf4c3323feab28a93d34cc646bd"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737e69d193dac7296365a6dcb73bbbf53bb760ab25a3727716bbd42022e8d7a"}, + {file = "aiohttp-3.9.1-cp311-cp311-win32.whl", hash = "sha256:4ee8caa925aebc1e64e98432d78ea8de67b2272252b0a931d2ac3bd876ad5544"}, + {file = "aiohttp-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a34086c5cc285be878622e0a6ab897a986a6e8bf5b67ecb377015f06ed316587"}, + {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f800164276eec54e0af5c99feb9494c295118fc10a11b997bbb1348ba1a52065"}, + {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:500f1c59906cd142d452074f3811614be04819a38ae2b3239a48b82649c08821"}, + {file = "aiohttp-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0b0a6a36ed7e164c6df1e18ee47afbd1990ce47cb428739d6c99aaabfaf1b3af"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69da0f3ed3496808e8cbc5123a866c41c12c15baaaead96d256477edf168eb57"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:176df045597e674fa950bf5ae536be85699e04cea68fa3a616cf75e413737eb5"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b796b44111f0cab6bbf66214186e44734b5baab949cb5fb56154142a92989aeb"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f27fdaadce22f2ef950fc10dcdf8048407c3b42b73779e48a4e76b3c35bca26c"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcb6532b9814ea7c5a6a3299747c49de30e84472fa72821b07f5a9818bce0f66"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:54631fb69a6e44b2ba522f7c22a6fb2667a02fd97d636048478db2fd8c4e98fe"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4b4c452d0190c5a820d3f5c0f3cd8a28ace48c54053e24da9d6041bf81113183"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:cae4c0c2ca800c793cae07ef3d40794625471040a87e1ba392039639ad61ab5b"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:565760d6812b8d78d416c3c7cfdf5362fbe0d0d25b82fed75d0d29e18d7fc30f"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54311eb54f3a0c45efb9ed0d0a8f43d1bc6060d773f6973efd90037a51cd0a3f"}, + {file = "aiohttp-3.9.1-cp312-cp312-win32.whl", hash = "sha256:85c3e3c9cb1d480e0b9a64c658cd66b3cfb8e721636ab8b0e746e2d79a7a9eed"}, + {file = "aiohttp-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:11cb254e397a82efb1805d12561e80124928e04e9c4483587ce7390b3866d213"}, + {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a22a34bc594d9d24621091d1b91511001a7eea91d6652ea495ce06e27381f70"}, + {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:598db66eaf2e04aa0c8900a63b0101fdc5e6b8a7ddd805c56d86efb54eb66672"}, + {file = "aiohttp-3.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c9376e2b09895c8ca8b95362283365eb5c03bdc8428ade80a864160605715f1"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41473de252e1797c2d2293804e389a6d6986ef37cbb4a25208de537ae32141dd"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c5857612c9813796960c00767645cb5da815af16dafb32d70c72a8390bbf690"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffcd828e37dc219a72c9012ec44ad2e7e3066bec6ff3aaa19e7d435dbf4032ca"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:219a16763dc0294842188ac8a12262b5671817042b35d45e44fd0a697d8c8361"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f694dc8a6a3112059258a725a4ebe9acac5fe62f11c77ac4dcf896edfa78ca28"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bcc0ea8d5b74a41b621ad4a13d96c36079c81628ccc0b30cfb1603e3dfa3a014"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:90ec72d231169b4b8d6085be13023ece8fa9b1bb495e4398d847e25218e0f431"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cf2a0ac0615842b849f40c4d7f304986a242f1e68286dbf3bd7a835e4f83acfd"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:0e49b08eafa4f5707ecfb321ab9592717a319e37938e301d462f79b4e860c32a"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2c59e0076ea31c08553e868cec02d22191c086f00b44610f8ab7363a11a5d9d8"}, + {file = "aiohttp-3.9.1-cp38-cp38-win32.whl", hash = "sha256:4831df72b053b1eed31eb00a2e1aff6896fb4485301d4ccb208cac264b648db4"}, + {file = "aiohttp-3.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:3135713c5562731ee18f58d3ad1bf41e1d8883eb68b363f2ffde5b2ea4b84cc7"}, + {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cfeadf42840c1e870dc2042a232a8748e75a36b52d78968cda6736de55582766"}, + {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:70907533db712f7aa791effb38efa96f044ce3d4e850e2d7691abd759f4f0ae0"}, + {file = "aiohttp-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cdefe289681507187e375a5064c7599f52c40343a8701761c802c1853a504558"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7481f581251bb5558ba9f635db70908819caa221fc79ee52a7f58392778c636"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49f0c1b3c2842556e5de35f122fc0f0b721334ceb6e78c3719693364d4af8499"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d406b01a9f5a7e232d1b0d161b40c05275ffbcbd772dc18c1d5a570961a1ca4"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d8e4450e7fe24d86e86b23cc209e0023177b6d59502e33807b732d2deb6975f"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c0266cd6f005e99f3f51e583012de2778e65af6b73860038b968a0a8888487a"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab221850108a4a063c5b8a70f00dd7a1975e5a1713f87f4ab26a46e5feac5a0e"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c88a15f272a0ad3d7773cf3a37cc7b7d077cbfc8e331675cf1346e849d97a4e5"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:237533179d9747080bcaad4d02083ce295c0d2eab3e9e8ce103411a4312991a0"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:02ab6006ec3c3463b528374c4cdce86434e7b89ad355e7bf29e2f16b46c7dd6f"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04fa38875e53eb7e354ece1607b1d2fdee2d175ea4e4d745f6ec9f751fe20c7c"}, + {file = "aiohttp-3.9.1-cp39-cp39-win32.whl", hash = "sha256:82eefaf1a996060602f3cc1112d93ba8b201dbf5d8fd9611227de2003dddb3b7"}, + {file = "aiohttp-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:9b05d33ff8e6b269e30a7957bd3244ffbce2a7a35a81b81c382629b80af1a8bf"}, + {file = "aiohttp-3.9.1.tar.gz", hash = "sha256:8fc49a87ac269d4529da45871e2ffb6874e87779c3d0e2ccd813c0899221239d"}, +] + +[package.dependencies] +aiosignal = ">=1.1.2" +attrs = ">=17.3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +yarl = ">=1.0,<2.0" + +[package.extras] +speedups = ["Brotli", "aiodns", "brotlicffi"] + +[[package]] +name = "aiosignal" +version = "1.3.1" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = false +python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" + +[[package]] +name = "anyio" +version = "3.7.1" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.7" +files = [ + {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, + {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, +] + +[package.dependencies] +idna = ">=2.8" +sniffio = ">=1.1" + +[package.extras] +doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] +test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (<0.22)"] + +[[package]] +name = "asgiref" +version = "3.7.2" +description = "ASGI specs, helper code, and adapters" +optional = false +python-versions = ">=3.7" +files = [ + {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, + {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, +] + +[package.extras] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] + +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + +[[package]] +name = "attrs" +version = "23.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] + +[[package]] +name = "backoff" +version = "2.2.1" +description = "Function decoration for backoff and retry" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, + {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, +] + +[[package]] +name = "bcrypt" +version = "4.1.2" +description = "Modern password hashing for your software and your servers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "bcrypt-4.1.2-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:ac621c093edb28200728a9cca214d7e838529e557027ef0581685909acd28b5e"}, + {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea505c97a5c465ab8c3ba75c0805a102ce526695cd6818c6de3b1a38f6f60da1"}, + {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57fa9442758da926ed33a91644649d3e340a71e2d0a5a8de064fb621fd5a3326"}, + {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eb3bd3321517916696233b5e0c67fd7d6281f0ef48e66812db35fc963a422a1c"}, + {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6cad43d8c63f34b26aef462b6f5e44fdcf9860b723d2453b5d391258c4c8e966"}, + {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:44290ccc827d3a24604f2c8bcd00d0da349e336e6503656cb8192133e27335e2"}, + {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:732b3920a08eacf12f93e6b04ea276c489f1c8fb49344f564cca2adb663b3e4c"}, + {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1c28973decf4e0e69cee78c68e30a523be441972c826703bb93099868a8ff5b5"}, + {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b8df79979c5bae07f1db22dcc49cc5bccf08a0380ca5c6f391cbb5790355c0b0"}, + {file = "bcrypt-4.1.2-cp37-abi3-win32.whl", hash = "sha256:fbe188b878313d01b7718390f31528be4010fed1faa798c5a1d0469c9c48c369"}, + {file = "bcrypt-4.1.2-cp37-abi3-win_amd64.whl", hash = "sha256:9800ae5bd5077b13725e2e3934aa3c9c37e49d3ea3d06318010aa40f54c63551"}, + {file = "bcrypt-4.1.2-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:71b8be82bc46cedd61a9f4ccb6c1a493211d031415a34adde3669ee1b0afbb63"}, + {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e3c6642077b0c8092580c819c1684161262b2e30c4f45deb000c38947bf483"}, + {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:387e7e1af9a4dd636b9505a465032f2f5cb8e61ba1120e79a0e1cd0b512f3dfc"}, + {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f70d9c61f9c4ca7d57f3bfe88a5ccf62546ffbadf3681bb1e268d9d2e41c91a7"}, + {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2a298db2a8ab20056120b45e86c00a0a5eb50ec4075b6142db35f593b97cb3fb"}, + {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ba55e40de38a24e2d78d34c2d36d6e864f93e0d79d0b6ce915e4335aa81d01b1"}, + {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3566a88234e8de2ccae31968127b0ecccbb4cddb629da744165db72b58d88ca4"}, + {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b90e216dc36864ae7132cb151ffe95155a37a14e0de3a8f64b49655dd959ff9c"}, + {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:69057b9fc5093ea1ab00dd24ede891f3e5e65bee040395fb1e66ee196f9c9b4a"}, + {file = "bcrypt-4.1.2-cp39-abi3-win32.whl", hash = "sha256:02d9ef8915f72dd6daaef40e0baeef8a017ce624369f09754baf32bb32dba25f"}, + {file = "bcrypt-4.1.2-cp39-abi3-win_amd64.whl", hash = "sha256:be3ab1071662f6065899fe08428e45c16aa36e28bc42921c4901a191fda6ee42"}, + {file = "bcrypt-4.1.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d75fc8cd0ba23f97bae88a6ec04e9e5351ff3c6ad06f38fe32ba50cbd0d11946"}, + {file = "bcrypt-4.1.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:a97e07e83e3262599434816f631cc4c7ca2aa8e9c072c1b1a7fec2ae809a1d2d"}, + {file = "bcrypt-4.1.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e51c42750b7585cee7892c2614be0d14107fad9581d1738d954a262556dd1aab"}, + {file = "bcrypt-4.1.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ba4e4cc26610581a6329b3937e02d319f5ad4b85b074846bf4fef8a8cf51e7bb"}, + {file = "bcrypt-4.1.2.tar.gz", hash = "sha256:33313a1200a3ae90b75587ceac502b048b840fc69e7f7a0905b5f87fac7a1258"}, +] + +[package.extras] +tests = ["pytest (>=3.2.1,!=3.3.0)"] +typecheck = ["mypy"] + +[[package]] +name = "boto3" +version = "1.34.17" +description = "The AWS SDK for Python" +optional = false +python-versions = ">= 3.8" +files = [ + {file = "boto3-1.34.17-py3-none-any.whl", hash = "sha256:1efc02be786884034d503d59c018cf7650d0cff9fcb37cd2eb49b802a6fe6111"}, + {file = "boto3-1.34.17.tar.gz", hash = "sha256:8ca248cc84e7e859e4e276eb9c4309fa01a3e58473bf48d6c33448be870c2bb8"}, +] + +[package.dependencies] +botocore = ">=1.34.17,<1.35.0" +jmespath = ">=0.7.1,<2.0.0" +s3transfer = ">=0.10.0,<0.11.0" + +[package.extras] +crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] + +[[package]] +name = "botocore" +version = "1.34.17" +description = "Low-level, data-driven core of boto 3." +optional = false +python-versions = ">= 3.8" +files = [ + {file = "botocore-1.34.17-py3-none-any.whl", hash = "sha256:7272c39032c6f1d62781e4c8445d9a1d9140c2bf52ba7ee66bf6db559c4b2427"}, + {file = "botocore-1.34.17.tar.gz", hash = "sha256:e48a662f3a6919219276b55085e8f73c3347966675f55e9d448be30cf79678ee"}, +] + +[package.dependencies] +jmespath = ">=0.7.1,<2.0.0" +python-dateutil = ">=2.1,<3.0.0" +urllib3 = {version = ">=1.25.4,<2.1", markers = "python_version >= \"3.10\""} + +[package.extras] +crt = ["awscrt (==0.19.19)"] + +[[package]] +name = "build" +version = "1.0.3" +description = "A simple, correct Python build frontend" +optional = false +python-versions = ">= 3.7" +files = [ + {file = "build-1.0.3-py3-none-any.whl", hash = "sha256:589bf99a67df7c9cf07ec0ac0e5e2ea5d4b37ac63301c4986d1acb126aa83f8f"}, + {file = "build-1.0.3.tar.gz", hash = "sha256:538aab1b64f9828977f84bc63ae570b060a8ed1be419e7870b8b4fc5e6ea553b"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "os_name == \"nt\""} +packaging = ">=19.0" +pyproject_hooks = "*" + +[package.extras] +docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"] +test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"] +typing = ["importlib-metadata (>=5.1)", "mypy (>=1.5.0,<1.6.0)", "tomli", "typing-extensions (>=3.7.4.3)"] +virtualenv = ["virtualenv (>=20.0.35)"] + +[[package]] +name = "cachetools" +version = "5.3.2" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.3.2-py3-none-any.whl", hash = "sha256:861f35a13a451f94e301ce2bec7cac63e881232ccce7ed67fab9b5df4d3beaa1"}, + {file = "cachetools-5.3.2.tar.gz", hash = "sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2"}, +] + +[[package]] +name = "certifi" +version = "2023.11.17" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, + {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "chroma-hnswlib" +version = "0.7.3" +description = "Chromas fork of hnswlib" +optional = false +python-versions = "*" +files = [ + {file = "chroma-hnswlib-0.7.3.tar.gz", hash = "sha256:b6137bedde49fffda6af93b0297fe00429fc61e5a072b1ed9377f909ed95a932"}, + {file = "chroma_hnswlib-0.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59d6a7c6f863c67aeb23e79a64001d537060b6995c3eca9a06e349ff7b0998ca"}, + {file = "chroma_hnswlib-0.7.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d71a3f4f232f537b6152947006bd32bc1629a8686df22fd97777b70f416c127a"}, + {file = "chroma_hnswlib-0.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c92dc1ebe062188e53970ba13f6b07e0ae32e64c9770eb7f7ffa83f149d4210"}, + {file = "chroma_hnswlib-0.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49da700a6656fed8753f68d44b8cc8ae46efc99fc8a22a6d970dc1697f49b403"}, + {file = "chroma_hnswlib-0.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:108bc4c293d819b56476d8f7865803cb03afd6ca128a2a04d678fffc139af029"}, + {file = "chroma_hnswlib-0.7.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:11e7ca93fb8192214ac2b9c0943641ac0daf8f9d4591bb7b73be808a83835667"}, + {file = "chroma_hnswlib-0.7.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6f552e4d23edc06cdeb553cdc757d2fe190cdeb10d43093d6a3319f8d4bf1c6b"}, + {file = "chroma_hnswlib-0.7.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f96f4d5699e486eb1fb95849fe35ab79ab0901265805be7e60f4eaa83ce263ec"}, + {file = "chroma_hnswlib-0.7.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:368e57fe9ebae05ee5844840fa588028a023d1182b0cfdb1d13f607c9ea05756"}, + {file = "chroma_hnswlib-0.7.3-cp311-cp311-win_amd64.whl", hash = "sha256:b7dca27b8896b494456db0fd705b689ac6b73af78e186eb6a42fea2de4f71c6f"}, + {file = "chroma_hnswlib-0.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:70f897dc6218afa1d99f43a9ad5eb82f392df31f57ff514ccf4eeadecd62f544"}, + {file = "chroma_hnswlib-0.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aef10b4952708f5a1381c124a29aead0c356f8d7d6e0b520b778aaa62a356f4"}, + {file = "chroma_hnswlib-0.7.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ee2d8d1529fca3898d512079144ec3e28a81d9c17e15e0ea4665697a7923253"}, + {file = "chroma_hnswlib-0.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:a4021a70e898783cd6f26e00008b494c6249a7babe8774e90ce4766dd288c8ba"}, + {file = "chroma_hnswlib-0.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a8f61fa1d417fda848e3ba06c07671f14806a2585272b175ba47501b066fe6b1"}, + {file = "chroma_hnswlib-0.7.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d7563be58bc98e8f0866907368e22ae218d6060601b79c42f59af4eccbbd2e0a"}, + {file = "chroma_hnswlib-0.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51b8d411486ee70d7b66ec08cc8b9b6620116b650df9c19076d2d8b6ce2ae914"}, + {file = "chroma_hnswlib-0.7.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d706782b628e4f43f1b8a81e9120ac486837fbd9bcb8ced70fe0d9b95c72d77"}, + {file = "chroma_hnswlib-0.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:54f053dedc0e3ba657f05fec6e73dd541bc5db5b09aa8bc146466ffb734bdc86"}, + {file = "chroma_hnswlib-0.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e607c5a71c610a73167a517062d302c0827ccdd6e259af6e4869a5c1306ffb5d"}, + {file = "chroma_hnswlib-0.7.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2358a795870156af6761890f9eb5ca8cade57eb10c5f046fe94dae1faa04b9e"}, + {file = "chroma_hnswlib-0.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cea425df2e6b8a5e201fff0d922a1cc1d165b3cfe762b1408075723c8892218"}, + {file = "chroma_hnswlib-0.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:454df3dd3e97aa784fba7cf888ad191e0087eef0fd8c70daf28b753b3b591170"}, + {file = "chroma_hnswlib-0.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:df587d15007ca701c6de0ee7d5585dd5e976b7edd2b30ac72bc376b3c3f85882"}, +] + +[package.dependencies] +numpy = "*" + +[[package]] +name = "chromadb" +version = "0.4.22" +description = "Chroma." +optional = false +python-versions = ">=3.8" +files = [ + {file = "chromadb-0.4.22-py3-none-any.whl", hash = "sha256:ad210b27b4cda2f09d15adc9c83c81bfa66b69f39648a27b637306e40de0680d"}, + {file = "chromadb-0.4.22.tar.gz", hash = "sha256:c793149e1c2bbbb52d77602c6c0594c5752f04cd9be12619250ddad2082af27a"}, +] + +[package.dependencies] +bcrypt = ">=4.0.1" +build = ">=1.0.3" +chroma-hnswlib = "0.7.3" +fastapi = ">=0.95.2" +grpcio = ">=1.58.0" +importlib-resources = "*" +kubernetes = ">=28.1.0" +mmh3 = ">=4.0.1" +numpy = ">=1.22.5" +onnxruntime = ">=1.14.1" +opentelemetry-api = ">=1.2.0" +opentelemetry-exporter-otlp-proto-grpc = ">=1.2.0" +opentelemetry-instrumentation-fastapi = ">=0.41b0" +opentelemetry-sdk = ">=1.2.0" +overrides = ">=7.3.1" +posthog = ">=2.4.0" +pulsar-client = ">=3.1.0" +pydantic = ">=1.9" +pypika = ">=0.48.9" +PyYAML = ">=6.0.0" +requests = ">=2.28" +tenacity = ">=8.2.3" +tokenizers = ">=0.13.2" +tqdm = ">=4.65.0" +typer = ">=0.9.0" +typing-extensions = ">=4.5.0" +uvicorn = {version = ">=0.18.3", extras = ["standard"]} + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "coloredlogs" +version = "15.0.1" +description = "Colored terminal output for Python's logging module" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934"}, + {file = "coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"}, +] + +[package.dependencies] +humanfriendly = ">=9.1" + +[package.extras] +cron = ["capturer (>=2.4)"] + +[[package]] +name = "dataclasses-json" +version = "0.6.3" +description = "Easily serialize dataclasses to and from JSON." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "dataclasses_json-0.6.3-py3-none-any.whl", hash = "sha256:4aeb343357997396f6bca1acae64e486c3a723d8f5c76301888abeccf0c45176"}, + {file = "dataclasses_json-0.6.3.tar.gz", hash = "sha256:35cb40aae824736fdf959801356641836365219cfe14caeb115c39136f775d2a"}, +] + +[package.dependencies] +marshmallow = ">=3.18.0,<4.0.0" +typing-inspect = ">=0.4.0,<1" + +[[package]] +name = "deprecated" +version = "1.2.14" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, +] + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] + +[[package]] +name = "distro" +version = "1.9.0" +description = "Distro - an OS platform information API" +optional = false +python-versions = ">=3.6" +files = [ + {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, + {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, +] + +[[package]] +name = "dnspython" +version = "2.4.2" +description = "DNS toolkit" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "dnspython-2.4.2-py3-none-any.whl", hash = "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8"}, + {file = "dnspython-2.4.2.tar.gz", hash = "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984"}, +] + +[package.extras] +dnssec = ["cryptography (>=2.6,<42.0)"] +doh = ["h2 (>=4.1.0)", "httpcore (>=0.17.3)", "httpx (>=0.24.1)"] +doq = ["aioquic (>=0.9.20)"] +idna = ["idna (>=2.1,<4.0)"] +trio = ["trio (>=0.14,<0.23)"] +wmi = ["wmi (>=1.5.1,<2.0.0)"] + +[[package]] +name = "ecdsa" +version = "0.18.0" +description = "ECDSA cryptographic signature library (pure python)" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "ecdsa-0.18.0-py2.py3-none-any.whl", hash = "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd"}, + {file = "ecdsa-0.18.0.tar.gz", hash = "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49"}, +] + +[package.dependencies] +six = ">=1.9.0" + +[package.extras] +gmpy = ["gmpy"] +gmpy2 = ["gmpy2"] + +[[package]] +name = "email-validator" +version = "2.1.0.post1" +description = "A robust email address syntax and deliverability validation library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "email_validator-2.1.0.post1-py3-none-any.whl", hash = "sha256:c973053efbeddfef924dc0bd93f6e77a1ea7ee0fce935aea7103c7a3d6d2d637"}, + {file = "email_validator-2.1.0.post1.tar.gz", hash = "sha256:a4b0bd1cf55f073b924258d19321b1f3aa74b4b5a71a42c305575dba920e1a44"}, +] + +[package.dependencies] +dnspython = ">=2.0.0" +idna = ">=2.0.0" + +[[package]] +name = "faker" +version = "22.2.0" +description = "Faker is a Python package that generates fake data for you." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Faker-22.2.0-py3-none-any.whl", hash = "sha256:2c2b7a8e55368defd718226bd5b48ef31b2d082c2900ccb4200987e433be500e"}, + {file = "Faker-22.2.0.tar.gz", hash = "sha256:fab78f435d27fa7bd109b095eea3504477e4149051c903fd63f11ce252e3d9b7"}, +] + +[package.dependencies] +python-dateutil = ">=2.4" + +[[package]] +name = "fastapi" +version = "0.104.1" +description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fastapi-0.104.1-py3-none-any.whl", hash = "sha256:752dc31160cdbd0436bb93bad51560b57e525cbb1d4bbf6f4904ceee75548241"}, + {file = "fastapi-0.104.1.tar.gz", hash = "sha256:e5e4540a7c5e1dcfbbcf5b903c234feddcdcd881f191977a1c5dfd917487e7ae"}, +] + +[package.dependencies] +anyio = ">=3.7.1,<4.0.0" +pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" +starlette = ">=0.27.0,<0.28.0" +typing-extensions = ">=4.8.0" + +[package.extras] +all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] + +[[package]] +name = "fastapi-jwt-auth" +version = "0.5.0" +description = "FastAPI extension that provides JWT Auth support (secure, easy to use and lightweight)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "fastapi-jwt-auth-0.5.0.tar.gz", hash = "sha256:d98068a9e828fe5909a1f338efabc3bb53149f11a9d2d395ab9d90fbb486b375"}, + {file = "fastapi_jwt_auth-0.5.0-py3-none-any.whl", hash = "sha256:43110a227e36f93b99257a1c79e66df8ed3d4c893291db8f9db2686192011f17"}, +] + +[package.dependencies] +fastapi = ">=0.61.0" +PyJWT = ">=1.7.1,<2.0.0" + +[package.extras] +asymmetric = ["cryptography (>=2.6,<4.0.0)"] +dev = ["cryptography (>=2.6,<4.0.0)", "uvicorn (>=0.11.5,<0.12.0)"] +doc = ["markdown-include (>=0.5.1,<0.6.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.5.0,<6.0.0)"] +test = ["coveralls (==2.1.2)", "pytest (==6.0.1)", "pytest-cov (==2.10.0)"] + +[[package]] +name = "filelock" +version = "3.13.1" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] + +[[package]] +name = "flatbuffers" +version = "23.5.26" +description = "The FlatBuffers serialization format for Python" +optional = false +python-versions = "*" +files = [ + {file = "flatbuffers-23.5.26-py2.py3-none-any.whl", hash = "sha256:c0ff356da363087b915fde4b8b45bdda73432fc17cddb3c8157472eab1422ad1"}, + {file = "flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89"}, +] + +[[package]] +name = "frozenlist" +version = "1.4.1" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = false +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, + {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, + {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, + {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, + {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, + {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, + {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, + {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, + {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, + {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, + {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, + {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, + {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, +] + +[[package]] +name = "fsspec" +version = "2023.12.2" +description = "File-system specification" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fsspec-2023.12.2-py3-none-any.whl", hash = "sha256:d800d87f72189a745fa3d6b033b9dc4a34ad069f60ca60b943a63599f5501960"}, + {file = "fsspec-2023.12.2.tar.gz", hash = "sha256:8548d39e8810b59c38014934f6b31e57f40c1b20f911f4cc2b85389c7e9bf0cb"}, +] + +[package.extras] +abfs = ["adlfs"] +adl = ["adlfs"] +arrow = ["pyarrow (>=1)"] +dask = ["dask", "distributed"] +devel = ["pytest", "pytest-cov"] +dropbox = ["dropbox", "dropboxdrivefs", "requests"] +full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] +fuse = ["fusepy"] +gcs = ["gcsfs"] +git = ["pygit2"] +github = ["requests"] +gs = ["gcsfs"] +gui = ["panel"] +hdfs = ["pyarrow (>=1)"] +http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "requests"] +libarchive = ["libarchive-c"] +oci = ["ocifs"] +s3 = ["s3fs"] +sftp = ["paramiko"] +smb = ["smbprotocol"] +ssh = ["paramiko"] +tqdm = ["tqdm"] + +[[package]] +name = "google-auth" +version = "2.26.2" +description = "Google Authentication Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-auth-2.26.2.tar.gz", hash = "sha256:97327dbbf58cccb58fc5a1712bba403ae76668e64814eb30f7316f7e27126b81"}, + {file = "google_auth-2.26.2-py2.py3-none-any.whl", hash = "sha256:3f445c8ce9b61ed6459aad86d8ccdba4a9afed841b2d1451a11ef4db08957424"}, +] + +[package.dependencies] +cachetools = ">=2.0.0,<6.0" +pyasn1-modules = ">=0.2.1" +rsa = ">=3.1.4,<5" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] +enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] +pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +reauth = ["pyu2f (>=0.1.5)"] +requests = ["requests (>=2.20.0,<3.0.0.dev0)"] + +[[package]] +name = "googleapis-common-protos" +version = "1.62.0" +description = "Common protobufs used in Google APIs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "googleapis-common-protos-1.62.0.tar.gz", hash = "sha256:83f0ece9f94e5672cced82f592d2a5edf527a96ed1794f0bab36d5735c996277"}, + {file = "googleapis_common_protos-1.62.0-py2.py3-none-any.whl", hash = "sha256:4750113612205514f9f6aa4cb00d523a94f3e8c06c5ad2fee466387dc4875f07"}, +] + +[package.dependencies] +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" + +[package.extras] +grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] + +[[package]] +name = "greenlet" +version = "3.0.3" +description = "Lightweight in-process concurrent programming" +optional = false +python-versions = ">=3.7" +files = [ + {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, + {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, + {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, + {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, + {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, + {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, + {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, + {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, + {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, + {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, + {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, + {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, + {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, + {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, + {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, + {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil"] + +[[package]] +name = "grpcio" +version = "1.60.0" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.7" +files = [ + {file = "grpcio-1.60.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:d020cfa595d1f8f5c6b343530cd3ca16ae5aefdd1e832b777f9f0eb105f5b139"}, + {file = "grpcio-1.60.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b98f43fcdb16172dec5f4b49f2fece4b16a99fd284d81c6bbac1b3b69fcbe0ff"}, + {file = "grpcio-1.60.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:20e7a4f7ded59097c84059d28230907cd97130fa74f4a8bfd1d8e5ba18c81491"}, + {file = "grpcio-1.60.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:452ca5b4afed30e7274445dd9b441a35ece656ec1600b77fff8c216fdf07df43"}, + {file = "grpcio-1.60.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43e636dc2ce9ece583b3e2ca41df5c983f4302eabc6d5f9cd04f0562ee8ec1ae"}, + {file = "grpcio-1.60.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e306b97966369b889985a562ede9d99180def39ad42c8014628dd3cc343f508"}, + {file = "grpcio-1.60.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f897c3b127532e6befdcf961c415c97f320d45614daf84deba0a54e64ea2457b"}, + {file = "grpcio-1.60.0-cp310-cp310-win32.whl", hash = "sha256:b87efe4a380887425bb15f220079aa8336276398dc33fce38c64d278164f963d"}, + {file = "grpcio-1.60.0-cp310-cp310-win_amd64.whl", hash = "sha256:a9c7b71211f066908e518a2ef7a5e211670761651039f0d6a80d8d40054047df"}, + {file = "grpcio-1.60.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:fb464479934778d7cc5baf463d959d361954d6533ad34c3a4f1d267e86ee25fd"}, + {file = "grpcio-1.60.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:4b44d7e39964e808b071714666a812049765b26b3ea48c4434a3b317bac82f14"}, + {file = "grpcio-1.60.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:90bdd76b3f04bdb21de5398b8a7c629676c81dfac290f5f19883857e9371d28c"}, + {file = "grpcio-1.60.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91229d7203f1ef0ab420c9b53fe2ca5c1fbeb34f69b3bc1b5089466237a4a134"}, + {file = "grpcio-1.60.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b36a2c6d4920ba88fa98075fdd58ff94ebeb8acc1215ae07d01a418af4c0253"}, + {file = "grpcio-1.60.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:297eef542156d6b15174a1231c2493ea9ea54af8d016b8ca7d5d9cc65cfcc444"}, + {file = "grpcio-1.60.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:87c9224acba0ad8bacddf427a1c2772e17ce50b3042a789547af27099c5f751d"}, + {file = "grpcio-1.60.0-cp311-cp311-win32.whl", hash = "sha256:95ae3e8e2c1b9bf671817f86f155c5da7d49a2289c5cf27a319458c3e025c320"}, + {file = "grpcio-1.60.0-cp311-cp311-win_amd64.whl", hash = "sha256:467a7d31554892eed2aa6c2d47ded1079fc40ea0b9601d9f79204afa8902274b"}, + {file = "grpcio-1.60.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:a7152fa6e597c20cb97923407cf0934e14224af42c2b8d915f48bc3ad2d9ac18"}, + {file = "grpcio-1.60.0-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:7db16dd4ea1b05ada504f08d0dca1cd9b926bed3770f50e715d087c6f00ad748"}, + {file = "grpcio-1.60.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:b0571a5aef36ba9177e262dc88a9240c866d903a62799e44fd4aae3f9a2ec17e"}, + {file = "grpcio-1.60.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fd9584bf1bccdfff1512719316efa77be235469e1e3295dce64538c4773840b"}, + {file = "grpcio-1.60.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6a478581b1a1a8fdf3318ecb5f4d0cda41cacdffe2b527c23707c9c1b8fdb55"}, + {file = "grpcio-1.60.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:77c8a317f0fd5a0a2be8ed5cbe5341537d5c00bb79b3bb27ba7c5378ba77dbca"}, + {file = "grpcio-1.60.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1c30bb23a41df95109db130a6cc1b974844300ae2e5d68dd4947aacba5985aa5"}, + {file = "grpcio-1.60.0-cp312-cp312-win32.whl", hash = "sha256:2aef56e85901c2397bd557c5ba514f84de1f0ae5dd132f5d5fed042858115951"}, + {file = "grpcio-1.60.0-cp312-cp312-win_amd64.whl", hash = "sha256:e381fe0c2aa6c03b056ad8f52f8efca7be29fb4d9ae2f8873520843b6039612a"}, + {file = "grpcio-1.60.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:92f88ca1b956eb8427a11bb8b4a0c0b2b03377235fc5102cb05e533b8693a415"}, + {file = "grpcio-1.60.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:e278eafb406f7e1b1b637c2cf51d3ad45883bb5bd1ca56bc05e4fc135dfdaa65"}, + {file = "grpcio-1.60.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:a48edde788b99214613e440fce495bbe2b1e142a7f214cce9e0832146c41e324"}, + {file = "grpcio-1.60.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de2ad69c9a094bf37c1102b5744c9aec6cf74d2b635558b779085d0263166454"}, + {file = "grpcio-1.60.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073f959c6f570797272f4ee9464a9997eaf1e98c27cb680225b82b53390d61e6"}, + {file = "grpcio-1.60.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c826f93050c73e7769806f92e601e0efdb83ec8d7c76ddf45d514fee54e8e619"}, + {file = "grpcio-1.60.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9e30be89a75ee66aec7f9e60086fadb37ff8c0ba49a022887c28c134341f7179"}, + {file = "grpcio-1.60.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b0fb2d4801546598ac5cd18e3ec79c1a9af8b8f2a86283c55a5337c5aeca4b1b"}, + {file = "grpcio-1.60.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:9073513ec380434eb8d21970e1ab3161041de121f4018bbed3146839451a6d8e"}, + {file = "grpcio-1.60.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:74d7d9fa97809c5b892449b28a65ec2bfa458a4735ddad46074f9f7d9550ad13"}, + {file = "grpcio-1.60.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:1434ca77d6fed4ea312901122dc8da6c4389738bf5788f43efb19a838ac03ead"}, + {file = "grpcio-1.60.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e61e76020e0c332a98290323ecfec721c9544f5b739fab925b6e8cbe1944cf19"}, + {file = "grpcio-1.60.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675997222f2e2f22928fbba640824aebd43791116034f62006e19730715166c0"}, + {file = "grpcio-1.60.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5208a57eae445ae84a219dfd8b56e04313445d146873117b5fa75f3245bc1390"}, + {file = "grpcio-1.60.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:428d699c8553c27e98f4d29fdc0f0edc50e9a8a7590bfd294d2edb0da7be3629"}, + {file = "grpcio-1.60.0-cp38-cp38-win32.whl", hash = "sha256:83f2292ae292ed5a47cdcb9821039ca8e88902923198f2193f13959360c01860"}, + {file = "grpcio-1.60.0-cp38-cp38-win_amd64.whl", hash = "sha256:705a68a973c4c76db5d369ed573fec3367d7d196673fa86614b33d8c8e9ebb08"}, + {file = "grpcio-1.60.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:c193109ca4070cdcaa6eff00fdb5a56233dc7610216d58fb81638f89f02e4968"}, + {file = "grpcio-1.60.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:676e4a44e740deaba0f4d95ba1d8c5c89a2fcc43d02c39f69450b1fa19d39590"}, + {file = "grpcio-1.60.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:5ff21e000ff2f658430bde5288cb1ac440ff15c0d7d18b5fb222f941b46cb0d2"}, + {file = "grpcio-1.60.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c86343cf9ff7b2514dd229bdd88ebba760bd8973dac192ae687ff75e39ebfab"}, + {file = "grpcio-1.60.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fd3b3968ffe7643144580f260f04d39d869fcc2cddb745deef078b09fd2b328"}, + {file = "grpcio-1.60.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:30943b9530fe3620e3b195c03130396cd0ee3a0d10a66c1bee715d1819001eaf"}, + {file = "grpcio-1.60.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b10241250cb77657ab315270b064a6c7f1add58af94befa20687e7c8d8603ae6"}, + {file = "grpcio-1.60.0-cp39-cp39-win32.whl", hash = "sha256:79a050889eb8d57a93ed21d9585bb63fca881666fc709f5d9f7f9372f5e7fd03"}, + {file = "grpcio-1.60.0-cp39-cp39-win_amd64.whl", hash = "sha256:8a97a681e82bc11a42d4372fe57898d270a2707f36c45c6676e49ce0d5c41353"}, + {file = "grpcio-1.60.0.tar.gz", hash = "sha256:2199165a1affb666aa24adf0c97436686d0a61bc5fc113c037701fb7c7fceb96"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.60.0)"] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.2" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"}, + {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.23.0)"] + +[[package]] +name = "httptools" +version = "0.6.1" +description = "A collection of framework independent HTTP protocol utils." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"}, + {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563"}, + {file = "httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58"}, + {file = "httptools-0.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185"}, + {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142"}, + {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658"}, + {file = "httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b"}, + {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1"}, + {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0"}, + {file = "httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc"}, + {file = "httptools-0.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2"}, + {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837"}, + {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d"}, + {file = "httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3"}, + {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0"}, + {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2"}, + {file = "httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90"}, + {file = "httptools-0.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503"}, + {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84"}, + {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb"}, + {file = "httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949"}, + {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3"}, + {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb"}, + {file = "httptools-0.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97"}, + {file = "httptools-0.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3"}, + {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4"}, + {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf"}, + {file = "httptools-0.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084"}, + {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3"}, + {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e"}, + {file = "httptools-0.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d"}, + {file = "httptools-0.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da"}, + {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81"}, + {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a"}, + {file = "httptools-0.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e"}, + {file = "httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a"}, +] + +[package.extras] +test = ["Cython (>=0.29.24,<0.30.0)"] + +[[package]] +name = "httpx" +version = "0.26.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "huggingface-hub" +version = "0.20.2" +description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "huggingface_hub-0.20.2-py3-none-any.whl", hash = "sha256:53752eda2239d30a470c307a61cf9adcf136bc77b0a734338c7d04941af560d8"}, + {file = "huggingface_hub-0.20.2.tar.gz", hash = "sha256:215c5fceff631030c7a3d19ba7b588921c908b3f21eef31d160ebc245b200ff6"}, +] + +[package.dependencies] +filelock = "*" +fsspec = ">=2023.5.0" +packaging = ">=20.9" +pyyaml = ">=5.1" +requests = "*" +tqdm = ">=4.42.1" +typing-extensions = ">=3.7.4.3" + +[package.extras] +all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +cli = ["InquirerPy (==0.3.4)"] +dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] +inference = ["aiohttp", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)"] +quality = ["mypy (==1.5.1)", "ruff (>=0.1.3)"] +tensorflow = ["graphviz", "pydot", "tensorflow"] +testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] +torch = ["torch"] +typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] + +[[package]] +name = "humanfriendly" +version = "10.0" +description = "Human friendly output for text interfaces using Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477"}, + {file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"}, +] + +[package.dependencies] +pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""} + +[[package]] +name = "idna" +version = "3.6" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, +] + +[[package]] +name = "importlib-metadata" +version = "6.11.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-6.11.0-py3-none-any.whl", hash = "sha256:f0afba6205ad8f8947c7d338b5342d5db2afbfd82f9cbef7879a9539cc12eb9b"}, + {file = "importlib_metadata-6.11.0.tar.gz", hash = "sha256:1231cf92d825c9e03cfc4da076a16de6422c863558229ea0b22b675657463443"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + +[[package]] +name = "importlib-resources" +version = "6.1.1" +description = "Read resources from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"}, + {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "jinja2" +version = "3.1.3" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jmespath" +version = "1.0.1" +description = "JSON Matching Expressions" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] + +[[package]] +name = "joblib" +version = "1.3.2" +description = "Lightweight pipelining with Python functions" +optional = false +python-versions = ">=3.7" +files = [ + {file = "joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9"}, + {file = "joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1"}, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + +[[package]] +name = "jsonpointer" +version = "2.4" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, + {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, +] + +[[package]] +name = "kubernetes" +version = "29.0.0" +description = "Kubernetes python client" +optional = false +python-versions = ">=3.6" +files = [ + {file = "kubernetes-29.0.0-py2.py3-none-any.whl", hash = "sha256:ab8cb0e0576ccdfb71886366efb102c6a20f268d817be065ce7f9909c631e43e"}, + {file = "kubernetes-29.0.0.tar.gz", hash = "sha256:c4812e227ae74d07d53c88293e564e54b850452715a59a927e7e1bc6b9a60459"}, +] + +[package.dependencies] +certifi = ">=14.05.14" +google-auth = ">=1.0.1" +oauthlib = ">=3.2.2" +python-dateutil = ">=2.5.3" +pyyaml = ">=5.4.1" +requests = "*" +requests-oauthlib = "*" +six = ">=1.9.0" +urllib3 = ">=1.24.2" +websocket-client = ">=0.32.0,<0.40.0 || >0.40.0,<0.41.dev0 || >=0.43.dev0" + +[package.extras] +adal = ["adal (>=1.0.2)"] + +[[package]] +name = "langchain" +version = "0.1.0" +description = "Building applications with LLMs through composability" +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain-0.1.0-py3-none-any.whl", hash = "sha256:8652e74b039333a55c79faff4400b077ba1bd0ddce5255574e42d301c05c1733"}, + {file = "langchain-0.1.0.tar.gz", hash = "sha256:d43119f8d3fda2c8ddf8c3a19bd5b94b347e27d1867ff14a921b90bdbed0668a"}, +] + +[package.dependencies] +aiohttp = ">=3.8.3,<4.0.0" +dataclasses-json = ">=0.5.7,<0.7" +jsonpatch = ">=1.33,<2.0" +langchain-community = ">=0.0.9,<0.1" +langchain-core = ">=0.1.7,<0.2" +langsmith = ">=0.0.77,<0.1.0" +numpy = ">=1,<2" +pydantic = ">=1,<3" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-textanalytics (>=5.3.0,<6.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"] +clarifai = ["clarifai (>=9.1.0)"] +cli = ["typer (>=0.9.0,<0.10.0)"] +cohere = ["cohere (>=4,<5)"] +docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"] +embeddings = ["sentence-transformers (>=2,<3)"] +extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<5)", "couchbase (>=4.1.9,<5.0.0)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "langchain-openai (>=0.0.2,<0.1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] +javascript = ["esprima (>=4.0.1,<5.0.0)"] +llms = ["clarifai (>=9.1.0)", "cohere (>=4,<5)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"] +openai = ["openai (<2)", "tiktoken (>=0.3.2,<0.6.0)"] +qdrant = ["qdrant-client (>=1.3.1,<2.0.0)"] +text-helpers = ["chardet (>=5.1.0,<6.0.0)"] + +[[package]] +name = "langchain-community" +version = "0.0.11" +description = "Community contributed LangChain integrations." +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain_community-0.0.11-py3-none-any.whl", hash = "sha256:30ab1d7dbf35d0ebe684d8a1e8964e8dedd3d31a3703790436b39674cfa06f41"}, + {file = "langchain_community-0.0.11.tar.gz", hash = "sha256:eaeaa8d63427ecf0cb32fe2f1ba4d05ad6d5ef9f7019baf21dc2dde5b1403002"}, +] + +[package.dependencies] +aiohttp = ">=3.8.3,<4.0.0" +dataclasses-json = ">=0.5.7,<0.7" +langchain-core = ">=0.1.8,<0.2" +langsmith = ">=0.0.63,<0.1.0" +numpy = ">=1,<2" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +cli = ["typer (>=0.9.0,<0.10.0)"] +extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "azure-ai-documentintelligence (>=1.0.0b1,<2.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<5)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "gradientai (>=1.4.0,<2.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "oracle-ads (>=2.9.1,<3.0.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)", "zhipuai (>=1.0.7,<2.0.0)"] + +[[package]] +name = "langchain-core" +version = "0.1.9" +description = "Building applications with LLMs through composability" +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain_core-0.1.9-py3-none-any.whl", hash = "sha256:1dd45aec185ce3afb1c19fb2e88cdbc19fafa7ae929d8107799a7c82ef69ea9f"}, + {file = "langchain_core-0.1.9.tar.gz", hash = "sha256:4b51fdbdbc06027c26ea89a6da809cae2e404c9daa95dc6c10e3eae383d8ea6a"}, +] + +[package.dependencies] +anyio = ">=3,<5" +jsonpatch = ">=1.33,<2.0" +langsmith = ">=0.0.63,<0.1.0" +packaging = ">=23.2,<24.0" +pydantic = ">=1,<3" +PyYAML = ">=5.3" +requests = ">=2,<3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +extended-testing = ["jinja2 (>=3,<4)"] + +[[package]] +name = "langsmith" +version = "0.0.79" +description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langsmith-0.0.79-py3-none-any.whl", hash = "sha256:be0374e913c36d9f6a13dd6b6e20a506066d5a0f3abfd476f9cf9e0b086ed744"}, + {file = "langsmith-0.0.79.tar.gz", hash = "sha256:d32639ccd18a92533b302f6f482255619afc8eb007fff91e37ee699d947c5e29"}, +] + +[package.dependencies] +pydantic = ">=1,<3" +requests = ">=2,<3" + +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + +[[package]] +name = "marshmallow" +version = "3.20.2" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = false +python-versions = ">=3.8" +files = [ + {file = "marshmallow-3.20.2-py3-none-any.whl", hash = "sha256:c21d4b98fee747c130e6bc8f45c4b3199ea66bc00c12ee1f639f0aeca034d5e9"}, + {file = "marshmallow-3.20.2.tar.gz", hash = "sha256:4c1daff273513dc5eb24b219a8035559dc573c8f322558ef85f5438ddd1236dd"}, +] + +[package.dependencies] +packaging = ">=17.0" + +[package.extras] +dev = ["pre-commit (>=2.4,<4.0)", "pytest", "pytz", "simplejson", "tox"] +docs = ["alabaster (==0.7.15)", "autodocsumm (==0.2.12)", "sphinx (==7.2.6)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"] +lint = ["pre-commit (>=2.4,<4.0)"] +tests = ["pytest", "pytz", "simplejson"] + +[[package]] +name = "mmh3" +version = "4.1.0" +description = "Python extension for MurmurHash (MurmurHash3), a set of fast and robust hash functions." +optional = false +python-versions = "*" +files = [ + {file = "mmh3-4.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be5ac76a8b0cd8095784e51e4c1c9c318c19edcd1709a06eb14979c8d850c31a"}, + {file = "mmh3-4.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:98a49121afdfab67cd80e912b36404139d7deceb6773a83620137aaa0da5714c"}, + {file = "mmh3-4.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5259ac0535874366e7d1a5423ef746e0d36a9e3c14509ce6511614bdc5a7ef5b"}, + {file = "mmh3-4.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5950827ca0453a2be357696da509ab39646044e3fa15cad364eb65d78797437"}, + {file = "mmh3-4.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1dd0f652ae99585b9dd26de458e5f08571522f0402155809fd1dc8852a613a39"}, + {file = "mmh3-4.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99d25548070942fab1e4a6f04d1626d67e66d0b81ed6571ecfca511f3edf07e6"}, + {file = "mmh3-4.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53db8d9bad3cb66c8f35cbc894f336273f63489ce4ac416634932e3cbe79eb5b"}, + {file = "mmh3-4.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75da0f615eb55295a437264cc0b736753f830b09d102aa4c2a7d719bc445ec05"}, + {file = "mmh3-4.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b926b07fd678ea84b3a2afc1fa22ce50aeb627839c44382f3d0291e945621e1a"}, + {file = "mmh3-4.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c5b053334f9b0af8559d6da9dc72cef0a65b325ebb3e630c680012323c950bb6"}, + {file = "mmh3-4.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:5bf33dc43cd6de2cb86e0aa73a1cc6530f557854bbbe5d59f41ef6de2e353d7b"}, + {file = "mmh3-4.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fa7eacd2b830727ba3dd65a365bed8a5c992ecd0c8348cf39a05cc77d22f4970"}, + {file = "mmh3-4.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:42dfd6742b9e3eec599f85270617debfa0bbb913c545bb980c8a4fa7b2d047da"}, + {file = "mmh3-4.1.0-cp310-cp310-win32.whl", hash = "sha256:2974ad343f0d39dcc88e93ee6afa96cedc35a9883bc067febd7ff736e207fa47"}, + {file = "mmh3-4.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:74699a8984ded645c1a24d6078351a056f5a5f1fe5838870412a68ac5e28d865"}, + {file = "mmh3-4.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:f0dc874cedc23d46fc488a987faa6ad08ffa79e44fb08e3cd4d4cf2877c00a00"}, + {file = "mmh3-4.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3280a463855b0eae64b681cd5b9ddd9464b73f81151e87bb7c91a811d25619e6"}, + {file = "mmh3-4.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:97ac57c6c3301769e757d444fa7c973ceb002cb66534b39cbab5e38de61cd896"}, + {file = "mmh3-4.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7b6502cdb4dbd880244818ab363c8770a48cdccecf6d729ade0241b736b5ec0"}, + {file = "mmh3-4.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52ba2da04671a9621580ddabf72f06f0e72c1c9c3b7b608849b58b11080d8f14"}, + {file = "mmh3-4.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a5fef4c4ecc782e6e43fbeab09cff1bac82c998a1773d3a5ee6a3605cde343e"}, + {file = "mmh3-4.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5135358a7e00991f73b88cdc8eda5203bf9de22120d10a834c5761dbeb07dd13"}, + {file = "mmh3-4.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cff9ae76a54f7c6fe0167c9c4028c12c1f6de52d68a31d11b6790bb2ae685560"}, + {file = "mmh3-4.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f02576a4d106d7830ca90278868bf0983554dd69183b7bbe09f2fcd51cf54f"}, + {file = "mmh3-4.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:073d57425a23721730d3ff5485e2da489dd3c90b04e86243dd7211f889898106"}, + {file = "mmh3-4.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:71e32ddec7f573a1a0feb8d2cf2af474c50ec21e7a8263026e8d3b4b629805db"}, + {file = "mmh3-4.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7cbb20b29d57e76a58b40fd8b13a9130db495a12d678d651b459bf61c0714cea"}, + {file = "mmh3-4.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:a42ad267e131d7847076bb7e31050f6c4378cd38e8f1bf7a0edd32f30224d5c9"}, + {file = "mmh3-4.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a013979fc9390abadc445ea2527426a0e7a4495c19b74589204f9b71bcaafeb"}, + {file = "mmh3-4.1.0-cp311-cp311-win32.whl", hash = "sha256:1d3b1cdad7c71b7b88966301789a478af142bddcb3a2bee563f7a7d40519a00f"}, + {file = "mmh3-4.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:0dc6dc32eb03727467da8e17deffe004fbb65e8b5ee2b502d36250d7a3f4e2ec"}, + {file = "mmh3-4.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:9ae3a5c1b32dda121c7dc26f9597ef7b01b4c56a98319a7fe86c35b8bc459ae6"}, + {file = "mmh3-4.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0033d60c7939168ef65ddc396611077a7268bde024f2c23bdc283a19123f9e9c"}, + {file = "mmh3-4.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d6af3e2287644b2b08b5924ed3a88c97b87b44ad08e79ca9f93d3470a54a41c5"}, + {file = "mmh3-4.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d82eb4defa245e02bb0b0dc4f1e7ee284f8d212633389c91f7fba99ba993f0a2"}, + {file = "mmh3-4.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba245e94b8d54765e14c2d7b6214e832557e7856d5183bc522e17884cab2f45d"}, + {file = "mmh3-4.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb04e2feeabaad6231e89cd43b3d01a4403579aa792c9ab6fdeef45cc58d4ec0"}, + {file = "mmh3-4.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e3b1a27def545ce11e36158ba5d5390cdbc300cfe456a942cc89d649cf7e3b2"}, + {file = "mmh3-4.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce0ab79ff736d7044e5e9b3bfe73958a55f79a4ae672e6213e92492ad5e734d5"}, + {file = "mmh3-4.1.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b02268be6e0a8eeb8a924d7db85f28e47344f35c438c1e149878bb1c47b1cd3"}, + {file = "mmh3-4.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:deb887f5fcdaf57cf646b1e062d56b06ef2f23421c80885fce18b37143cba828"}, + {file = "mmh3-4.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99dd564e9e2b512eb117bd0cbf0f79a50c45d961c2a02402787d581cec5448d5"}, + {file = "mmh3-4.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:08373082dfaa38fe97aa78753d1efd21a1969e51079056ff552e687764eafdfe"}, + {file = "mmh3-4.1.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:54b9c6a2ea571b714e4fe28d3e4e2db37abfd03c787a58074ea21ee9a8fd1740"}, + {file = "mmh3-4.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a7b1edf24c69e3513f879722b97ca85e52f9032f24a52284746877f6a7304086"}, + {file = "mmh3-4.1.0-cp312-cp312-win32.whl", hash = "sha256:411da64b951f635e1e2284b71d81a5a83580cea24994b328f8910d40bed67276"}, + {file = "mmh3-4.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:bebc3ecb6ba18292e3d40c8712482b4477abd6981c2ebf0e60869bd90f8ac3a9"}, + {file = "mmh3-4.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:168473dd608ade6a8d2ba069600b35199a9af837d96177d3088ca91f2b3798e3"}, + {file = "mmh3-4.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:372f4b7e1dcde175507640679a2a8790185bb71f3640fc28a4690f73da986a3b"}, + {file = "mmh3-4.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:438584b97f6fe13e944faf590c90fc127682b57ae969f73334040d9fa1c7ffa5"}, + {file = "mmh3-4.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6e27931b232fc676675fac8641c6ec6b596daa64d82170e8597f5a5b8bdcd3b6"}, + {file = "mmh3-4.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:571a92bad859d7b0330e47cfd1850b76c39b615a8d8e7aa5853c1f971fd0c4b1"}, + {file = "mmh3-4.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a69d6afe3190fa08f9e3a58e5145549f71f1f3fff27bd0800313426929c7068"}, + {file = "mmh3-4.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afb127be0be946b7630220908dbea0cee0d9d3c583fa9114a07156f98566dc28"}, + {file = "mmh3-4.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:940d86522f36348ef1a494cbf7248ab3f4a1638b84b59e6c9e90408bd11ad729"}, + {file = "mmh3-4.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3dcccc4935686619a8e3d1f7b6e97e3bd89a4a796247930ee97d35ea1a39341"}, + {file = "mmh3-4.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01bb9b90d61854dfc2407c5e5192bfb47222d74f29d140cb2dd2a69f2353f7cc"}, + {file = "mmh3-4.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bcb1b8b951a2c0b0fb8a5426c62a22557e2ffc52539e0a7cc46eb667b5d606a9"}, + {file = "mmh3-4.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6477a05d5e5ab3168e82e8b106e316210ac954134f46ec529356607900aea82a"}, + {file = "mmh3-4.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:da5892287e5bea6977364b15712a2573c16d134bc5fdcdd4cf460006cf849278"}, + {file = "mmh3-4.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:99180d7fd2327a6fffbaff270f760576839dc6ee66d045fa3a450f3490fda7f5"}, + {file = "mmh3-4.1.0-cp38-cp38-win32.whl", hash = "sha256:9b0d4f3949913a9f9a8fb1bb4cc6ecd52879730aab5ff8c5a3d8f5b593594b73"}, + {file = "mmh3-4.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:598c352da1d945108aee0c3c3cfdd0e9b3edef74108f53b49d481d3990402169"}, + {file = "mmh3-4.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:475d6d1445dd080f18f0f766277e1237fa2914e5fe3307a3b2a3044f30892103"}, + {file = "mmh3-4.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5ca07c41e6a2880991431ac717c2a049056fff497651a76e26fc22224e8b5732"}, + {file = "mmh3-4.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ebe052fef4bbe30c0548d12ee46d09f1b69035ca5208a7075e55adfe091be44"}, + {file = "mmh3-4.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaefd42e85afb70f2b855a011f7b4d8a3c7e19c3f2681fa13118e4d8627378c5"}, + {file = "mmh3-4.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0ae43caae5a47afe1b63a1ae3f0986dde54b5fb2d6c29786adbfb8edc9edfb"}, + {file = "mmh3-4.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6218666f74c8c013c221e7f5f8a693ac9cf68e5ac9a03f2373b32d77c48904de"}, + {file = "mmh3-4.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac59294a536ba447b5037f62d8367d7d93b696f80671c2c45645fa9f1109413c"}, + {file = "mmh3-4.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:086844830fcd1e5c84fec7017ea1ee8491487cfc877847d96f86f68881569d2e"}, + {file = "mmh3-4.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e42b38fad664f56f77f6fbca22d08450f2464baa68acdbf24841bf900eb98e87"}, + {file = "mmh3-4.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d08b790a63a9a1cde3b5d7d733ed97d4eb884bfbc92f075a091652d6bfd7709a"}, + {file = "mmh3-4.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:73ea4cc55e8aea28c86799ecacebca09e5f86500414870a8abaedfcbaf74d288"}, + {file = "mmh3-4.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f90938ff137130e47bcec8dc1f4ceb02f10178c766e2ef58a9f657ff1f62d124"}, + {file = "mmh3-4.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:aa1f13e94b8631c8cd53259250556edcf1de71738936b60febba95750d9632bd"}, + {file = "mmh3-4.1.0-cp39-cp39-win32.whl", hash = "sha256:a3b680b471c181490cf82da2142029edb4298e1bdfcb67c76922dedef789868d"}, + {file = "mmh3-4.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:fefef92e9c544a8dbc08f77a8d1b6d48006a750c4375bbcd5ff8199d761e263b"}, + {file = "mmh3-4.1.0-cp39-cp39-win_arm64.whl", hash = "sha256:8e2c1f6a2b41723a4f82bd5a762a777836d29d664fc0095f17910bea0adfd4a6"}, + {file = "mmh3-4.1.0.tar.gz", hash = "sha256:a1cf25348b9acd229dda464a094d6170f47d2850a1fcb762a3b6172d2ce6ca4a"}, +] + +[package.extras] +test = ["mypy (>=1.0)", "pytest (>=7.0.0)"] + +[[package]] +name = "monotonic" +version = "1.6" +description = "An implementation of time.monotonic() for Python 2 & < 3.3" +optional = false +python-versions = "*" +files = [ + {file = "monotonic-1.6-py2.py3-none-any.whl", hash = "sha256:68687e19a14f11f26d140dd5c86f3dba4bf5df58003000ed467e0e2a69bca96c"}, + {file = "monotonic-1.6.tar.gz", hash = "sha256:3a55207bcfed53ddd5c5bae174524062935efed17792e9de2ad0205ce9ad63f7"}, +] + +[[package]] +name = "motor" +version = "3.1.1" +description = "Non-blocking MongoDB driver for Tornado or asyncio" +optional = false +python-versions = ">=3.7" +files = [ + {file = "motor-3.1.1-py3-none-any.whl", hash = "sha256:01d93d7c512810dcd85f4d634a7244ba42ff6be7340c869791fe793561e734da"}, + {file = "motor-3.1.1.tar.gz", hash = "sha256:a4bdadf8a08ebb186ba16e557ba432aa867f689a42b80f2e9f8b24bbb1604742"}, +] + +[package.dependencies] +pymongo = ">=4.1,<5" + +[package.extras] +aws = ["pymongo[aws] (>=4.1,<5)"] +encryption = ["pymongo[encryption] (>=4.1,<5)"] +gssapi = ["pymongo[gssapi] (>=4.1,<5)"] +ocsp = ["pymongo[ocsp] (>=4.1,<5)"] +snappy = ["pymongo[snappy] (>=4.1,<5)"] +srv = ["pymongo[srv] (>=4.1,<5)"] +zstd = ["pymongo[zstd] (>=4.1,<5)"] + +[[package]] +name = "mpmath" +version = "1.3.0" +description = "Python library for arbitrary-precision floating-point arithmetic" +optional = false +python-versions = "*" +files = [ + {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, + {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, +] + +[package.extras] +develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] +docs = ["sphinx"] +gmpy = ["gmpy2 (>=2.1.0a4)"] +tests = ["pytest (>=4.6)"] + +[[package]] +name = "multidict" +version = "6.0.4" +description = "multidict implementation" +optional = false +python-versions = ">=3.7" +files = [ + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, + {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, + {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, + {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, + {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, + {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, + {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, + {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, + {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, + {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, + {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, + {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, + {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "networkx" +version = "3.2.1" +description = "Python package for creating and manipulating graphs and networks" +optional = false +python-versions = ">=3.9" +files = [ + {file = "networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2"}, + {file = "networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6"}, +] + +[package.extras] +default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] + +[[package]] +name = "nltk" +version = "3.8.1" +description = "Natural Language Toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, + {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, +] + +[package.dependencies] +click = "*" +joblib = "*" +regex = ">=2021.8.3" +tqdm = "*" + +[package.extras] +all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] +corenlp = ["requests"] +machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] +plot = ["matplotlib"] +tgrep = ["pyparsing"] +twitter = ["twython"] + +[[package]] +name = "numpy" +version = "1.26.3" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:806dd64230dbbfaca8a27faa64e2f414bf1c6622ab78cc4264f7f5f028fee3bf"}, + {file = "numpy-1.26.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f98011ba4ab17f46f80f7f8f1c291ee7d855fcef0a5a98db80767a468c85cd"}, + {file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d45b3ec2faed4baca41c76617fcdcfa4f684ff7a151ce6fc78ad3b6e85af0a6"}, + {file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd2b45bf079d9ad90377048e2747a0c82351989a2165821f0c96831b4a2a54b"}, + {file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:211ddd1e94817ed2d175b60b6374120244a4dd2287f4ece45d49228b4d529178"}, + {file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1240f767f69d7c4c8a29adde2310b871153df9b26b5cb2b54a561ac85146485"}, + {file = "numpy-1.26.3-cp310-cp310-win32.whl", hash = "sha256:21a9484e75ad018974a2fdaa216524d64ed4212e418e0a551a2d83403b0531d3"}, + {file = "numpy-1.26.3-cp310-cp310-win_amd64.whl", hash = "sha256:9e1591f6ae98bcfac2a4bbf9221c0b92ab49762228f38287f6eeb5f3f55905ce"}, + {file = "numpy-1.26.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b831295e5472954104ecb46cd98c08b98b49c69fdb7040483aff799a755a7374"}, + {file = "numpy-1.26.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e87562b91f68dd8b1c39149d0323b42e0082db7ddb8e934ab4c292094d575d6"}, + {file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c66d6fec467e8c0f975818c1796d25c53521124b7cfb760114be0abad53a0a2"}, + {file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f25e2811a9c932e43943a2615e65fc487a0b6b49218899e62e426e7f0a57eeda"}, + {file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:af36e0aa45e25c9f57bf684b1175e59ea05d9a7d3e8e87b7ae1a1da246f2767e"}, + {file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:51c7f1b344f302067b02e0f5b5d2daa9ed4a721cf49f070280ac202738ea7f00"}, + {file = "numpy-1.26.3-cp311-cp311-win32.whl", hash = "sha256:7ca4f24341df071877849eb2034948459ce3a07915c2734f1abb4018d9c49d7b"}, + {file = "numpy-1.26.3-cp311-cp311-win_amd64.whl", hash = "sha256:39763aee6dfdd4878032361b30b2b12593fb445ddb66bbac802e2113eb8a6ac4"}, + {file = "numpy-1.26.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a7081fd19a6d573e1a05e600c82a1c421011db7935ed0d5c483e9dd96b99cf13"}, + {file = "numpy-1.26.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12c70ac274b32bc00c7f61b515126c9205323703abb99cd41836e8125ea0043e"}, + {file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f784e13e598e9594750b2ef6729bcd5a47f6cfe4a12cca13def35e06d8163e3"}, + {file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f24750ef94d56ce6e33e4019a8a4d68cfdb1ef661a52cdaee628a56d2437419"}, + {file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:77810ef29e0fb1d289d225cabb9ee6cf4d11978a00bb99f7f8ec2132a84e0166"}, + {file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8ed07a90f5450d99dad60d3799f9c03c6566709bd53b497eb9ccad9a55867f36"}, + {file = "numpy-1.26.3-cp312-cp312-win32.whl", hash = "sha256:f73497e8c38295aaa4741bdfa4fda1a5aedda5473074369eca10626835445511"}, + {file = "numpy-1.26.3-cp312-cp312-win_amd64.whl", hash = "sha256:da4b0c6c699a0ad73c810736303f7fbae483bcb012e38d7eb06a5e3b432c981b"}, + {file = "numpy-1.26.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1666f634cb3c80ccbd77ec97bc17337718f56d6658acf5d3b906ca03e90ce87f"}, + {file = "numpy-1.26.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18c3319a7d39b2c6a9e3bb75aab2304ab79a811ac0168a671a62e6346c29b03f"}, + {file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b7e807d6888da0db6e7e75838444d62495e2b588b99e90dd80c3459594e857b"}, + {file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4d362e17bcb0011738c2d83e0a65ea8ce627057b2fdda37678f4374a382a137"}, + {file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b8c275f0ae90069496068c714387b4a0eba5d531aace269559ff2b43655edd58"}, + {file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cc0743f0302b94f397a4a65a660d4cd24267439eb16493fb3caad2e4389bccbb"}, + {file = "numpy-1.26.3-cp39-cp39-win32.whl", hash = "sha256:9bc6d1a7f8cedd519c4b7b1156d98e051b726bf160715b769106661d567b3f03"}, + {file = "numpy-1.26.3-cp39-cp39-win_amd64.whl", hash = "sha256:867e3644e208c8922a3be26fc6bbf112a035f50f0a86497f98f228c50c607bb2"}, + {file = "numpy-1.26.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3c67423b3703f8fbd90f5adaa37f85b5794d3366948efe9a5190a5f3a83fc34e"}, + {file = "numpy-1.26.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46f47ee566d98849323f01b349d58f2557f02167ee301e5e28809a8c0e27a2d0"}, + {file = "numpy-1.26.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a8474703bffc65ca15853d5fd4d06b18138ae90c17c8d12169968e998e448bb5"}, + {file = "numpy-1.26.3.tar.gz", hash = "sha256:697df43e2b6310ecc9d95f05d5ef20eacc09c7c4ecc9da3f235d39e71b7da1e4"}, +] + +[[package]] +name = "nvidia-cublas-cu12" +version = "12.1.3.1" +description = "CUBLAS native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:ee53ccca76a6fc08fb9701aa95b6ceb242cdaab118c3bb152af4e579af792728"}, + {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-win_amd64.whl", hash = "sha256:2b964d60e8cf11b5e1073d179d85fa340c120e99b3067558f3cf98dd69d02906"}, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.1.105" +description = "CUDA profiling tools runtime libs." +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:e54fde3983165c624cb79254ae9818a456eb6e87a7fd4d56a2352c24ee542d7e"}, + {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:bea8236d13a0ac7190bd2919c3e8e6ce1e402104276e6f9694479e48bb0eb2a4"}, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.1.105" +description = "NVRTC native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:339b385f50c309763ca65456ec75e17bbefcbbf2893f462cb8b90584cd27a1c2"}, + {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:0a98a522d9ff138b96c010a65e145dc1b4850e9ecb75a0172371793752fd46ed"}, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.1.105" +description = "CUDA Runtime native Libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:6e258468ddf5796e25f1dc591a31029fa317d97a0a94ed93468fc86301d61e40"}, + {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:dfb46ef84d73fababab44cf03e3b83f80700d27ca300e537f85f636fac474344"}, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "8.9.2.26" +description = "cuDNN runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl", hash = "sha256:5ccb288774fdfb07a7e7025ffec286971c06d8d7b4fb162525334616d7629ff9"}, +] + +[package.dependencies] +nvidia-cublas-cu12 = "*" + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.0.2.54" +description = "CUFFT native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl", hash = "sha256:794e3948a1aa71fd817c3775866943936774d1c14e7628c74f6f7417224cdf56"}, + {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-win_amd64.whl", hash = "sha256:d9ac353f78ff89951da4af698f80870b1534ed69993f10a4cf1d96f21357e253"}, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.2.106" +description = "CURAND native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:9d264c5036dde4e64f1de8c50ae753237c12e0b1348738169cd0f8a536c0e1e0"}, + {file = "nvidia_curand_cu12-10.3.2.106-py3-none-win_amd64.whl", hash = "sha256:75b6b0c574c0037839121317e17fd01f8a69fd2ef8e25853d826fec30bdba74a"}, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.4.5.107" +description = "CUDA solver native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl", hash = "sha256:8a7ec542f0412294b15072fa7dab71d31334014a69f953004ea7a118206fe0dd"}, + {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-win_amd64.whl", hash = "sha256:74e0c3a24c78612192a74fcd90dd117f1cf21dea4822e66d89e8ea80e3cd2da5"}, +] + +[package.dependencies] +nvidia-cublas-cu12 = "*" +nvidia-cusparse-cu12 = "*" +nvidia-nvjitlink-cu12 = "*" + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.1.0.106" +description = "CUSPARSE native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:f3b50f42cf363f86ab21f720998517a659a48131e8d538dc02f8768237bd884c"}, + {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-win_amd64.whl", hash = "sha256:b798237e81b9719373e8fae8d4f091b70a0cf09d9d85c95a557e11df2d8e9a5a"}, +] + +[package.dependencies] +nvidia-nvjitlink-cu12 = "*" + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.18.1" +description = "NVIDIA Collective Communication Library (NCCL) Runtime" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_nccl_cu12-2.18.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:1a6c4acefcbebfa6de320f412bf7866de856e786e0462326ba1bac40de0b5e71"}, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.3.101" +description = "Nvidia JIT LTO Library" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_nvjitlink_cu12-12.3.101-py3-none-manylinux1_x86_64.whl", hash = "sha256:64335a8088e2b9d196ae8665430bc6a2b7e6ef2eb877a9c735c804bd4ff6467c"}, + {file = "nvidia_nvjitlink_cu12-12.3.101-py3-none-win_amd64.whl", hash = "sha256:1b2e317e437433753530792f13eece58f0aec21a2b05903be7bffe58a606cbd1"}, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.1.105" +description = "NVIDIA Tools Extension" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:dc21cf308ca5691e7c04d962e213f8a4aa9bbfa23d95412f452254c2caeb09e5"}, + {file = "nvidia_nvtx_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:65f4d98982b31b60026e0e6de73fbdfc09d08a96f4656dd3665ca616a11e1e82"}, +] + +[[package]] +name = "oauthlib" +version = "3.2.2" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +optional = false +python-versions = ">=3.6" +files = [ + {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, + {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, +] + +[package.extras] +rsa = ["cryptography (>=3.0.0)"] +signals = ["blinker (>=1.4.0)"] +signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] + +[[package]] +name = "onnxruntime" +version = "1.16.3" +description = "ONNX Runtime is a runtime accelerator for Machine Learning models" +optional = false +python-versions = "*" +files = [ + {file = "onnxruntime-1.16.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:3bc41f323ac77acfed190be8ffdc47a6a75e4beeb3473fbf55eeb075ccca8df2"}, + {file = "onnxruntime-1.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:212741b519ee61a4822c79c47147d63a8b0ffde25cd33988d3d7be9fbd51005d"}, + {file = "onnxruntime-1.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f91f5497fe3df4ceee2f9e66c6148d9bfeb320cd6a71df361c66c5b8bac985a"}, + {file = "onnxruntime-1.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b1fc269cabd27f129fb9058917d6fdc89b188c49ed8700f300b945c81f889"}, + {file = "onnxruntime-1.16.3-cp310-cp310-win32.whl", hash = "sha256:f36b56a593b49a3c430be008c2aea6658d91a3030115729609ec1d5ffbaab1b6"}, + {file = "onnxruntime-1.16.3-cp310-cp310-win_amd64.whl", hash = "sha256:3c467eaa3d2429c026b10c3d17b78b7f311f718ef9d2a0d6938e5c3c2611b0cf"}, + {file = "onnxruntime-1.16.3-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:a225bb683991001d111f75323d355b3590e75e16b5e0f07a0401e741a0143ea1"}, + {file = "onnxruntime-1.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9aded21fe3d898edd86be8aa2eb995aa375e800ad3dfe4be9f618a20b8ee3630"}, + {file = "onnxruntime-1.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00cccc37a5195c8fca5011b9690b349db435986bd508eb44c9fce432da9228a4"}, + {file = "onnxruntime-1.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e253e572021563226a86f1c024f8f70cdae28f2fb1cc8c3a9221e8b1ce37db5"}, + {file = "onnxruntime-1.16.3-cp311-cp311-win32.whl", hash = "sha256:a82a8f0b4c978d08f9f5c7a6019ae51151bced9fd91e5aaa0c20a9e4ac7a60b6"}, + {file = "onnxruntime-1.16.3-cp311-cp311-win_amd64.whl", hash = "sha256:78d81d9af457a1dc90db9a7da0d09f3ccb1288ea1236c6ab19f0ca61f3eee2d3"}, + {file = "onnxruntime-1.16.3-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:04ebcd29c20473596a1412e471524b2fb88d55e6301c40b98dd2407b5911595f"}, + {file = "onnxruntime-1.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9996bab0f202a6435ab867bc55598f15210d0b72794d5de83712b53d564084ae"}, + {file = "onnxruntime-1.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b8f5083f903408238883821dd8c775f8120cb4a604166dbdabe97f4715256d5"}, + {file = "onnxruntime-1.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c2dcf1b70f8434abb1116fe0975c00e740722aaf321997195ea3618cc00558e"}, + {file = "onnxruntime-1.16.3-cp38-cp38-win32.whl", hash = "sha256:d4a0151e1accd04da6711f6fd89024509602f82c65a754498e960b032359b02d"}, + {file = "onnxruntime-1.16.3-cp38-cp38-win_amd64.whl", hash = "sha256:e8aa5bba78afbd4d8a2654b14ec7462ff3ce4a6aad312a3c2d2c2b65009f2541"}, + {file = "onnxruntime-1.16.3-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:6829dc2a79d48c911fedaf4c0f01e03c86297d32718a3fdee7a282766dfd282a"}, + {file = "onnxruntime-1.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:76f876c53bfa912c6c242fc38213a6f13f47612d4360bc9d599bd23753e53161"}, + {file = "onnxruntime-1.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4137e5d443e2dccebe5e156a47f1d6d66f8077b03587c35f11ee0c7eda98b533"}, + {file = "onnxruntime-1.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c56695c1a343c7c008b647fff3df44da63741fbe7b6003ef576758640719be7b"}, + {file = "onnxruntime-1.16.3-cp39-cp39-win32.whl", hash = "sha256:985a029798744ce4743fcf8442240fed35c8e4d4d30ec7d0c2cdf1388cd44408"}, + {file = "onnxruntime-1.16.3-cp39-cp39-win_amd64.whl", hash = "sha256:28ff758b17ce3ca6bcad3d936ec53bd7f5482e7630a13f6dcae518eba8f71d85"}, +] + +[package.dependencies] +coloredlogs = "*" +flatbuffers = "*" +numpy = ">=1.21.6" +packaging = "*" +protobuf = "*" +sympy = "*" + +[[package]] +name = "openai" +version = "1.7.1" +description = "The official Python library for the openai API" +optional = false +python-versions = ">=3.7.1" +files = [ + {file = "openai-1.7.1-py3-none-any.whl", hash = "sha256:e52ad7ea015331edc584e6e9c98741c819d7ffbbd2ecc50bf1f55c33f9cb3f77"}, + {file = "openai-1.7.1.tar.gz", hash = "sha256:7556e6aa30e20254b1ad68de49bb5ef4d8106bfac5e8a78abdc1daa911fbb1fb"}, +] + +[package.dependencies] +anyio = ">=3.5.0,<5" +distro = ">=1.7.0,<2" +httpx = ">=0.23.0,<1" +pydantic = ">=1.9.0,<3" +sniffio = "*" +tqdm = ">4" +typing-extensions = ">=4.7,<5" + +[package.extras] +datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] + +[[package]] +name = "opentelemetry-api" +version = "1.22.0" +description = "OpenTelemetry Python API" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_api-1.22.0-py3-none-any.whl", hash = "sha256:43621514301a7e9f5d06dd8013a1b450f30c2e9372b8e30aaeb4562abf2ce034"}, + {file = "opentelemetry_api-1.22.0.tar.gz", hash = "sha256:15ae4ca925ecf9cfdfb7a709250846fbb08072260fca08ade78056c502b86bed"}, +] + +[package.dependencies] +deprecated = ">=1.2.6" +importlib-metadata = ">=6.0,<7.0" + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.22.0" +description = "OpenTelemetry Protobuf encoding" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_exporter_otlp_proto_common-1.22.0-py3-none-any.whl", hash = "sha256:3f2538bec5312587f8676c332b3747f54c89fe6364803a807e217af4603201fa"}, + {file = "opentelemetry_exporter_otlp_proto_common-1.22.0.tar.gz", hash = "sha256:71ae2f81bc6d6fe408d06388826edc8933759b2ca3a97d24054507dc7cfce52d"}, +] + +[package.dependencies] +backoff = {version = ">=1.10.0,<3.0.0", markers = "python_version >= \"3.7\""} +opentelemetry-proto = "1.22.0" + +[[package]] +name = "opentelemetry-exporter-otlp-proto-grpc" +version = "1.22.0" +description = "OpenTelemetry Collector Protobuf over gRPC Exporter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_exporter_otlp_proto_grpc-1.22.0-py3-none-any.whl", hash = "sha256:b5bcadc129272004316a455e9081216d3380c1fc2231a928ea6a70aa90e173fb"}, + {file = "opentelemetry_exporter_otlp_proto_grpc-1.22.0.tar.gz", hash = "sha256:1e0e5aa4bbabc74942f06f268deffd94851d12a8dc30b02527472ef1729fe5b1"}, +] + +[package.dependencies] +backoff = {version = ">=1.10.0,<3.0.0", markers = "python_version >= \"3.7\""} +deprecated = ">=1.2.6" +googleapis-common-protos = ">=1.52,<2.0" +grpcio = ">=1.0.0,<2.0.0" +opentelemetry-api = ">=1.15,<2.0" +opentelemetry-exporter-otlp-proto-common = "1.22.0" +opentelemetry-proto = "1.22.0" +opentelemetry-sdk = ">=1.22.0,<1.23.0" + +[package.extras] +test = ["pytest-grpc"] + +[[package]] +name = "opentelemetry-instrumentation" +version = "0.43b0" +description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_instrumentation-0.43b0-py3-none-any.whl", hash = "sha256:0ff1334d7e359e27640e9d420024efeb73eacae464309c2e14ede7ba6c93967e"}, + {file = "opentelemetry_instrumentation-0.43b0.tar.gz", hash = "sha256:c3755da6c4be8033be0216d0501e11f4832690f4e2eca5a3576fbf113498f0f6"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.4,<2.0" +setuptools = ">=16.0" +wrapt = ">=1.0.0,<2.0.0" + +[[package]] +name = "opentelemetry-instrumentation-asgi" +version = "0.43b0" +description = "ASGI instrumentation for OpenTelemetry" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_instrumentation_asgi-0.43b0-py3-none-any.whl", hash = "sha256:1f593829fa039e9367820736fb063e92acd15c25b53d7bcb5d319971b8e93fd7"}, + {file = "opentelemetry_instrumentation_asgi-0.43b0.tar.gz", hash = "sha256:3f6f19333dca31ef696672e4e36cb1c2613c71dc7e847c11ff36a37e1130dadc"}, +] + +[package.dependencies] +asgiref = ">=3.0,<4.0" +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.43b0" +opentelemetry-semantic-conventions = "0.43b0" +opentelemetry-util-http = "0.43b0" + +[package.extras] +instruments = ["asgiref (>=3.0,<4.0)"] +test = ["opentelemetry-instrumentation-asgi[instruments]", "opentelemetry-test-utils (==0.43b0)"] + +[[package]] +name = "opentelemetry-instrumentation-fastapi" +version = "0.43b0" +description = "OpenTelemetry FastAPI Instrumentation" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_instrumentation_fastapi-0.43b0-py3-none-any.whl", hash = "sha256:b79c044df68a52e07b35fa12a424e7cc0dd27ff0a171c5fdcc41dea9de8fc938"}, + {file = "opentelemetry_instrumentation_fastapi-0.43b0.tar.gz", hash = "sha256:2afaaf470622e1a2732182c68f6d2431ffe5e026a7edacd0f83605632b66347f"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.43b0" +opentelemetry-instrumentation-asgi = "0.43b0" +opentelemetry-semantic-conventions = "0.43b0" +opentelemetry-util-http = "0.43b0" + +[package.extras] +instruments = ["fastapi (>=0.58,<1.0)"] +test = ["httpx (>=0.22,<1.0)", "opentelemetry-instrumentation-fastapi[instruments]", "opentelemetry-test-utils (==0.43b0)", "requests (>=2.23,<3.0)"] + +[[package]] +name = "opentelemetry-proto" +version = "1.22.0" +description = "OpenTelemetry Python Proto" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_proto-1.22.0-py3-none-any.whl", hash = "sha256:ce7188d22c75b6d0fe53e7fb58501613d0feade5139538e79dedd9420610fa0c"}, + {file = "opentelemetry_proto-1.22.0.tar.gz", hash = "sha256:9ec29169286029f17ca34ec1f3455802ffb90131642d2f545ece9a63e8f69003"}, +] + +[package.dependencies] +protobuf = ">=3.19,<5.0" + +[[package]] +name = "opentelemetry-sdk" +version = "1.22.0" +description = "OpenTelemetry Python SDK" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_sdk-1.22.0-py3-none-any.whl", hash = "sha256:a730555713d7c8931657612a88a141e3a4fe6eb5523d9e2d5a8b1e673d76efa6"}, + {file = "opentelemetry_sdk-1.22.0.tar.gz", hash = "sha256:45267ac1f38a431fc2eb5d6e0c0d83afc0b78de57ac345488aa58c28c17991d0"}, +] + +[package.dependencies] +opentelemetry-api = "1.22.0" +opentelemetry-semantic-conventions = "0.43b0" +typing-extensions = ">=3.7.4" + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.43b0" +description = "OpenTelemetry Semantic Conventions" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_semantic_conventions-0.43b0-py3-none-any.whl", hash = "sha256:291284d7c1bf15fdaddf309b3bd6d3b7ce12a253cec6d27144439819a15d8445"}, + {file = "opentelemetry_semantic_conventions-0.43b0.tar.gz", hash = "sha256:b9576fb890df479626fa624e88dde42d3d60b8b6c8ae1152ad157a8b97358635"}, +] + +[[package]] +name = "opentelemetry-util-http" +version = "0.43b0" +description = "Web util for OpenTelemetry" +optional = false +python-versions = ">=3.7" +files = [ + {file = "opentelemetry_util_http-0.43b0-py3-none-any.whl", hash = "sha256:f25a820784b030f6cb86b3d76e5676c769b75ed3f55a210bcdae0a5e175ebadb"}, + {file = "opentelemetry_util_http-0.43b0.tar.gz", hash = "sha256:3ff6ab361dbe99fc81200d625603c0fb890c055c6e416a3e6d661ddf47a6c7f7"}, +] + +[[package]] +name = "overrides" +version = "7.4.0" +description = "A decorator to automatically detect mismatch when overriding a method." +optional = false +python-versions = ">=3.6" +files = [ + {file = "overrides-7.4.0-py3-none-any.whl", hash = "sha256:3ad24583f86d6d7a49049695efe9933e67ba62f0c7625d53c59fa832ce4b8b7d"}, + {file = "overrides-7.4.0.tar.gz", hash = "sha256:9502a3cca51f4fac40b5feca985b6703a5c1f6ad815588a7ca9e285b9dca6757"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "passlib" +version = "1.7.4" +description = "comprehensive password hashing framework supporting over 30 schemes" +optional = false +python-versions = "*" +files = [ + {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"}, + {file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"}, +] + +[package.extras] +argon2 = ["argon2-cffi (>=18.2.0)"] +bcrypt = ["bcrypt (>=3.1.0)"] +build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"] +totp = ["cryptography"] + +[[package]] +name = "pillow" +version = "10.2.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pillow-10.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e"}, + {file = "pillow-10.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fad5ff2f13d69b7e74ce5b4ecd12cc0ec530fcee76356cac6742785ff71c452"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da2b52b37dad6d9ec64e653637a096905b258d2fc2b984c41ae7d08b938a67e4"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:47c0995fc4e7f79b5cfcab1fc437ff2890b770440f7696a3ba065ee0fd496563"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:322bdf3c9b556e9ffb18f93462e5f749d3444ce081290352c6070d014c93feb2"}, + {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:51f1a1bffc50e2e9492e87d8e09a17c5eea8409cda8d3f277eb6edc82813c17c"}, + {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69ffdd6120a4737710a9eee73e1d2e37db89b620f702754b8f6e62594471dee0"}, + {file = "pillow-10.2.0-cp310-cp310-win32.whl", hash = "sha256:c6dafac9e0f2b3c78df97e79af707cdc5ef8e88208d686a4847bab8266870023"}, + {file = "pillow-10.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:aebb6044806f2e16ecc07b2a2637ee1ef67a11840a66752751714a0d924adf72"}, + {file = "pillow-10.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:7049e301399273a0136ff39b84c3678e314f2158f50f517bc50285fb5ec847ad"}, + {file = "pillow-10.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35bb52c37f256f662abdfa49d2dfa6ce5d93281d323a9af377a120e89a9eafb5"}, + {file = "pillow-10.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c23f307202661071d94b5e384e1e1dc7dfb972a28a2310e4ee16103e66ddb67"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773efe0603db30c281521a7c0214cad7836c03b8ccff897beae9b47c0b657d61"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:716d30ed977be8b37d3ef185fecb9e5a1d62d110dfbdcd1e2a122ab46fddb03f"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a086c2af425c5f62a65e12fbf385f7c9fcb8f107d0849dba5839461a129cf311"}, + {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c8de2789052ed501dd829e9cae8d3dcce7acb4777ea4a479c14521c942d395b1"}, + {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:609448742444d9290fd687940ac0b57fb35e6fd92bdb65386e08e99af60bf757"}, + {file = "pillow-10.2.0-cp311-cp311-win32.whl", hash = "sha256:823ef7a27cf86df6597fa0671066c1b596f69eba53efa3d1e1cb8b30f3533068"}, + {file = "pillow-10.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1da3b2703afd040cf65ec97efea81cfba59cdbed9c11d8efc5ab09df9509fc56"}, + {file = "pillow-10.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:edca80cbfb2b68d7b56930b84a0e45ae1694aeba0541f798e908a49d66b837f1"}, + {file = "pillow-10.2.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:1b5e1b74d1bd1b78bc3477528919414874748dd363e6272efd5abf7654e68bef"}, + {file = "pillow-10.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7c2286c23cd350b80d2fc9d424fc797575fb16f854b831d16fd47ceec078f2c"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e23412b5c41e58cec602f1135c57dfcf15482013ce6e5f093a86db69646a5aa"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:52a50aa3fb3acb9cf7213573ef55d31d6eca37f5709c69e6858fe3bc04a5c2a2"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:127cee571038f252a552760076407f9cff79761c3d436a12af6000cd182a9d04"}, + {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8d12251f02d69d8310b046e82572ed486685c38f02176bd08baf216746eb947f"}, + {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54f1852cd531aa981bc0965b7d609f5f6cc8ce8c41b1139f6ed6b3c54ab82bfb"}, + {file = "pillow-10.2.0-cp312-cp312-win32.whl", hash = "sha256:257d8788df5ca62c980314053197f4d46eefedf4e6175bc9412f14412ec4ea2f"}, + {file = "pillow-10.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:154e939c5f0053a383de4fd3d3da48d9427a7e985f58af8e94d0b3c9fcfcf4f9"}, + {file = "pillow-10.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:f379abd2f1e3dddb2b61bc67977a6b5a0a3f7485538bcc6f39ec76163891ee48"}, + {file = "pillow-10.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8373c6c251f7ef8bda6675dd6d2b3a0fcc31edf1201266b5cf608b62a37407f9"}, + {file = "pillow-10.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:870ea1ada0899fd0b79643990809323b389d4d1d46c192f97342eeb6ee0b8483"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4b6b1e20608493548b1f32bce8cca185bf0480983890403d3b8753e44077129"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3031709084b6e7852d00479fd1d310b07d0ba82765f973b543c8af5061cf990e"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:3ff074fc97dd4e80543a3e91f69d58889baf2002b6be64347ea8cf5533188213"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:cb4c38abeef13c61d6916f264d4845fab99d7b711be96c326b84df9e3e0ff62d"}, + {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b1b3020d90c2d8e1dae29cf3ce54f8094f7938460fb5ce8bc5c01450b01fbaf6"}, + {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:170aeb00224ab3dc54230c797f8404507240dd868cf52066f66a41b33169bdbe"}, + {file = "pillow-10.2.0-cp38-cp38-win32.whl", hash = "sha256:c4225f5220f46b2fde568c74fca27ae9771536c2e29d7c04f4fb62c83275ac4e"}, + {file = "pillow-10.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0689b5a8c5288bc0504d9fcee48f61a6a586b9b98514d7d29b840143d6734f39"}, + {file = "pillow-10.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b792a349405fbc0163190fde0dc7b3fef3c9268292586cf5645598b48e63dc67"}, + {file = "pillow-10.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c570f24be1e468e3f0ce7ef56a89a60f0e05b30a3669a459e419c6eac2c35364"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8ecd059fdaf60c1963c58ceb8997b32e9dc1b911f5da5307aab614f1ce5c2fb"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c365fd1703040de1ec284b176d6af5abe21b427cb3a5ff68e0759e1e313a5e7e"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:70c61d4c475835a19b3a5aa42492409878bbca7438554a1f89d20d58a7c75c01"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6f491cdf80ae540738859d9766783e3b3c8e5bd37f5dfa0b76abdecc5081f13"}, + {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d189550615b4948f45252d7f005e53c2040cea1af5b60d6f79491a6e147eef7"}, + {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:49d9ba1ed0ef3e061088cd1e7538a0759aab559e2e0a80a36f9fd9d8c0c21591"}, + {file = "pillow-10.2.0-cp39-cp39-win32.whl", hash = "sha256:babf5acfede515f176833ed6028754cbcd0d206f7f614ea3447d67c33be12516"}, + {file = "pillow-10.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:0304004f8067386b477d20a518b50f3fa658a28d44e4116970abfcd94fac34a8"}, + {file = "pillow-10.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:0fb3e7fc88a14eacd303e90481ad983fd5b69c761e9e6ef94c983f91025da869"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:322209c642aabdd6207517e9739c704dc9f9db943015535783239022002f054a"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eedd52442c0a5ff4f887fab0c1c0bb164d8635b32c894bc1faf4c618dd89df2"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb28c753fd5eb3dd859b4ee95de66cc62af91bcff5db5f2571d32a520baf1f04"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:33870dc4653c5017bf4c8873e5488d8f8d5f8935e2f1fb9a2208c47cdd66efd2"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3c31822339516fb3c82d03f30e22b1d038da87ef27b6a78c9549888f8ceda39a"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a2b56ba36e05f973d450582fb015594aaa78834fefe8dfb8fcd79b93e64ba4c6"}, + {file = "pillow-10.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d8e6aeb9201e655354b3ad049cb77d19813ad4ece0df1249d3c793de3774f8c7"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:2247178effb34a77c11c0e8ac355c7a741ceca0a732b27bf11e747bbc950722f"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15587643b9e5eb26c48e49a7b33659790d28f190fc514a322d55da2fb5c2950e"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753cd8f2086b2b80180d9b3010dd4ed147efc167c90d3bf593fe2af21265e5a5"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7c8f97e8e7a9009bcacbe3766a36175056c12f9a44e6e6f2d5caad06dcfbf03b"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d1b35bcd6c5543b9cb547dee3150c93008f8dd0f1fef78fc0cd2b141c5baf58a"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe4c15f6c9285dc54ce6553a3ce908ed37c8f3825b5a51a15c91442bb955b868"}, + {file = "pillow-10.2.0.tar.gz", hash = "sha256:e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + +[[package]] +name = "pluggy" +version = "1.3.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "posthog" +version = "3.3.1" +description = "Integrate PostHog into any python application." +optional = false +python-versions = "*" +files = [ + {file = "posthog-3.3.1-py2.py3-none-any.whl", hash = "sha256:5f53b232acb680a0389e372db5f786061a18386b8b5324bddcc64eff9fdb319b"}, + {file = "posthog-3.3.1.tar.gz", hash = "sha256:252cb6ab5cbe7ff002753f34fb647721b3af75034b4a5a631317ebf3db58fe59"}, +] + +[package.dependencies] +backoff = ">=1.10.0" +monotonic = ">=1.5" +python-dateutil = ">2.1" +requests = ">=2.7,<3.0" +six = ">=1.5" + +[package.extras] +dev = ["black", "flake8", "flake8-print", "isort", "pre-commit"] +sentry = ["django", "sentry-sdk"] +test = ["coverage", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint", "pytest", "pytest-timeout"] + +[[package]] +name = "protobuf" +version = "4.25.2" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "protobuf-4.25.2-cp310-abi3-win32.whl", hash = "sha256:b50c949608682b12efb0b2717f53256f03636af5f60ac0c1d900df6213910fd6"}, + {file = "protobuf-4.25.2-cp310-abi3-win_amd64.whl", hash = "sha256:8f62574857ee1de9f770baf04dde4165e30b15ad97ba03ceac65f760ff018ac9"}, + {file = "protobuf-4.25.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:2db9f8fa64fbdcdc93767d3cf81e0f2aef176284071507e3ede160811502fd3d"}, + {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:10894a2885b7175d3984f2be8d9850712c57d5e7587a2410720af8be56cdaf62"}, + {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:fc381d1dd0516343f1440019cedf08a7405f791cd49eef4ae1ea06520bc1c020"}, + {file = "protobuf-4.25.2-cp38-cp38-win32.whl", hash = "sha256:33a1aeef4b1927431d1be780e87b641e322b88d654203a9e9d93f218ee359e61"}, + {file = "protobuf-4.25.2-cp38-cp38-win_amd64.whl", hash = "sha256:47f3de503fe7c1245f6f03bea7e8d3ec11c6c4a2ea9ef910e3221c8a15516d62"}, + {file = "protobuf-4.25.2-cp39-cp39-win32.whl", hash = "sha256:5e5c933b4c30a988b52e0b7c02641760a5ba046edc5e43d3b94a74c9fc57c1b3"}, + {file = "protobuf-4.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:d66a769b8d687df9024f2985d5137a337f957a0916cf5464d1513eee96a63ff0"}, + {file = "protobuf-4.25.2-py3-none-any.whl", hash = "sha256:a8b7a98d4ce823303145bf3c1a8bdb0f2f4642a414b196f04ad9853ed0c8f830"}, + {file = "protobuf-4.25.2.tar.gz", hash = "sha256:fe599e175cb347efc8ee524bcd4b902d11f7262c0e569ececcb89995c15f0a5e"}, +] + +[[package]] +name = "psycopg2" +version = "2.9.9" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "psycopg2-2.9.9-cp310-cp310-win32.whl", hash = "sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516"}, + {file = "psycopg2-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3"}, + {file = "psycopg2-2.9.9-cp311-cp311-win32.whl", hash = "sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372"}, + {file = "psycopg2-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981"}, + {file = "psycopg2-2.9.9-cp312-cp312-win32.whl", hash = "sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024"}, + {file = "psycopg2-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693"}, + {file = "psycopg2-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa"}, + {file = "psycopg2-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a"}, + {file = "psycopg2-2.9.9-cp38-cp38-win32.whl", hash = "sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c"}, + {file = "psycopg2-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e"}, + {file = "psycopg2-2.9.9-cp39-cp39-win32.whl", hash = "sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59"}, + {file = "psycopg2-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913"}, + {file = "psycopg2-2.9.9.tar.gz", hash = "sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156"}, +] + +[[package]] +name = "pulsar-client" +version = "3.4.0" +description = "Apache Pulsar Python client library" +optional = false +python-versions = "*" +files = [ + {file = "pulsar_client-3.4.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ebf99db5244ff69479283b25621b070492acc4bb643d162d86b90387cb6fdb2a"}, + {file = "pulsar_client-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6cb5d8e1482a8aea758633be23717e0c4bb7dc53784e37915c0048c0382f134"}, + {file = "pulsar_client-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30a7592e42c76034e9a8d64d42dd5bab361425f869de562e9ccad698e19cd88"}, + {file = "pulsar_client-3.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5963090a78a5644ba25f41da3a6d49ea3f00c972b095baff365916dc246426a"}, + {file = "pulsar_client-3.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:419cdcf577f755e3f31bf264300d9ba158325edb2ee9cee555d81ba1909c094e"}, + {file = "pulsar_client-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:4c93c35ee97307dae153e748b33dcd3d4f06da34bca373321aa2df73f1535705"}, + {file = "pulsar_client-3.4.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:11952fb022ee72debf53b169f4482f9dc5c890be0149ae98779864b3a21f1bd3"}, + {file = "pulsar_client-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8743c320aa96798d20cafa98ea97a68c4295fc4872c23acd5e012fd36cb06ba"}, + {file = "pulsar_client-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33571de99cd898349f17978ba62e2b839ea0275fb7067f31bf5f6ebfeae0987d"}, + {file = "pulsar_client-3.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a60c03c3e70f018538e7cd3fa84d95e283b610272b744166dbc48960a809fa07"}, + {file = "pulsar_client-3.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c47041267b5843ffec54352d842156c279945f3e976d7025ffa89875ff76390"}, + {file = "pulsar_client-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:49fe4ab04004b476c87ab3ad22fe87346fca564a3e3ca9c0ac58fee45a895d81"}, + {file = "pulsar_client-3.4.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:1e077a4839be3ead3de3f05b4c244269dca2df07f47cea0b90544c7e9dc1642f"}, + {file = "pulsar_client-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f202b84e1f683d64672dd1971114600ae2e5c3735587286ff9bfb431385f08e8"}, + {file = "pulsar_client-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c606c04f357341042fa6c75477de7d2204f7ae50aa29c2f74b24e54c85f47f96"}, + {file = "pulsar_client-3.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c67b25ede3a578f5a7dc30230e52609ef38191f74b47e5cbdbc98c42df556927"}, + {file = "pulsar_client-3.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b7f8211cc9460cdf4d06e4e1cb878689d2aa4a7e4027bd2a2f1419a79ade16a6"}, + {file = "pulsar_client-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:c5399e9780d6951c69808c0b6175311a966af82fb08addf6e741ae37b1bee7ef"}, + {file = "pulsar_client-3.4.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:a2d6c850b60106dc915d3476a490fba547c6748a5f742b68abd30d1a35355b82"}, + {file = "pulsar_client-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a52ea8294a9f30eb6f0a2db5dc16e3aad7ff2284f818c48ad3a6b601723be02b"}, + {file = "pulsar_client-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eeeede40108be12222e009285c971e5b8f6433d9f0f8ef934d6a131585921c4"}, + {file = "pulsar_client-3.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9409066c600f2b6f220552c5dfe08aeeabcf07fe0e76367aa5816b2e87a5cf72"}, + {file = "pulsar_client-3.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:58e2f886e6dab43e66c3ce990fe96209e55ab46350506829a637b77b74125fb9"}, + {file = "pulsar_client-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:b57dfa5063b0d9dc7664896c55605eac90753e35e80db5a959d3be2be0ab0d48"}, + {file = "pulsar_client-3.4.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:7704c664aa2c801af4c2d3a58e9d8ffaeef12ce8a0f71712e9187f9a96da856f"}, + {file = "pulsar_client-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0364db563e27442053bdbb8655e7ffb420f491690bc2c78da5a58bd35c658ad"}, + {file = "pulsar_client-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3e34de19e0744d8aa3538cb2172076bccd0761b3e94ebadb7bd59765ae3d1ed"}, + {file = "pulsar_client-3.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:dc8be41dec8cb052fb1837550f495e9b73a8b3cf85e07157904ec84832758a65"}, + {file = "pulsar_client-3.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b49d669bed15b7edb9c936704310d57808f1d01c511b94d866f54fe8ffe1752d"}, + {file = "pulsar_client-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:88c93e5fbfc349f3967e931f7a908d15fd4fd725ebdd842423ac9cd961fe293f"}, +] + +[package.dependencies] +certifi = "*" + +[package.extras] +all = ["apache-bookkeeper-client (>=4.16.1)", "fastavro (>=1.9.2)", "grpcio (>=1.60.0)", "prometheus-client", "protobuf (>=3.6.1,<=3.20.3)", "ratelimit"] +avro = ["fastavro (>=1.9.2)"] +functions = ["apache-bookkeeper-client (>=4.16.1)", "grpcio (>=1.60.0)", "prometheus-client", "protobuf (>=3.6.1,<=3.20.3)", "ratelimit"] + +[[package]] +name = "pyasn1" +version = "0.5.1" +description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "pyasn1-0.5.1-py2.py3-none-any.whl", hash = "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58"}, + {file = "pyasn1-0.5.1.tar.gz", hash = "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c"}, +] + +[[package]] +name = "pyasn1-modules" +version = "0.3.0" +description = "A collection of ASN.1-based protocols modules" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"}, + {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"}, +] + +[package.dependencies] +pyasn1 = ">=0.4.6,<0.6.0" + +[[package]] +name = "pydantic" +version = "1.10.13" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"}, + {file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"}, + {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"}, + {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"}, + {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"}, + {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"}, + {file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"}, + {file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"}, + {file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"}, + {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"}, + {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"}, + {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"}, + {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"}, + {file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"}, + {file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"}, + {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"}, + {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"}, + {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"}, + {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"}, + {file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"}, + {file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"}, + {file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"}, + {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"}, + {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"}, + {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"}, + {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"}, + {file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"}, + {file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"}, + {file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"}, + {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"}, + {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"}, + {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"}, + {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"}, + {file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"}, + {file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"}, + {file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"}, +] + +[package.dependencies] +email-validator = {version = ">=1.0.3", optional = true, markers = "extra == \"email\""} +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pyjwt" +version = "1.7.1" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = "*" +files = [ + {file = "PyJWT-1.7.1-py2.py3-none-any.whl", hash = "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e"}, + {file = "PyJWT-1.7.1.tar.gz", hash = "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96"}, +] + +[package.extras] +crypto = ["cryptography (>=1.4)"] +flake8 = ["flake8", "flake8-import-order", "pep8-naming"] +test = ["pytest (>=4.0.1,<5.0.0)", "pytest-cov (>=2.6.0,<3.0.0)", "pytest-runner (>=4.2,<5.0.0)"] + +[[package]] +name = "pymongo" +version = "4.3.3" +description = "Python driver for MongoDB " +optional = false +python-versions = ">=3.7" +files = [ + {file = "pymongo-4.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:74731c9e423c93cbe791f60c27030b6af6a948cef67deca079da6cd1bb583a8e"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux1_i686.whl", hash = "sha256:66413c50d510e5bcb0afc79880d1693a2185bcea003600ed898ada31338c004e"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:9b87b23570565a6ddaa9244d87811c2ee9cffb02a753c8a2da9c077283d85845"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux2014_i686.whl", hash = "sha256:695939036a320f4329ccf1627edefbbb67cc7892b8222d297b0dd2313742bfee"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux2014_ppc64le.whl", hash = "sha256:ffcc8394123ea8d43fff8e5d000095fe7741ce3f8988366c5c919c4f5eb179d3"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux2014_s390x.whl", hash = "sha256:943f208840777f34312c103a2d1caab02d780c4e9be26b3714acf6c4715ba7e1"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:01f7cbe88d22440b6594c955e37312d932fd632ffed1a86d0c361503ca82cc9d"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdb87309de97c63cb9a69132e1cb16be470e58cffdfbad68fdd1dc292b22a840"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d86c35d94b5499689354ccbc48438a79f449481ee6300f3e905748edceed78e7"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a966d5304b7d90c45c404914e06bbf02c5bf7e99685c6c12f0047ef2aa837142"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be1d2ce7e269215c3ee9a215e296b7a744aff4f39233486d2c4d77f5f0c561a6"}, + {file = "pymongo-4.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:55b6163dac53ef1e5d834297810c178050bd0548a4136cd4e0f56402185916ca"}, + {file = "pymongo-4.3.3-cp310-cp310-win32.whl", hash = "sha256:dc0cff74cd36d7e1edba91baa09622c35a8a57025f2f2b7a41e3f83b1db73186"}, + {file = "pymongo-4.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:cafa52873ae12baa512a8721afc20de67a36886baae6a5f394ddef0ce9391f91"}, + {file = "pymongo-4.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:599d3f6fbef31933b96e2d906b0f169b3371ff79ea6aaf6ecd76c947a3508a3d"}, + {file = "pymongo-4.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0640b4e9d008e13956b004d1971a23377b3d45491f87082161c92efb1e6c0d6"}, + {file = "pymongo-4.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:341221e2f2866a5960e6f8610f4cbac0bb13097f3b1a289aa55aba984fc0d969"}, + {file = "pymongo-4.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7fac06a539daef4fcf5d8288d0d21b412f9b750454cd5a3cf90484665db442a"}, + {file = "pymongo-4.3.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a51901066696c4af38c6c63a1f0aeffd5e282367ff475de8c191ec9609b56d"}, + {file = "pymongo-4.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3055510fdfdb1775bc8baa359783022f70bb553f2d46e153c094dfcb08578ff"}, + {file = "pymongo-4.3.3-cp311-cp311-win32.whl", hash = "sha256:524d78673518dcd352a91541ecd2839c65af92dc883321c2109ef6e5cd22ef23"}, + {file = "pymongo-4.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:b8a03af1ce79b902a43f5f694c4ca8d92c2a4195db0966f08f266549e2fc49bc"}, + {file = "pymongo-4.3.3-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:39b03045c71f761aee96a12ebfbc2f4be89e724ff6f5e31c2574c1a0e2add8bd"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6fcfbf435eebf8a1765c6d1f46821740ebe9f54f815a05c8fc30d789ef43cb12"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:7d43ac9c7eeda5100fb0a7152fab7099c9cf9e5abd3bb36928eb98c7d7a339c6"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3b93043b14ba7eb08c57afca19751658ece1cfa2f0b7b1fb5c7a41452fbb8482"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:c09956606c08c4a7c6178a04ba2dd9388fcc5db32002ade9c9bc865ab156ab6d"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:b0cfe925610f2fd59555bb7fc37bd739e4b197d33f2a8b2fae7b9c0c6640318c"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:4d00b91c77ceb064c9b0459f0d6ea5bfdbc53ea9e17cf75731e151ef25a830c7"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:c6258a3663780ae47ba73d43eb63c79c40ffddfb764e09b56df33be2f9479837"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29e758f0e734e1e90357ae01ec9c6daf19ff60a051192fe110d8fb25c62600e"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f3621a46cdc7a9ba8080422262398a91762a581d27e0647746588d3f995c88"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:47f7aa217b25833cd6f0e72b0d224be55393c2692b4f5e0561cb3beeb10296e9"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2fdc855149efe7cdcc2a01ca02bfa24761c640203ea94df467f3baf19078be"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5effd87c7d363890259eac16c56a4e8da307286012c076223997f8cc4a8c435b"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6dd1cf2995fdbd64fc0802313e8323f5fa18994d51af059b5b8862b73b5e53f0"}, + {file = "pymongo-4.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bb869707d8e30645ed6766e44098600ca6cdf7989c22a3ea2b7966bb1d98d4b2"}, + {file = "pymongo-4.3.3-cp37-cp37m-win32.whl", hash = "sha256:49210feb0be8051a64d71691f0acbfbedc33e149f0a5d6e271fddf6a12493fed"}, + {file = "pymongo-4.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:54c377893f2cbbffe39abcff5ff2e917b082c364521fa079305f6f064e1a24a9"}, + {file = "pymongo-4.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c184ec5be465c0319440734491e1aa4709b5f3ba75fdfc9dbbc2ae715a7f6829"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:dca34367a4e77fcab0693e603a959878eaf2351585e7d752cac544bc6b2dee46"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cd6a4afb20fb3c26a7bfd4611a0bbb24d93cbd746f5eb881f114b5e38fd55501"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0c466710871d0026c190fc4141e810cf9d9affbf4935e1d273fbdc7d7cda6143"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:d07d06dba5b5f7d80f9cc45501456e440f759fe79f9895922ed486237ac378a8"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:711bc52cb98e7892c03e9b669bebd89c0a890a90dbc6d5bb2c47f30239bac6e9"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:34b040e095e1671df0c095ec0b04fc4ebb19c4c160f87c2b55c079b16b1a6b00"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:4ed00f96e147f40b565fe7530d1da0b0f3ab803d5dd5b683834500fa5d195ec4"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef888f48eb9203ee1e04b9fb27429017b290fb916f1e7826c2f7808c88798394"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:316498b642c00401370b2156b5233b256f9b33799e0a8d9d0b8a7da217a20fca"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa7e202feb683dad74f00dea066690448d0cfa310f8a277db06ec8eb466601b5"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52896e22115c97f1c829db32aa2760b0d61839cfe08b168c2b1d82f31dbc5f55"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c051fe37c96b9878f37fa58906cb53ecd13dcb7341d3a85f1e2e2f6b10782d9"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5134d33286c045393c7beb51be29754647cec5ebc051cf82799c5ce9820a2ca2"}, + {file = "pymongo-4.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a9c2885b4a8e6e39db5662d8b02ca6dcec796a45e48c2de12552841f061692ba"}, + {file = "pymongo-4.3.3-cp38-cp38-win32.whl", hash = "sha256:a6cd6f1db75eb07332bd3710f58f5fce4967eadbf751bad653842750a61bda62"}, + {file = "pymongo-4.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:d5571b6978750601f783cea07fb6b666837010ca57e5cefa389c1d456f6222e2"}, + {file = "pymongo-4.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:81d1a7303bd02ca1c5be4aacd4db73593f573ba8e0c543c04c6da6275fd7a47e"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:016c412118e1c23fef3a1eada4f83ae6e8844fd91986b2e066fc1b0013cdd9ae"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:8fd6e191b92a10310f5a6cfe10d6f839d79d192fb02480bda325286bd1c7b385"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:e2961b05f9c04a53da8bfc72f1910b6aec7205fcf3ac9c036d24619979bbee4b"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:b38a96b3eed8edc515b38257f03216f382c4389d022a8834667e2bc63c0c0c31"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:c1a70c51da9fa95bd75c167edb2eb3f3c4d27bc4ddd29e588f21649d014ec0b7"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:8a06a0c02f5606330e8f2e2f3b7949877ca7e4024fa2bff5a4506bec66c49ec7"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:6c2216d8b6a6d019c6f4b1ad55f890e5e77eb089309ffc05b6911c09349e7474"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eac0a143ef4f28f49670bf89cb15847eb80b375d55eba401ca2f777cd425f338"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:08fc250b5552ee97ceeae0f52d8b04f360291285fc7437f13daa516ce38fdbc6"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704d939656e21b073bfcddd7228b29e0e8a93dd27b54240eaafc0b9a631629a6"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1074f1a6f23e28b983c96142f2d45be03ec55d93035b471c26889a7ad2365db3"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b16250238de8dafca225647608dddc7bbb5dce3dd53b4d8e63c1cc287394c2f"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7761cacb8745093062695b11574effea69db636c2fd0a9269a1f0183712927b4"}, + {file = "pymongo-4.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fd7bb378d82b88387dc10227cfd964f6273eb083e05299e9b97cbe075da12d11"}, + {file = "pymongo-4.3.3-cp39-cp39-win32.whl", hash = "sha256:dc24d245026a72d9b4953729d31813edd4bd4e5c13622d96e27c284942d33f24"}, + {file = "pymongo-4.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:fc28e8d85d392a06434e9a934908d97e2cf453d69488d2bcd0bfb881497fd975"}, + {file = "pymongo-4.3.3.tar.gz", hash = "sha256:34e95ffb0a68bffbc3b437f2d1f25fc916fef3df5cdeed0992da5f42fae9b807"}, +] + +[package.dependencies] +dnspython = ">=1.16.0,<3.0.0" + +[package.extras] +aws = ["pymongo-auth-aws (<2.0.0)"] +encryption = ["pymongo-auth-aws (<2.0.0)", "pymongocrypt (>=1.3.0,<2.0.0)"] +gssapi = ["pykerberos"] +ocsp = ["certifi", "pyopenssl (>=17.2.0)", "requests (<3.0.0)", "service-identity (>=18.1.0)"] +snappy = ["python-snappy"] +zstd = ["zstandard"] + +[[package]] +name = "pypika" +version = "0.48.9" +description = "A SQL query builder API for Python" +optional = false +python-versions = "*" +files = [ + {file = "PyPika-0.48.9.tar.gz", hash = "sha256:838836a61747e7c8380cd1b7ff638694b7a7335345d0f559b04b2cd832ad5378"}, +] + +[[package]] +name = "pyproject-hooks" +version = "1.0.0" +description = "Wrappers to call pyproject.toml-based build backend hooks." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"}, + {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"}, +] + +[[package]] +name = "pyreadline3" +version = "3.4.1" +description = "A python implementation of GNU readline." +optional = false +python-versions = "*" +files = [ + {file = "pyreadline3-3.4.1-py3-none-any.whl", hash = "sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb"}, + {file = "pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae"}, +] + +[[package]] +name = "pytest" +version = "7.4.4" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-dotenv" +version = "1.0.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, + {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "python-jose" +version = "3.3.0" +description = "JOSE implementation in Python" +optional = false +python-versions = "*" +files = [ + {file = "python-jose-3.3.0.tar.gz", hash = "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a"}, + {file = "python_jose-3.3.0-py2.py3-none-any.whl", hash = "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a"}, +] + +[package.dependencies] +ecdsa = "!=0.15" +pyasn1 = "*" +rsa = "*" + +[package.extras] +cryptography = ["cryptography (>=3.4.0)"] +pycrypto = ["pyasn1", "pycrypto (>=2.6.0,<2.7.0)"] +pycryptodome = ["pyasn1", "pycryptodome (>=3.3.1,<4.0.0)"] + +[[package]] +name = "python-multipart" +version = "0.0.6" +description = "A streaming multipart parser for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python_multipart-0.0.6-py3-none-any.whl", hash = "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18"}, + {file = "python_multipart-0.0.6.tar.gz", hash = "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132"}, +] + +[package.extras] +dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==1.7.3)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "redis" +version = "5.0.1" +description = "Python client for Redis database and key-value store" +optional = false +python-versions = ">=3.7" +files = [ + {file = "redis-5.0.1-py3-none-any.whl", hash = "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f"}, + {file = "redis-5.0.1.tar.gz", hash = "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f"}, +] + +[package.dependencies] +async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} + +[package.extras] +hiredis = ["hiredis (>=1.0.0)"] +ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] + +[[package]] +name = "regex" +version = "2023.12.25" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.7" +files = [ + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, + {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, + {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, + {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, + {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, + {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, + {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, + {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, + {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, + {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, + {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, + {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, + {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, + {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, + {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-oauthlib" +version = "1.3.1" +description = "OAuthlib authentication support for Requests." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, + {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, +] + +[package.dependencies] +oauthlib = ">=3.0.0" +requests = ">=2.0.0" + +[package.extras] +rsa = ["oauthlib[signedtoken] (>=3.0.0)"] + +[[package]] +name = "rsa" +version = "4.9" +description = "Pure-Python RSA implementation" +optional = false +python-versions = ">=3.6,<4" +files = [ + {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, + {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, +] + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +name = "s3transfer" +version = "0.10.0" +description = "An Amazon S3 Transfer Manager" +optional = false +python-versions = ">= 3.8" +files = [ + {file = "s3transfer-0.10.0-py3-none-any.whl", hash = "sha256:3cdb40f5cfa6966e812209d0994f2a4709b561c88e90cf00c2696d2df4e56b2e"}, + {file = "s3transfer-0.10.0.tar.gz", hash = "sha256:d0c8bbf672d5eebbe4e57945e23b972d963f07d82f661cabf678a5c88831595b"}, +] + +[package.dependencies] +botocore = ">=1.33.2,<2.0a.0" + +[package.extras] +crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] + +[[package]] +name = "safetensors" +version = "0.4.1" +description = "" +optional = false +python-versions = ">=3.7" +files = [ + {file = "safetensors-0.4.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:cba01c6b76e01ec453933b3b3c0157c59b52881c83eaa0f7666244e71aa75fd1"}, + {file = "safetensors-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a8f6f679d97ea0135c7935c202feefbd042c149aa70ee759855e890c01c7814"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbc2ce1f5ae5143a7fb72b71fa71db6a42b4f6cf912aa3acdc6b914084778e68"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d87d993eaefe6611a9c241a8bd364a5f1ffed5771c74840363a6c4ed8d868f6"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:097e9af2efa8778cd2f0cba451784253e62fa7cc9fc73c0744d27212f7294e25"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d10a9f7bae608ccfdc009351f01dc3d8535ff57f9488a58a4c38e45bf954fe93"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:270b99885ec14abfd56c1d7f28ada81740a9220b4bae960c3de1c6fe84af9e4d"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:285b52a481e7ba93e29ad4ec5841ef2c4479ef0a6c633c4e2629e0508453577b"}, + {file = "safetensors-0.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c3c9f0ca510e0de95abd6424789dcbc879942a3a4e29b0dfa99d9427bf1da75c"}, + {file = "safetensors-0.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:88b4653059c903015284a9722f9a46838c654257173b279c8f6f46dbe80b612d"}, + {file = "safetensors-0.4.1-cp310-none-win32.whl", hash = "sha256:2fe6926110e3d425c4b684a4379b7796fdc26ad7d16922ea1696c8e6ea7e920f"}, + {file = "safetensors-0.4.1-cp310-none-win_amd64.whl", hash = "sha256:a79e16222106b2f5edbca1b8185661477d8971b659a3c814cc6f15181a9b34c8"}, + {file = "safetensors-0.4.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:d93321eea0dd7e81b283e47a1d20dee6069165cc158286316d0d06d340de8fe8"}, + {file = "safetensors-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8ff8e41c8037db17de0ea2a23bc684f43eaf623be7d34906fe1ac10985b8365e"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39d36f1d88468a87c437a1bc27c502e71b6ca44c385a9117a9f9ba03a75cc9c6"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7ef010e9afcb4057fb6be3d0a0cfa07aac04fe97ef73fe4a23138d8522ba7c17"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b287304f2b2220d51ccb51fd857761e78bcffbeabe7b0238f8dc36f2edfd9542"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e09000b2599e1836314430f81a3884c66a5cbabdff5d9f175b5d560d4de38d78"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9c80ce0001efa16066358d2dd77993adc25f5a6c61850e4ad096a2232930bce"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:413e1f6ac248f7d1b755199a06635e70c3515493d3b41ba46063dec33aa2ebb7"}, + {file = "safetensors-0.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3ac139377cfe71ba04573f1cda66e663b7c3e95be850e9e6c2dd4b5984bd513"}, + {file = "safetensors-0.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:04157d008385bea66d12fe90844a80d4a76dc25ec5230b5bd9a630496d1b7c03"}, + {file = "safetensors-0.4.1-cp311-none-win32.whl", hash = "sha256:5f25297148ec665f0deb8bd67e9564634d8d6841041ab5393ccfe203379ea88b"}, + {file = "safetensors-0.4.1-cp311-none-win_amd64.whl", hash = "sha256:b2f8877990a72ff595507b80f4b69036a9a1986a641f8681adf3425d97d3d2a5"}, + {file = "safetensors-0.4.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:eb2c1da1cc39509d1a55620a5f4d14f8911c47a89c926a96e6f4876e864375a3"}, + {file = "safetensors-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:303d2c0415cf15a28f8d7f17379ea3c34c2b466119118a34edd9965983a1a8a6"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb4cb3e37a9b961ddd68e873b29fe9ab4a081e3703412e34aedd2b7a8e9cafd9"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae5497adc68669db2fed7cb2dad81e6a6106e79c9a132da3efdb6af1db1014fa"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b30abd0cddfe959d1daedf92edcd1b445521ebf7ddefc20860ed01486b33c90"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d784a98c492c751f228a4a894c3b8a092ff08b24e73b5568938c28b8c0e8f8df"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57a5ab08b0ec7a7caf30d2ac79bb30c89168431aca4f8854464bb9461686925"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:edcf3121890b5f0616aa5a54683b1a5d2332037b970e507d6bb7841a3a596556"}, + {file = "safetensors-0.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fdb58dee173ef33634c3016c459d671ca12d11e6acf9db008261cbe58107e579"}, + {file = "safetensors-0.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:780dc21eb3fd32ddd0e8c904bdb0290f2454f4ac21ae71e94f9ce72db1900a5a"}, + {file = "safetensors-0.4.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:48901bd540f8a3c1791314bc5c8a170927bf7f6acddb75bf0a263d081a3637d4"}, + {file = "safetensors-0.4.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:3b0b7b2d5976fbed8a05e2bbdce5816a59e6902e9e7c7e07dc723637ed539787"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f69903ff49cb30b9227fb5d029bea276ea20d04b06803877a420c5b1b74c689"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0ddd050e01f3e843aa8c1c27bf68675b8a08e385d0045487af4d70418c3cb356"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a82bc2bd7a9a0e08239bdd6d7774d64121f136add93dfa344a2f1a6d7ef35fa"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ace9e66a40f98a216ad661245782483cf79cf56eb2b112650bb904b0baa9db5"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82cbb8f4d022f2e94498cbefca900698b8ded3d4f85212f47da614001ff06652"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:791edc10a3c359a2f5f52d5cddab0df8a45107d91027d86c3d44e57162e5d934"}, + {file = "safetensors-0.4.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:83c2cfbe8c6304f0891e7bb378d56f66d2148972eeb5f747cd8a2246886f0d8c"}, + {file = "safetensors-0.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:04dd14f53f5500eb4c4149674216ba1000670efbcf4b1b5c2643eb244e7882ea"}, + {file = "safetensors-0.4.1-cp37-none-win32.whl", hash = "sha256:d5b3defa74f3723a388bfde2f5d488742bc4879682bd93267c09a3bcdf8f869b"}, + {file = "safetensors-0.4.1-cp37-none-win_amd64.whl", hash = "sha256:25a043cbb59d4f75e9dd87fdf5c009dd8830105a2c57ace49b72167dd9808111"}, + {file = "safetensors-0.4.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:3f6a520af7f2717c5ecba112041f2c8af1ca6480b97bf957aba81ed9642e654c"}, + {file = "safetensors-0.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c3807ac3b16288dffebb3474b555b56fe466baa677dfc16290dcd02dca1ab228"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b58ba13a9e82b4bc3fc221914f6ef237fe6c2adb13cede3ace64d1aacf49610"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dac4bb42f8679aadc59bd91a4c5a1784a758ad49d0912995945cd674089f628e"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911b48dc09e321a194def3a7431662ff4f03646832f3a8915bbf0f449b8a5fcb"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82571d20288c975c1b30b08deb9b1c3550f36b31191e1e81fae87669a92217d0"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da52ee0dc8ba03348ffceab767bd8230842fdf78f8a996e2a16445747143a778"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2536b11ce665834201072e9397404170f93f3be10cca9995b909f023a04501ee"}, + {file = "safetensors-0.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:998fbac99ca956c3a09fe07cc0b35fac26a521fa8865a690686d889f0ff4e4a6"}, + {file = "safetensors-0.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:845be0aafabf2a60c2d482d4e93023fecffe5e5443d801d7a7741bae9de41233"}, + {file = "safetensors-0.4.1-cp38-none-win32.whl", hash = "sha256:ce7a28bc8af685a69d7e869d09d3e180a275e3281e29cf5f1c7319e231932cc7"}, + {file = "safetensors-0.4.1-cp38-none-win_amd64.whl", hash = "sha256:e056fb9e22d118cc546107f97dc28b449d88274207dd28872bd668c86216e4f6"}, + {file = "safetensors-0.4.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:bdc0d039e44a727824639824090bd8869535f729878fa248addd3dc01db30eae"}, + {file = "safetensors-0.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c1b1d510c7aba71504ece87bf393ea82638df56303e371e5e2cf09d18977dd7"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bd0afd95c1e497f520e680ea01e0397c0868a3a3030e128438cf6e9e3fcd671"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f603bdd8deac6726d39f41688ed353c532dd53935234405d79e9eb53f152fbfb"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8a85e3e47e0d4eebfaf9a58b40aa94f977a56050cb5598ad5396a9ee7c087c6"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0ccb5aa0f3be2727117e5631200fbb3a5b3a2b3757545a92647d6dd8be6658f"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d784938534e255473155e4d9f276ee69eb85455b6af1292172c731409bf9adee"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a257de175c254d39ccd6a21341cd62eb7373b05c1e618a78096a56a857e0c316"}, + {file = "safetensors-0.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6fd80f7794554091836d4d613d33a7d006e2b8d6ba014d06f97cebdfda744f64"}, + {file = "safetensors-0.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:35803201d980efcf964b75a0a2aee97fe5e9ecc5f3ad676b38fafdfe98e0620d"}, + {file = "safetensors-0.4.1-cp39-none-win32.whl", hash = "sha256:7ff8a36e0396776d3ed9a106fc9a9d7c55d4439ca9a056a24bf66d343041d3e6"}, + {file = "safetensors-0.4.1-cp39-none-win_amd64.whl", hash = "sha256:bfa2e20342b81921b98edba52f8deb68843fa9c95250739a56b52ceda5ea5c61"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ae2d5a31cfb8a973a318f7c4d2cffe0bd1fe753cdf7bb41a1939d45a0a06f964"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1a45dbf03e8334d3a5dc93687d98b6dc422f5d04c7d519dac09b84a3c87dd7c6"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297b359d91126c0f9d4fd17bae3cfa2fe3a048a6971b8db07db746ad92f850c"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bda3d98e2bcece388232cfc551ebf063b55bdb98f65ab54df397da30efc7dcc5"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8934bdfd202ebd0697040a3dff40dd77bc4c5bbf3527ede0532f5e7fb4d970f"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:42c3710cec7e5c764c7999697516370bee39067de0aa089b7e2cfb97ac8c6b20"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:53134226053e56bd56e73f7db42596e7908ed79f3c9a1016e4c1dade593ac8e5"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:257d59e40a1b367cb544122e7451243d65b33c3f34d822a347f4eea6fdf97fdf"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d54c2f1826e790d1eb2d2512bfd0ee443f0206b423d6f27095057c7f18a0687"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:645b3f1138fce6e818e79d4128afa28f0657430764cc045419c1d069ff93f732"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e9a7ffb1e551c6df51d267f5a751f042b183df22690f6feceac8d27364fd51d7"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:44e230fbbe120de564b64f63ef3a8e6ff02840fa02849d9c443d56252a1646d4"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:9d16b3b2fcc6fca012c74bd01b5619c655194d3e3c13e4d4d0e446eefa39a463"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5d95ea4d8b32233910734a904123bdd3979c137c461b905a5ed32511defc075f"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:dab431699b5d45e0ca043bc580651ce9583dda594e62e245b7497adb32e99809"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16d8bbb7344e39cb9d4762e85c21df94ebeb03edac923dd94bb9ed8c10eac070"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1faf5111c66a6ba91f85dff2e36edaaf36e6966172703159daeef330de4ddc7b"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:660ca1d8bff6c7bc7c6b30b9b32df74ef3ab668f5df42cefd7588f0d40feadcb"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ae2f67f04ed0bb2e56fd380a8bd3eef03f609df53f88b6f5c7e89c08e52aae00"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:c8ed5d2c04cdc1afc6b3c28d59580448ac07732c50d94c15e14670f9c473a2ce"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:2b6a2814278b6660261aa9a9aae524616de9f1ec364e3716d219b6ed8f91801f"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3cfd1ca35eacc635f0eaa894e5c5ed83ffebd0f95cac298fd430014fa7323631"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4177b456c6b0c722d82429127b5beebdaf07149d265748e97e0a34ff0b3694c8"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:313e8472197bde54e3ec54a62df184c414582979da8f3916981b6a7954910a1b"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fdb4adb76e21bad318210310590de61c9f4adcef77ee49b4a234f9dc48867869"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:1d568628e9c43ca15eb96c217da73737c9ccb07520fafd8a1eba3f2750614105"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:573b6023a55a2f28085fc0a84e196c779b6cbef4d9e73acea14c8094fee7686f"}, + {file = "safetensors-0.4.1.tar.gz", hash = "sha256:2304658e6ada81a5223225b4efe84748e760c46079bffedf7e321763cafb36c9"}, +] + +[package.extras] +all = ["safetensors[jax]", "safetensors[numpy]", "safetensors[paddlepaddle]", "safetensors[pinned-tf]", "safetensors[quality]", "safetensors[testing]", "safetensors[torch]"] +dev = ["safetensors[all]"] +jax = ["flax (>=0.6.3)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "safetensors[numpy]"] +numpy = ["numpy (>=1.21.6)"] +paddlepaddle = ["paddlepaddle (>=2.4.1)", "safetensors[numpy]"] +pinned-tf = ["safetensors[numpy]", "tensorflow (==2.11.0)"] +quality = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "isort (>=5.5.4)"] +tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] +testing = ["h5py (>=3.7.0)", "huggingface_hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools_rust (>=1.5.2)"] +torch = ["safetensors[numpy]", "torch (>=1.10)"] + +[[package]] +name = "scikit-learn" +version = "1.3.2" +description = "A set of python modules for machine learning and data mining" +optional = false +python-versions = ">=3.8" +files = [ + {file = "scikit-learn-1.3.2.tar.gz", hash = "sha256:a2f54c76accc15a34bfb9066e6c7a56c1e7235dda5762b990792330b52ccfb05"}, + {file = "scikit_learn-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e326c0eb5cf4d6ba40f93776a20e9a7a69524c4db0757e7ce24ba222471ee8a1"}, + {file = "scikit_learn-1.3.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:535805c2a01ccb40ca4ab7d081d771aea67e535153e35a1fd99418fcedd1648a"}, + {file = "scikit_learn-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1215e5e58e9880b554b01187b8c9390bf4dc4692eedeaf542d3273f4785e342c"}, + {file = "scikit_learn-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ee107923a623b9f517754ea2f69ea3b62fc898a3641766cb7deb2f2ce450161"}, + {file = "scikit_learn-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:35a22e8015048c628ad099da9df5ab3004cdbf81edc75b396fd0cff8699ac58c"}, + {file = "scikit_learn-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6fb6bc98f234fda43163ddbe36df8bcde1d13ee176c6dc9b92bb7d3fc842eb66"}, + {file = "scikit_learn-1.3.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:18424efee518a1cde7b0b53a422cde2f6625197de6af36da0b57ec502f126157"}, + {file = "scikit_learn-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3271552a5eb16f208a6f7f617b8cc6d1f137b52c8a1ef8edf547db0259b2c9fb"}, + {file = "scikit_learn-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4144a5004a676d5022b798d9e573b05139e77f271253a4703eed295bde0433"}, + {file = "scikit_learn-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:67f37d708f042a9b8d59551cf94d30431e01374e00dc2645fa186059c6c5d78b"}, + {file = "scikit_learn-1.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8db94cd8a2e038b37a80a04df8783e09caac77cbe052146432e67800e430c028"}, + {file = "scikit_learn-1.3.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:61a6efd384258789aa89415a410dcdb39a50e19d3d8410bd29be365bcdd512d5"}, + {file = "scikit_learn-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb06f8dce3f5ddc5dee1715a9b9f19f20d295bed8e3cd4fa51e1d050347de525"}, + {file = "scikit_learn-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b2de18d86f630d68fe1f87af690d451388bb186480afc719e5f770590c2ef6c"}, + {file = "scikit_learn-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:0402638c9a7c219ee52c94cbebc8fcb5eb9fe9c773717965c1f4185588ad3107"}, + {file = "scikit_learn-1.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a19f90f95ba93c1a7f7924906d0576a84da7f3b2282ac3bfb7a08a32801add93"}, + {file = "scikit_learn-1.3.2-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:b8692e395a03a60cd927125eef3a8e3424d86dde9b2370d544f0ea35f78a8073"}, + {file = "scikit_learn-1.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15e1e94cc23d04d39da797ee34236ce2375ddea158b10bee3c343647d615581d"}, + {file = "scikit_learn-1.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:785a2213086b7b1abf037aeadbbd6d67159feb3e30263434139c98425e3dcfcf"}, + {file = "scikit_learn-1.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:64381066f8aa63c2710e6b56edc9f0894cc7bf59bd71b8ce5613a4559b6145e0"}, + {file = "scikit_learn-1.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6c43290337f7a4b969d207e620658372ba3c1ffb611f8bc2b6f031dc5c6d1d03"}, + {file = "scikit_learn-1.3.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:dc9002fc200bed597d5d34e90c752b74df516d592db162f756cc52836b38fe0e"}, + {file = "scikit_learn-1.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d08ada33e955c54355d909b9c06a4789a729977f165b8bae6f225ff0a60ec4a"}, + {file = "scikit_learn-1.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:763f0ae4b79b0ff9cca0bf3716bcc9915bdacff3cebea15ec79652d1cc4fa5c9"}, + {file = "scikit_learn-1.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:ed932ea780517b00dae7431e031faae6b49b20eb6950918eb83bd043237950e0"}, +] + +[package.dependencies] +joblib = ">=1.1.1" +numpy = ">=1.17.3,<2.0" +scipy = ">=1.5.0" +threadpoolctl = ">=2.0.0" + +[package.extras] +benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.10.1)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] +tests = ["black (>=23.3.0)", "matplotlib (>=3.1.3)", "mypy (>=1.3)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.0.272)", "scikit-image (>=0.16.2)"] + +[[package]] +name = "scipy" +version = "1.11.4" +description = "Fundamental algorithms for scientific computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "scipy-1.11.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc9a714581f561af0848e6b69947fda0614915f072dfd14142ed1bfe1b806710"}, + {file = "scipy-1.11.4-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:cf00bd2b1b0211888d4dc75656c0412213a8b25e80d73898083f402b50f47e41"}, + {file = "scipy-1.11.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9999c008ccf00e8fbcce1236f85ade5c569d13144f77a1946bef8863e8f6eb4"}, + {file = "scipy-1.11.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:933baf588daa8dc9a92c20a0be32f56d43faf3d1a60ab11b3f08c356430f6e56"}, + {file = "scipy-1.11.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8fce70f39076a5aa62e92e69a7f62349f9574d8405c0a5de6ed3ef72de07f446"}, + {file = "scipy-1.11.4-cp310-cp310-win_amd64.whl", hash = "sha256:6550466fbeec7453d7465e74d4f4b19f905642c89a7525571ee91dd7adabb5a3"}, + {file = "scipy-1.11.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f313b39a7e94f296025e3cffc2c567618174c0b1dde173960cf23808f9fae4be"}, + {file = "scipy-1.11.4-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:1b7c3dca977f30a739e0409fb001056484661cb2541a01aba0bb0029f7b68db8"}, + {file = "scipy-1.11.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00150c5eae7b610c32589dda259eacc7c4f1665aedf25d921907f4d08a951b1c"}, + {file = "scipy-1.11.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:530f9ad26440e85766509dbf78edcfe13ffd0ab7fec2560ee5c36ff74d6269ff"}, + {file = "scipy-1.11.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5e347b14fe01003d3b78e196e84bd3f48ffe4c8a7b8a1afbcb8f5505cb710993"}, + {file = "scipy-1.11.4-cp311-cp311-win_amd64.whl", hash = "sha256:acf8ed278cc03f5aff035e69cb511741e0418681d25fbbb86ca65429c4f4d9cd"}, + {file = "scipy-1.11.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:028eccd22e654b3ea01ee63705681ee79933652b2d8f873e7949898dda6d11b6"}, + {file = "scipy-1.11.4-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2c6ff6ef9cc27f9b3db93a6f8b38f97387e6e0591600369a297a50a8e96e835d"}, + {file = "scipy-1.11.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b030c6674b9230d37c5c60ab456e2cf12f6784596d15ce8da9365e70896effc4"}, + {file = "scipy-1.11.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad669df80528aeca5f557712102538f4f37e503f0c5b9541655016dd0932ca79"}, + {file = "scipy-1.11.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce7fff2e23ab2cc81ff452a9444c215c28e6305f396b2ba88343a567feec9660"}, + {file = "scipy-1.11.4-cp312-cp312-win_amd64.whl", hash = "sha256:36750b7733d960d7994888f0d148d31ea3017ac15eef664194b4ef68d36a4a97"}, + {file = "scipy-1.11.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e619aba2df228a9b34718efb023966da781e89dd3d21637b27f2e54db0410d7"}, + {file = "scipy-1.11.4-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:f3cd9e7b3c2c1ec26364856f9fbe78695fe631150f94cd1c22228456404cf1ec"}, + {file = "scipy-1.11.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d10e45a6c50211fe256da61a11c34927c68f277e03138777bdebedd933712fea"}, + {file = "scipy-1.11.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91af76a68eeae0064887a48e25c4e616fa519fa0d38602eda7e0f97d65d57937"}, + {file = "scipy-1.11.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6df1468153a31cf55ed5ed39647279beb9cfb5d3f84369453b49e4b8502394fd"}, + {file = "scipy-1.11.4-cp39-cp39-win_amd64.whl", hash = "sha256:ee410e6de8f88fd5cf6eadd73c135020bfbbbdfcd0f6162c36a7638a1ea8cc65"}, + {file = "scipy-1.11.4.tar.gz", hash = "sha256:90a2b78e7f5733b9de748f589f09225013685f9b218275257f8a8168ededaeaa"}, +] + +[package.dependencies] +numpy = ">=1.21.6,<1.28.0" + +[package.extras] +dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] +test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "sentence-transformers" +version = "2.2.2" +description = "Multilingual text embeddings" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "sentence-transformers-2.2.2.tar.gz", hash = "sha256:dbc60163b27de21076c9a30d24b5b7b6fa05141d68cf2553fa9a77bf79a29136"}, +] + +[package.dependencies] +huggingface-hub = ">=0.4.0" +nltk = "*" +numpy = "*" +scikit-learn = "*" +scipy = "*" +sentencepiece = "*" +torch = ">=1.6.0" +torchvision = "*" +tqdm = "*" +transformers = ">=4.6.0,<5.0.0" + +[[package]] +name = "sentencepiece" +version = "0.1.99" +description = "SentencePiece python wrapper" +optional = false +python-versions = "*" +files = [ + {file = "sentencepiece-0.1.99-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0eb528e70571b7c02723e5804322469b82fe7ea418c96051d0286c0fa028db73"}, + {file = "sentencepiece-0.1.99-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:77d7fafb2c4e4659cbdf303929503f37a26eabc4ff31d3a79bf1c5a1b338caa7"}, + {file = "sentencepiece-0.1.99-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be9cf5b9e404c245aeb3d3723c737ba7a8f5d4ba262ef233a431fa6c45f732a0"}, + {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baed1a26464998f9710d20e52607c29ffd4293e7c71c6a1f83f51ad0911ec12c"}, + {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9832f08bb372d4c8b567612f8eab9e36e268dff645f1c28f9f8e851be705f6d1"}, + {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:019e7535108e309dae2b253a75834fc3128240aa87c00eb80732078cdc182588"}, + {file = "sentencepiece-0.1.99-cp310-cp310-win32.whl", hash = "sha256:fa16a830416bb823fa2a52cbdd474d1f7f3bba527fd2304fb4b140dad31bb9bc"}, + {file = "sentencepiece-0.1.99-cp310-cp310-win_amd64.whl", hash = "sha256:14b0eccb7b641d4591c3e12ae44cab537d68352e4d3b6424944f0c447d2348d5"}, + {file = "sentencepiece-0.1.99-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6d3c56f24183a1e8bd61043ff2c58dfecdc68a5dd8955dc13bab83afd5f76b81"}, + {file = "sentencepiece-0.1.99-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed6ea1819fd612c989999e44a51bf556d0ef6abfb553080b9be3d347e18bcfb7"}, + {file = "sentencepiece-0.1.99-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2a0260cd1fb7bd8b4d4f39dc2444a8d5fd4e0a0c4d5c899810ef1abf99b2d45"}, + {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a1abff4d1ff81c77cac3cc6fefa34fa4b8b371e5ee51cb7e8d1ebc996d05983"}, + {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:004e6a621d4bc88978eecb6ea7959264239a17b70f2cbc348033d8195c9808ec"}, + {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db361e03342c41680afae5807590bc88aa0e17cfd1a42696a160e4005fcda03b"}, + {file = "sentencepiece-0.1.99-cp311-cp311-win32.whl", hash = "sha256:2d95e19168875b70df62916eb55428a0cbcb834ac51d5a7e664eda74def9e1e0"}, + {file = "sentencepiece-0.1.99-cp311-cp311-win_amd64.whl", hash = "sha256:f90d73a6f81248a909f55d8e6ef56fec32d559e1e9af045f0b0322637cb8e5c7"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:62e24c81e74bd87a6e0d63c51beb6527e4c0add67e1a17bac18bcd2076afcfeb"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57efcc2d51caff20d9573567d9fd3f854d9efe613ed58a439c78c9f93101384a"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a904c46197993bd1e95b93a6e373dca2f170379d64441041e2e628ad4afb16f"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89adf59854741c0d465f0e1525b388c0d174f611cc04af54153c5c4f36088c4"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-win32.whl", hash = "sha256:47c378146928690d1bc106fdf0da768cebd03b65dd8405aa3dd88f9c81e35dba"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-win_amd64.whl", hash = "sha256:9ba142e7a90dd6d823c44f9870abdad45e6c63958eb60fe44cca6828d3b69da2"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b7b1a9ae4d7c6f1f867e63370cca25cc17b6f4886729595b885ee07a58d3cec3"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0f644c9d4d35c096a538507b2163e6191512460035bf51358794a78515b74f7"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8843d23a0f686d85e569bd6dcd0dd0e0cbc03731e63497ca6d5bacd18df8b85"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33e6f690a1caebb4867a2e367afa1918ad35be257ecdb3455d2bbd787936f155"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-win32.whl", hash = "sha256:8a321866c2f85da7beac74a824b4ad6ddc2a4c9bccd9382529506d48f744a12c"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-win_amd64.whl", hash = "sha256:c42f753bcfb7661c122a15b20be7f684b61fc8592c89c870adf52382ea72262d"}, + {file = "sentencepiece-0.1.99-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:85b476406da69c70586f0bb682fcca4c9b40e5059814f2db92303ea4585c650c"}, + {file = "sentencepiece-0.1.99-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cfbcfe13c69d3f87b7fcd5da168df7290a6d006329be71f90ba4f56bc77f8561"}, + {file = "sentencepiece-0.1.99-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:445b0ec381af1cd4eef95243e7180c63d9c384443c16c4c47a28196bd1cda937"}, + {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6890ea0f2b4703f62d0bf27932e35808b1f679bdb05c7eeb3812b935ba02001"}, + {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb71af492b0eefbf9f2501bec97bcd043b6812ab000d119eaf4bd33f9e283d03"}, + {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27b866b5bd3ddd54166bbcbf5c8d7dd2e0b397fac8537991c7f544220b1f67bc"}, + {file = "sentencepiece-0.1.99-cp38-cp38-win32.whl", hash = "sha256:b133e8a499eac49c581c3c76e9bdd08c338cc1939e441fee6f92c0ccb5f1f8be"}, + {file = "sentencepiece-0.1.99-cp38-cp38-win_amd64.whl", hash = "sha256:0eaf3591dd0690a87f44f4df129cf8d05d8a4029b5b6709b489b8e27f9a9bcff"}, + {file = "sentencepiece-0.1.99-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38efeda9bbfb55052d482a009c6a37e52f42ebffcea9d3a98a61de7aee356a28"}, + {file = "sentencepiece-0.1.99-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6c030b081dc1e1bcc9fadc314b19b740715d3d566ad73a482da20d7d46fd444c"}, + {file = "sentencepiece-0.1.99-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84dbe53e02e4f8a2e45d2ac3e430d5c83182142658e25edd76539b7648928727"}, + {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b0f55d0a0ee1719b4b04221fe0c9f0c3461dc3dabd77a035fa2f4788eb3ef9a"}, + {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e800f206cd235dc27dc749299e05853a4e4332e8d3dfd81bf13d0e5b9007d9"}, + {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ae1c40cda8f9d5b0423cfa98542735c0235e7597d79caf318855cdf971b2280"}, + {file = "sentencepiece-0.1.99-cp39-cp39-win32.whl", hash = "sha256:c84ce33af12ca222d14a1cdd37bd76a69401e32bc68fe61c67ef6b59402f4ab8"}, + {file = "sentencepiece-0.1.99-cp39-cp39-win_amd64.whl", hash = "sha256:350e5c74d739973f1c9643edb80f7cc904dc948578bcb1d43c6f2b173e5d18dd"}, + {file = "sentencepiece-0.1.99.tar.gz", hash = "sha256:189c48f5cb2949288f97ccdb97f0473098d9c3dcf5a3d99d4eabe719ec27297f"}, +] + +[[package]] +name = "sentry-sdk" +version = "1.39.2" +description = "Python client for Sentry (https://sentry.io)" +optional = false +python-versions = "*" +files = [ + {file = "sentry-sdk-1.39.2.tar.gz", hash = "sha256:24c83b0b41c887d33328a9166f5950dc37ad58f01c9f2fbff6b87a6f1094170c"}, + {file = "sentry_sdk-1.39.2-py2.py3-none-any.whl", hash = "sha256:acaf597b30258fc7663063b291aa99e58f3096e91fe1e6634f4b79f9c1943e8e"}, +] + +[package.dependencies] +certifi = "*" +fastapi = {version = ">=0.79.0", optional = true, markers = "extra == \"fastapi\""} +urllib3 = {version = ">=1.26.11", markers = "python_version >= \"3.6\""} + +[package.extras] +aiohttp = ["aiohttp (>=3.5)"] +arq = ["arq (>=0.23)"] +asyncpg = ["asyncpg (>=0.23)"] +beam = ["apache-beam (>=2.12)"] +bottle = ["bottle (>=0.12.13)"] +celery = ["celery (>=3)"] +chalice = ["chalice (>=1.16.0)"] +clickhouse-driver = ["clickhouse-driver (>=0.2.0)"] +django = ["django (>=1.8)"] +falcon = ["falcon (>=1.4)"] +fastapi = ["fastapi (>=0.79.0)"] +flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"] +grpcio = ["grpcio (>=1.21.1)"] +httpx = ["httpx (>=0.16.0)"] +huey = ["huey (>=2)"] +loguru = ["loguru (>=0.5)"] +opentelemetry = ["opentelemetry-distro (>=0.35b0)"] +opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] +pure-eval = ["asttokens", "executing", "pure_eval"] +pymongo = ["pymongo (>=3.1)"] +pyspark = ["pyspark (>=2.4.4)"] +quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] +rq = ["rq (>=0.6)"] +sanic = ["sanic (>=0.8)"] +sqlalchemy = ["sqlalchemy (>=1.2)"] +starlette = ["starlette (>=0.19.1)"] +starlite = ["starlite (>=1.48)"] +tornado = ["tornado (>=5)"] + +[[package]] +name = "setuptools" +version = "69.0.3" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, + {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sniffio" +version = "1.3.0" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] + +[[package]] +name = "sqlalchemy" +version = "1.4.51" +description = "Database Abstraction Library" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "SQLAlchemy-1.4.51-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:1a09d5bd1a40d76ad90e5570530e082ddc000e1d92de495746f6257dc08f166b"}, + {file = "SQLAlchemy-1.4.51-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2be4e6294c53f2ec8ea36486b56390e3bcaa052bf3a9a47005687ccf376745d1"}, + {file = "SQLAlchemy-1.4.51-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca484ca11c65e05639ffe80f20d45e6be81fbec7683d6c9a15cd421e6e8b340"}, + {file = "SQLAlchemy-1.4.51-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0535d5b57d014d06ceeaeffd816bb3a6e2dddeb670222570b8c4953e2d2ea678"}, + {file = "SQLAlchemy-1.4.51-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af55cc207865d641a57f7044e98b08b09220da3d1b13a46f26487cc2f898a072"}, + {file = "SQLAlchemy-1.4.51-cp310-cp310-win32.whl", hash = "sha256:7af40425ac535cbda129d9915edcaa002afe35d84609fd3b9d6a8c46732e02ee"}, + {file = "SQLAlchemy-1.4.51-cp310-cp310-win_amd64.whl", hash = "sha256:8d1d7d63e5d2f4e92a39ae1e897a5d551720179bb8d1254883e7113d3826d43c"}, + {file = "SQLAlchemy-1.4.51-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eaeeb2464019765bc4340214fca1143081d49972864773f3f1e95dba5c7edc7d"}, + {file = "SQLAlchemy-1.4.51-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7deeae5071930abb3669b5185abb6c33ddfd2398f87660fafdb9e6a5fb0f3f2f"}, + {file = "SQLAlchemy-1.4.51-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0892e7ac8bc76da499ad3ee8de8da4d7905a3110b952e2a35a940dab1ffa550e"}, + {file = "SQLAlchemy-1.4.51-cp311-cp311-win32.whl", hash = "sha256:50e074aea505f4427151c286955ea025f51752fa42f9939749336672e0674c81"}, + {file = "SQLAlchemy-1.4.51-cp311-cp311-win_amd64.whl", hash = "sha256:3b0cd89a7bd03f57ae58263d0f828a072d1b440c8c2949f38f3b446148321171"}, + {file = "SQLAlchemy-1.4.51-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a33cb3f095e7d776ec76e79d92d83117438b6153510770fcd57b9c96f9ef623d"}, + {file = "SQLAlchemy-1.4.51-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cacc0b2dd7d22a918a9642fc89840a5d3cee18a0e1fe41080b1141b23b10916"}, + {file = "SQLAlchemy-1.4.51-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:245c67c88e63f1523e9216cad6ba3107dea2d3ee19adc359597a628afcabfbcb"}, + {file = "SQLAlchemy-1.4.51-cp312-cp312-win32.whl", hash = "sha256:8e702e7489f39375601c7ea5a0bef207256828a2bc5986c65cb15cd0cf097a87"}, + {file = "SQLAlchemy-1.4.51-cp312-cp312-win_amd64.whl", hash = "sha256:0525c4905b4b52d8ccc3c203c9d7ab2a80329ffa077d4bacf31aefda7604dc65"}, + {file = "SQLAlchemy-1.4.51-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:1980e6eb6c9be49ea8f89889989127daafc43f0b1b6843d71efab1514973cca0"}, + {file = "SQLAlchemy-1.4.51-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec7a0ed9b32afdf337172678a4a0e6419775ba4e649b66f49415615fa47efbd"}, + {file = "SQLAlchemy-1.4.51-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352df882088a55293f621328ec33b6ffca936ad7f23013b22520542e1ab6ad1b"}, + {file = "SQLAlchemy-1.4.51-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:86a22143a4001f53bf58027b044da1fb10d67b62a785fc1390b5c7f089d9838c"}, + {file = "SQLAlchemy-1.4.51-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c37bc677690fd33932182b85d37433845de612962ed080c3e4d92f758d1bd894"}, + {file = "SQLAlchemy-1.4.51-cp36-cp36m-win32.whl", hash = "sha256:d0a83afab5e062abffcdcbcc74f9d3ba37b2385294dd0927ad65fc6ebe04e054"}, + {file = "SQLAlchemy-1.4.51-cp36-cp36m-win_amd64.whl", hash = "sha256:a61184c7289146c8cff06b6b41807c6994c6d437278e72cf00ff7fe1c7a263d1"}, + {file = "SQLAlchemy-1.4.51-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:3f0ef620ecbab46e81035cf3dedfb412a7da35340500ba470f9ce43a1e6c423b"}, + {file = "SQLAlchemy-1.4.51-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c55040d8ea65414de7c47f1a23823cd9f3fad0dc93e6b6b728fee81230f817b"}, + {file = "SQLAlchemy-1.4.51-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ef80328e3fee2be0a1abe3fe9445d3a2e52a1282ba342d0dab6edf1fef4707"}, + {file = "SQLAlchemy-1.4.51-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f8cafa6f885a0ff5e39efa9325195217bb47d5929ab0051636610d24aef45ade"}, + {file = "SQLAlchemy-1.4.51-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8f2df79a46e130235bc5e1bbef4de0583fb19d481eaa0bffa76e8347ea45ec6"}, + {file = "SQLAlchemy-1.4.51-cp37-cp37m-win32.whl", hash = "sha256:f2e5b6f5cf7c18df66d082604a1d9c7a2d18f7d1dbe9514a2afaccbb51cc4fc3"}, + {file = "SQLAlchemy-1.4.51-cp37-cp37m-win_amd64.whl", hash = "sha256:5e180fff133d21a800c4f050733d59340f40d42364fcb9d14f6a67764bdc48d2"}, + {file = "SQLAlchemy-1.4.51-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7d8139ca0b9f93890ab899da678816518af74312bb8cd71fb721436a93a93298"}, + {file = "SQLAlchemy-1.4.51-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb18549b770351b54e1ab5da37d22bc530b8bfe2ee31e22b9ebe650640d2ef12"}, + {file = "SQLAlchemy-1.4.51-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55e699466106d09f028ab78d3c2e1f621b5ef2c8694598242259e4515715da7c"}, + {file = "SQLAlchemy-1.4.51-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2ad16880ccd971ac8e570550fbdef1385e094b022d6fc85ef3ce7df400dddad3"}, + {file = "SQLAlchemy-1.4.51-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b97fd5bb6b7c1a64b7ac0632f7ce389b8ab362e7bd5f60654c2a418496be5d7f"}, + {file = "SQLAlchemy-1.4.51-cp38-cp38-win32.whl", hash = "sha256:cecb66492440ae8592797dd705a0cbaa6abe0555f4fa6c5f40b078bd2740fc6b"}, + {file = "SQLAlchemy-1.4.51-cp38-cp38-win_amd64.whl", hash = "sha256:39b02b645632c5fe46b8dd30755682f629ffbb62ff317ecc14c998c21b2896ff"}, + {file = "SQLAlchemy-1.4.51-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:b03850c290c765b87102959ea53299dc9addf76ca08a06ea98383348ae205c99"}, + {file = "SQLAlchemy-1.4.51-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e646b19f47d655261b22df9976e572f588185279970efba3d45c377127d35349"}, + {file = "SQLAlchemy-1.4.51-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3cf56cc36d42908495760b223ca9c2c0f9f0002b4eddc994b24db5fcb86a9e4"}, + {file = "SQLAlchemy-1.4.51-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0d661cff58c91726c601cc0ee626bf167b20cc4d7941c93c5f3ac28dc34ddbea"}, + {file = "SQLAlchemy-1.4.51-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3823dda635988e6744d4417e13f2e2b5fe76c4bf29dd67e95f98717e1b094cad"}, + {file = "SQLAlchemy-1.4.51-cp39-cp39-win32.whl", hash = "sha256:b00cf0471888823b7a9f722c6c41eb6985cf34f077edcf62695ac4bed6ec01ee"}, + {file = "SQLAlchemy-1.4.51-cp39-cp39-win_amd64.whl", hash = "sha256:a055ba17f4675aadcda3005df2e28a86feb731fdcc865e1f6b4f209ed1225cba"}, + {file = "SQLAlchemy-1.4.51.tar.gz", hash = "sha256:e7908c2025eb18394e32d65dd02d2e37e17d733cdbe7d78231c2b6d7eb20cdb9"}, +] + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] +aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (!=0.4.17)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "greenlet (!=0.4.17)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"] +mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] +postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +pymysql = ["pymysql", "pymysql (<1)"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "sqlalchemy2-stubs" +version = "0.0.2a38" +description = "Typing Stubs for SQLAlchemy 1.4" +optional = false +python-versions = ">=3.6" +files = [ + {file = "sqlalchemy2-stubs-0.0.2a38.tar.gz", hash = "sha256:861d722abeb12f13eacd775a9f09379b11a5a9076f469ccd4099961b95800f9e"}, + {file = "sqlalchemy2_stubs-0.0.2a38-py3-none-any.whl", hash = "sha256:b62aa46943807287550e2033dafe07564b33b6a815fbaa3c144e396f9cc53bcb"}, +] + +[package.dependencies] +typing-extensions = ">=3.7.4" + +[[package]] +name = "sqlmodel" +version = "0.0.10" +description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "sqlmodel-0.0.10-py3-none-any.whl", hash = "sha256:10b3a312f66bed2b88a7b369cd06d1c0e89f62ad8e6303eefa1ea5b3e7b141f4"}, + {file = "sqlmodel-0.0.10.tar.gz", hash = "sha256:632f7f82d67f007161412e7c18279ba0f2b0ecacd5922a65aff89231ebc324ca"}, +] + +[package.dependencies] +pydantic = ">=1.9.0,<2.0.0" +SQLAlchemy = ">=1.4.36,<2.0.0" +sqlalchemy2-stubs = "*" + +[[package]] +name = "starlette" +version = "0.27.0" +description = "The little ASGI library that shines." +optional = false +python-versions = ">=3.7" +files = [ + {file = "starlette-0.27.0-py3-none-any.whl", hash = "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91"}, + {file = "starlette-0.27.0.tar.gz", hash = "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75"}, +] + +[package.dependencies] +anyio = ">=3.4.0,<5" + +[package.extras] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] + +[[package]] +name = "sympy" +version = "1.12" +description = "Computer algebra system (CAS) in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"}, + {file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"}, +] + +[package.dependencies] +mpmath = ">=0.19" + +[[package]] +name = "tenacity" +version = "8.2.3" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tenacity-8.2.3-py3-none-any.whl", hash = "sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c"}, + {file = "tenacity-8.2.3.tar.gz", hash = "sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a"}, +] + +[package.extras] +doc = ["reno", "sphinx", "tornado (>=4.5)"] + +[[package]] +name = "threadpoolctl" +version = "3.2.0" +description = "threadpoolctl" +optional = false +python-versions = ">=3.8" +files = [ + {file = "threadpoolctl-3.2.0-py3-none-any.whl", hash = "sha256:2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032"}, + {file = "threadpoolctl-3.2.0.tar.gz", hash = "sha256:c96a0ba3bdddeaca37dc4cc7344aafad41cdb8c313f74fdfe387a867bba93355"}, +] + +[[package]] +name = "tiktoken" +version = "0.5.2" +description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tiktoken-0.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8c4e654282ef05ec1bd06ead22141a9a1687991cef2c6a81bdd1284301abc71d"}, + {file = "tiktoken-0.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7b3134aa24319f42c27718c6967f3c1916a38a715a0fa73d33717ba121231307"}, + {file = "tiktoken-0.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6092e6e77730929c8c6a51bb0d7cfdf1b72b63c4d033d6258d1f2ee81052e9e5"}, + {file = "tiktoken-0.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72ad8ae2a747622efae75837abba59be6c15a8f31b4ac3c6156bc56ec7a8e631"}, + {file = "tiktoken-0.5.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:51cba7c8711afa0b885445f0637f0fcc366740798c40b981f08c5f984e02c9d1"}, + {file = "tiktoken-0.5.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3d8c7d2c9313f8e92e987d585ee2ba0f7c40a0de84f4805b093b634f792124f5"}, + {file = "tiktoken-0.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:692eca18c5fd8d1e0dde767f895c17686faaa102f37640e884eecb6854e7cca7"}, + {file = "tiktoken-0.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:138d173abbf1ec75863ad68ca289d4da30caa3245f3c8d4bfb274c4d629a2f77"}, + {file = "tiktoken-0.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7388fdd684690973fdc450b47dfd24d7f0cbe658f58a576169baef5ae4658607"}, + {file = "tiktoken-0.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a114391790113bcff670c70c24e166a841f7ea8f47ee2fe0e71e08b49d0bf2d4"}, + {file = "tiktoken-0.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca96f001e69f6859dd52926d950cfcc610480e920e576183497ab954e645e6ac"}, + {file = "tiktoken-0.5.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:15fed1dd88e30dfadcdd8e53a8927f04e1f6f81ad08a5ca824858a593ab476c7"}, + {file = "tiktoken-0.5.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:93f8e692db5756f7ea8cb0cfca34638316dcf0841fb8469de8ed7f6a015ba0b0"}, + {file = "tiktoken-0.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:bcae1c4c92df2ffc4fe9f475bf8148dbb0ee2404743168bbeb9dcc4b79dc1fdd"}, + {file = "tiktoken-0.5.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b76a1e17d4eb4357d00f0622d9a48ffbb23401dcf36f9716d9bd9c8e79d421aa"}, + {file = "tiktoken-0.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01d8b171bb5df4035580bc26d4f5339a6fd58d06f069091899d4a798ea279d3e"}, + {file = "tiktoken-0.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42adf7d4fb1ed8de6e0ff2e794a6a15005f056a0d83d22d1d6755a39bffd9e7f"}, + {file = "tiktoken-0.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3f894dbe0adb44609f3d532b8ea10820d61fdcb288b325a458dfc60fefb7db"}, + {file = "tiktoken-0.5.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:58ccfddb4e62f0df974e8f7e34a667981d9bb553a811256e617731bf1d007d19"}, + {file = "tiktoken-0.5.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58902a8bad2de4268c2a701f1c844d22bfa3cbcc485b10e8e3e28a050179330b"}, + {file = "tiktoken-0.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:5e39257826d0647fcac403d8fa0a474b30d02ec8ffc012cfaf13083e9b5e82c5"}, + {file = "tiktoken-0.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bde3b0fbf09a23072d39c1ede0e0821f759b4fa254a5f00078909158e90ae1f"}, + {file = "tiktoken-0.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2ddee082dcf1231ccf3a591d234935e6acf3e82ee28521fe99af9630bc8d2a60"}, + {file = "tiktoken-0.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35c057a6a4e777b5966a7540481a75a31429fc1cb4c9da87b71c8b75b5143037"}, + {file = "tiktoken-0.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c4a049b87e28f1dc60509f8eb7790bc8d11f9a70d99b9dd18dfdd81a084ffe6"}, + {file = "tiktoken-0.5.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5bf5ce759089f4f6521ea6ed89d8f988f7b396e9f4afb503b945f5c949c6bec2"}, + {file = "tiktoken-0.5.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0c964f554af1a96884e01188f480dad3fc224c4bbcf7af75d4b74c4b74ae0125"}, + {file = "tiktoken-0.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:368dd5726d2e8788e47ea04f32e20f72a2012a8a67af5b0b003d1e059f1d30a3"}, + {file = "tiktoken-0.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a2deef9115b8cd55536c0a02c0203512f8deb2447f41585e6d929a0b878a0dd2"}, + {file = "tiktoken-0.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2ed7d380195affbf886e2f8b92b14edfe13f4768ff5fc8de315adba5b773815e"}, + {file = "tiktoken-0.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c76fce01309c8140ffe15eb34ded2bb94789614b7d1d09e206838fc173776a18"}, + {file = "tiktoken-0.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60a5654d6a2e2d152637dd9a880b4482267dfc8a86ccf3ab1cec31a8c76bfae8"}, + {file = "tiktoken-0.5.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:41d4d3228e051b779245a8ddd21d4336f8975563e92375662f42d05a19bdff41"}, + {file = "tiktoken-0.5.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c1cdec2c92fcde8c17a50814b525ae6a88e8e5b02030dc120b76e11db93f13"}, + {file = "tiktoken-0.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:84ddb36faedb448a50b246e13d1b6ee3437f60b7169b723a4b2abad75e914f3e"}, + {file = "tiktoken-0.5.2.tar.gz", hash = "sha256:f54c581f134a8ea96ce2023ab221d4d4d81ab614efa0b2fbce926387deb56c80"}, +] + +[package.dependencies] +regex = ">=2022.1.18" +requests = ">=2.26.0" + +[package.extras] +blobfile = ["blobfile (>=2)"] + +[[package]] +name = "tokenizers" +version = "0.15.0" +description = "" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tokenizers-0.15.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:cd3cd0299aaa312cd2988957598f80becd04d5a07338741eca076057a2b37d6e"}, + {file = "tokenizers-0.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a922c492c721744ee175f15b91704be2d305569d25f0547c77cd6c9f210f9dc"}, + {file = "tokenizers-0.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:331dd786d02fc38698f835fff61c99480f98b73ce75a4c65bd110c9af5e4609a"}, + {file = "tokenizers-0.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88dd0961c437d413ab027f8b115350c121d49902cfbadf08bb8f634b15fa1814"}, + {file = "tokenizers-0.15.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6fdcc55339df7761cd52e1fbe8185d3b3963bc9e3f3545faa6c84f9e8818259a"}, + {file = "tokenizers-0.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1480b0051d8ab5408e8e4db2dc832f7082ea24aa0722c427bde2418c6f3bd07"}, + {file = "tokenizers-0.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9855e6c258918f9cf62792d4f6ddfa6c56dccd8c8118640f867f6393ecaf8bd7"}, + {file = "tokenizers-0.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de9529fe75efcd54ba8d516aa725e1851df9199f0669b665c55e90df08f5af86"}, + {file = "tokenizers-0.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8edcc90a36eab0705fe9121d6c77c6e42eeef25c7399864fd57dfb27173060bf"}, + {file = "tokenizers-0.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ae17884aafb3e94f34fb7cfedc29054f5f54e142475ebf8a265a4e388fee3f8b"}, + {file = "tokenizers-0.15.0-cp310-none-win32.whl", hash = "sha256:9a3241acdc9b44cff6e95c4a55b9be943ef3658f8edb3686034d353734adba05"}, + {file = "tokenizers-0.15.0-cp310-none-win_amd64.whl", hash = "sha256:4b31807cb393d6ea31926b307911c89a1209d5e27629aa79553d1599c8ffdefe"}, + {file = "tokenizers-0.15.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:af7e9be8c05d30bb137b9fd20f9d99354816599e5fd3d58a4b1e28ba3b36171f"}, + {file = "tokenizers-0.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c3d7343fa562ea29661783344a2d83662db0d3d17a6fa6a403cac8e512d2d9fd"}, + {file = "tokenizers-0.15.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:32371008788aeeb0309a9244809a23e4c0259625e6b74a103700f6421373f395"}, + {file = "tokenizers-0.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca9db64c7c9954fbae698884c5bb089764edc549731e5f9b7fa1dd4e4d78d77f"}, + {file = "tokenizers-0.15.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbed5944c31195514669cf6381a0d8d47f164943000d10f93d6d02f0d45c25e0"}, + {file = "tokenizers-0.15.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aab16c4a26d351d63e965b0c792f5da7227a37b69a6dc6d922ff70aa595b1b0c"}, + {file = "tokenizers-0.15.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c2b60b12fdd310bf85ce5d7d3f823456b9b65eed30f5438dd7761879c495983"}, + {file = "tokenizers-0.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0344d6602740e44054a9e5bbe9775a5e149c4dddaff15959bb07dcce95a5a859"}, + {file = "tokenizers-0.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4525f6997d81d9b6d9140088f4f5131f6627e4c960c2c87d0695ae7304233fc3"}, + {file = "tokenizers-0.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:65975094fef8cc68919644936764efd2ce98cf1bacbe8db2687155d2b0625bee"}, + {file = "tokenizers-0.15.0-cp311-none-win32.whl", hash = "sha256:ff5d2159c5d93015f5a4542aac6c315506df31853123aa39042672031768c301"}, + {file = "tokenizers-0.15.0-cp311-none-win_amd64.whl", hash = "sha256:2dd681b53cf615e60a31a115a3fda3980e543d25ca183797f797a6c3600788a3"}, + {file = "tokenizers-0.15.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:c9cce6ee149a3d703f86877bc2a6d997e34874b2d5a2d7839e36b2273f31d3d9"}, + {file = "tokenizers-0.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a0a94bc3370e6f1cc8a07a8ae867ce13b7c1b4291432a773931a61f256d44ea"}, + {file = "tokenizers-0.15.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:309cfcccfc7e502cb1f1de2c9c1c94680082a65bfd3a912d5a5b2c90c677eb60"}, + {file = "tokenizers-0.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8413e994dd7d875ab13009127fc85633916c71213917daf64962bafd488f15dc"}, + {file = "tokenizers-0.15.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d0ebf9430f901dbdc3dcb06b493ff24a3644c9f88c08e6a1d6d0ae2228b9b818"}, + {file = "tokenizers-0.15.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10361e9c7864b22dd791ec5126327f6c9292fb1d23481d4895780688d5e298ac"}, + {file = "tokenizers-0.15.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:babe42635b8a604c594bdc56d205755f73414fce17ba8479d142a963a6c25cbc"}, + {file = "tokenizers-0.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3768829861e964c7a4556f5f23307fce6a23872c2ebf030eb9822dbbbf7e9b2a"}, + {file = "tokenizers-0.15.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9c91588a630adc88065e1c03ac6831e3e2112558869b9ebcb2b8afd8a14c944d"}, + {file = "tokenizers-0.15.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:77606994e793ca54ecf3a3619adc8a906a28ca223d9354b38df41cb8766a0ed6"}, + {file = "tokenizers-0.15.0-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:6fe143939f3b596681922b2df12a591a5b010e7dcfbee2202482cd0c1c2f2459"}, + {file = "tokenizers-0.15.0-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:b7bee0f1795e3e3561e9a557061b1539e5255b8221e3f928f58100282407e090"}, + {file = "tokenizers-0.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5d37e7f4439b4c46192ab4f2ff38ab815e4420f153caa13dec9272ef14403d34"}, + {file = "tokenizers-0.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caadf255cf7f951b38d10097836d1f3bcff4aeaaffadfdf748bab780bf5bff95"}, + {file = "tokenizers-0.15.0-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:05accb9162bf711a941b1460b743d62fec61c160daf25e53c5eea52c74d77814"}, + {file = "tokenizers-0.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26a2ef890740127cb115ee5260878f4a677e36a12831795fd7e85887c53b430b"}, + {file = "tokenizers-0.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e54c5f26df14913620046b33e822cb3bcd091a332a55230c0e63cc77135e2169"}, + {file = "tokenizers-0.15.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:669b8ed653a578bcff919566631156f5da3aab84c66f3c0b11a6281e8b4731c7"}, + {file = "tokenizers-0.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0ea480d943297df26f06f508dab6e012b07f42bf3dffdd36e70799368a5f5229"}, + {file = "tokenizers-0.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc80a0a565ebfc7cd89de7dd581da8c2b3238addfca6280572d27d763f135f2f"}, + {file = "tokenizers-0.15.0-cp37-none-win32.whl", hash = "sha256:cdd945e678bbdf4517d5d8de66578a5030aeefecdb46f5320b034de9cad8d4dd"}, + {file = "tokenizers-0.15.0-cp37-none-win_amd64.whl", hash = "sha256:1ab96ab7dc706e002c32b2ea211a94c1c04b4f4de48354728c3a6e22401af322"}, + {file = "tokenizers-0.15.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:f21c9eb71c9a671e2a42f18b456a3d118e50c7f0fc4dd9fa8f4eb727fea529bf"}, + {file = "tokenizers-0.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a5f4543a35889679fc3052086e69e81880b2a5a28ff2a52c5a604be94b77a3f"}, + {file = "tokenizers-0.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f8aa81afec893e952bd39692b2d9ef60575ed8c86fce1fd876a06d2e73e82dca"}, + {file = "tokenizers-0.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1574a5a4af22c3def93fe8fe4adcc90a39bf5797ed01686a4c46d1c3bc677d2f"}, + {file = "tokenizers-0.15.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c7982fd0ec9e9122d03b209dac48cebfea3de0479335100ef379a9a959b9a5a"}, + {file = "tokenizers-0.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d16b647032df2ce2c1f9097236e046ea9fedd969b25637b9d5d734d78aa53b"}, + {file = "tokenizers-0.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b3cdf29e6f9653da330515dc8fa414be5a93aae79e57f8acc50d4028dd843edf"}, + {file = "tokenizers-0.15.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7286f3df10de840867372e3e64b99ef58c677210e3ceb653cd0e740a5c53fe78"}, + {file = "tokenizers-0.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aabc83028baa5a36ce7a94e7659250f0309c47fa4a639e5c2c38e6d5ea0de564"}, + {file = "tokenizers-0.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:72f78b0e0e276b1fc14a672fa73f3acca034ba8db4e782124a2996734a9ba9cf"}, + {file = "tokenizers-0.15.0-cp38-none-win32.whl", hash = "sha256:9680b0ecc26e7e42f16680c1aa62e924d58d1c2dd992707081cc10a374896ea2"}, + {file = "tokenizers-0.15.0-cp38-none-win_amd64.whl", hash = "sha256:f17cbd88dab695911cbdd385a5a7e3709cc61dff982351f5d1b5939f074a2466"}, + {file = "tokenizers-0.15.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:3661862df7382c5eb23ac4fbf7c75e69b02dc4f5784e4c5a734db406b5b24596"}, + {file = "tokenizers-0.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3045d191dad49647f5a5039738ecf1c77087945c7a295f7bcf051c37067e883"}, + {file = "tokenizers-0.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9fcaad9ab0801f14457d7c820d9f246b5ab590c407fc6b073819b1573097aa7"}, + {file = "tokenizers-0.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a79f17027f24fe9485701c8dbb269b9c713954ec3bdc1e7075a66086c0c0cd3c"}, + {file = "tokenizers-0.15.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:01a3aa332abc4bee7640563949fcfedca4de8f52691b3b70f2fc6ca71bfc0f4e"}, + {file = "tokenizers-0.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05b83896a893cdfedad8785250daa3ba9f0504848323471524d4783d7291661e"}, + {file = "tokenizers-0.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbbf2489fcf25d809731ba2744ff278dd07d9eb3f8b7482726bd6cae607073a4"}, + {file = "tokenizers-0.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab806ad521a5e9de38078b7add97589c313915f6f5fec6b2f9f289d14d607bd6"}, + {file = "tokenizers-0.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4a522612d5c88a41563e3463226af64e2fa00629f65cdcc501d1995dd25d23f5"}, + {file = "tokenizers-0.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e58a38c4e6075810bdfb861d9c005236a72a152ebc7005941cc90d1bbf16aca9"}, + {file = "tokenizers-0.15.0-cp39-none-win32.whl", hash = "sha256:b8034f1041fd2bd2b84ff9f4dc4ae2e1c3b71606820a9cd5c562ebd291a396d1"}, + {file = "tokenizers-0.15.0-cp39-none-win_amd64.whl", hash = "sha256:edde9aa964145d528d0e0dbf14f244b8a85ebf276fb76869bc02e2530fa37a96"}, + {file = "tokenizers-0.15.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:309445d10d442b7521b98083dc9f0b5df14eca69dbbfebeb98d781ee2cef5d30"}, + {file = "tokenizers-0.15.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d3125a6499226d4d48efc54f7498886b94c418e93a205b673bc59364eecf0804"}, + {file = "tokenizers-0.15.0-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ed56ddf0d54877bb9c6d885177db79b41576e61b5ef6defeb579dcb803c04ad5"}, + {file = "tokenizers-0.15.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b22cd714706cc5b18992a232b023f736e539495f5cc61d2d28d176e55046f6c"}, + {file = "tokenizers-0.15.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac2719b1e9bc8e8e7f6599b99d0a8e24f33d023eb8ef644c0366a596f0aa926"}, + {file = "tokenizers-0.15.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:85ddae17570ec7e5bfaf51ffa78d044f444a8693e1316e1087ee6150596897ee"}, + {file = "tokenizers-0.15.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:76f1bed992e396bf6f83e3df97b64ff47885e45e8365f8983afed8556a0bc51f"}, + {file = "tokenizers-0.15.0-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:3bb0f4df6dce41a1c7482087b60d18c372ef4463cb99aa8195100fcd41e0fd64"}, + {file = "tokenizers-0.15.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:22c27672c27a059a5f39ff4e49feed8c7f2e1525577c8a7e3978bd428eb5869d"}, + {file = "tokenizers-0.15.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78104f5d035c9991f92831fc0efe9e64a05d4032194f2a69f67aaa05a4d75bbb"}, + {file = "tokenizers-0.15.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a40b73dc19d82c3e3ffb40abdaacca8fbc95eeb26c66b7f9f860aebc07a73998"}, + {file = "tokenizers-0.15.0-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d801d1368188c74552cd779b1286e67cb9fd96f4c57a9f9a2a09b6def9e1ab37"}, + {file = "tokenizers-0.15.0-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82641ffb13a4da1293fcc9f437d457647e60ed0385a9216cd135953778b3f0a1"}, + {file = "tokenizers-0.15.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:160f9d1810f2c18fffa94aa98bf17632f6bd2dabc67fcb01a698ca80c37d52ee"}, + {file = "tokenizers-0.15.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d7d6eea831ed435fdeeb9bcd26476226401d7309d115a710c65da4088841948"}, + {file = "tokenizers-0.15.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f6456bec6c557d63d8ec0023758c32f589e1889ed03c055702e84ce275488bed"}, + {file = "tokenizers-0.15.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eef39a502fad3bf104b9e1906b4fb0cee20e44e755e51df9a98f8922c3bf6d4"}, + {file = "tokenizers-0.15.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1e4664c5b797e093c19b794bbecc19d2367e782b4a577d8b7c1821db5dc150d"}, + {file = "tokenizers-0.15.0-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ca003fb5f3995ff5cf676db6681b8ea5d54d3b30bea36af1120e78ee1a4a4cdf"}, + {file = "tokenizers-0.15.0-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7f17363141eb0c53752c89e10650b85ef059a52765d0802ba9613dbd2d21d425"}, + {file = "tokenizers-0.15.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:8a765db05581c7d7e1280170f2888cda351760d196cc059c37ea96f121125799"}, + {file = "tokenizers-0.15.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:2a0dd641a72604486cd7302dd8f87a12c8a9b45e1755e47d2682733f097c1af5"}, + {file = "tokenizers-0.15.0-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a1a3c973e4dc97797fc19e9f11546c95278ffc55c4492acb742f69e035490bc"}, + {file = "tokenizers-0.15.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4fab75642aae4e604e729d6f78e0addb9d7e7d49e28c8f4d16b24da278e5263"}, + {file = "tokenizers-0.15.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65f80be77f6327a86d8fd35a4467adcfe6174c159b4ab52a1a8dd4c6f2d7d9e1"}, + {file = "tokenizers-0.15.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a8da7533dbe66b88afd430c56a2f2ce1fd82e2681868f857da38eeb3191d7498"}, + {file = "tokenizers-0.15.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa8eb4584fc6cbe6a84d7a7864be3ed28e23e9fd2146aa8ef1814d579df91958"}, + {file = "tokenizers-0.15.0.tar.gz", hash = "sha256:10c7e6e7b4cabd757da59e93f5f8d1126291d16f8b54f28510825ef56a3e5d0e"}, +] + +[package.dependencies] +huggingface_hub = ">=0.16.4,<1.0" + +[package.extras] +dev = ["tokenizers[testing]"] +docs = ["setuptools_rust", "sphinx", "sphinx_rtd_theme"] +testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests"] + +[[package]] +name = "torch" +version = "2.1.2" +description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "torch-2.1.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:3a871edd6c02dae77ad810335c0833391c1a4ce49af21ea8cf0f6a5d2096eea8"}, + {file = "torch-2.1.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:bef6996c27d8f6e92ea4e13a772d89611da0e103b48790de78131e308cf73076"}, + {file = "torch-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:0e13034fd5fb323cbbc29e56d0637a3791e50dd589616f40c79adfa36a5a35a1"}, + {file = "torch-2.1.2-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:d9b535cad0df3d13997dbe8bd68ac33e0e3ae5377639c9881948e40794a61403"}, + {file = "torch-2.1.2-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:f9a55d55af02826ebfbadf4e9b682f0f27766bc33df8236b48d28d705587868f"}, + {file = "torch-2.1.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:a6ebbe517097ef289cc7952783588c72de071d4b15ce0f8b285093f0916b1162"}, + {file = "torch-2.1.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:8f32ce591616a30304f37a7d5ea80b69ca9e1b94bba7f308184bf616fdaea155"}, + {file = "torch-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e0ee6cf90c8970e05760f898d58f9ac65821c37ffe8b04269ec787aa70962b69"}, + {file = "torch-2.1.2-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:76d37967c31c99548ad2c4d3f2cf191db48476f2e69b35a0937137116da356a1"}, + {file = "torch-2.1.2-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:e2d83f07b4aac983453ea5bf8f9aa9dacf2278a8d31247f5d9037f37befc60e4"}, + {file = "torch-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:f41fe0c7ecbf903a568c73486139a75cfab287a0f6c17ed0698fdea7a1e8641d"}, + {file = "torch-2.1.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e3225f47d50bb66f756fe9196a768055d1c26b02154eb1f770ce47a2578d3aa7"}, + {file = "torch-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33d59cd03cb60106857f6c26b36457793637512998666ee3ce17311f217afe2b"}, + {file = "torch-2.1.2-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:8e221deccd0def6c2badff6be403e0c53491805ed9915e2c029adbcdb87ab6b5"}, + {file = "torch-2.1.2-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:05b18594f60a911a0c4f023f38a8bda77131fba5fd741bda626e97dcf5a3dd0a"}, + {file = "torch-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:9ca96253b761e9aaf8e06fb30a66ee301aecbf15bb5a303097de1969077620b6"}, + {file = "torch-2.1.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d93ba70f67b08c2ae5598ee711cbc546a1bc8102cef938904b8c85c2089a51a0"}, + {file = "torch-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:255b50bc0608db177e6a3cc118961d77de7e5105f07816585fa6f191f33a9ff3"}, + {file = "torch-2.1.2-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:6984cd5057c0c977b3c9757254e989d3f1124f4ce9d07caa6cb637783c71d42a"}, + {file = "torch-2.1.2-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:bc195d7927feabc0eb7c110e457c955ed2ab616f3c7c28439dd4188cf589699f"}, +] + +[package.dependencies] +filelock = "*" +fsspec = "*" +jinja2 = "*" +networkx = "*" +nvidia-cublas-cu12 = {version = "12.1.3.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-cupti-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-nvrtc-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-runtime-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cudnn-cu12 = {version = "8.9.2.26", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cufft-cu12 = {version = "11.0.2.54", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-curand-cu12 = {version = "10.3.2.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cusolver-cu12 = {version = "11.4.5.107", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cusparse-cu12 = {version = "12.1.0.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-nccl-cu12 = {version = "2.18.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-nvtx-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +sympy = "*" +triton = {version = "2.1.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +typing-extensions = "*" + +[package.extras] +dynamo = ["jinja2"] +opt-einsum = ["opt-einsum (>=3.3)"] + +[[package]] +name = "torchvision" +version = "0.16.2" +description = "image and video datasets and models for torch deep learning" +optional = false +python-versions = ">=3.8" +files = [ + {file = "torchvision-0.16.2-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:bc86f2800cb2c0c1a09c581409cdd6bff66e62f103dc83fc63f73346264c3756"}, + {file = "torchvision-0.16.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b024bd412df6d3a007dcebf311a894eb3c5c21e1af80d12be382bbcb097a7c3a"}, + {file = "torchvision-0.16.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:e89f10f3c8351972b6e3fda95bc3e479ea8dbfc9dfcfd2c32902dbad4ba5cfc5"}, + {file = "torchvision-0.16.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:96c7583700112a410bdc4e1e4f118c429dab49c29c9a31a2cc3579bc9b08b19d"}, + {file = "torchvision-0.16.2-cp310-cp310-win_amd64.whl", hash = "sha256:9f4032ebb3277fb07ff6a9b818d50a547fb8fcd89d958cfd9e773322454bb688"}, + {file = "torchvision-0.16.2-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:67b1aaf8b8cb02ce75dd445f291a27c8036a502f8c0aa76e28c37a0faac2e153"}, + {file = "torchvision-0.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bef30d03e1d1c629761f4dca51d3b7d8a0dc0acce6f4068ab2a1634e8e7b64e0"}, + {file = "torchvision-0.16.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:e59cc7b2bd1ab5c0ce4ae382e4e37be8f1c174e8b5de2f6a23c170de9ae28495"}, + {file = "torchvision-0.16.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:e130b08cc9b3cc73a6c59d6edf032394a322f9579bfd21d14bc2e1d0999aa758"}, + {file = "torchvision-0.16.2-cp311-cp311-win_amd64.whl", hash = "sha256:8692ab1e48807e9604046a6f4beeb67b523294cee1b00828654bb0df2cfce2b2"}, + {file = "torchvision-0.16.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:b82732dcf876a37c852772342aa6ee3480c03bb3e2a802ae109fc5f7e28d26e9"}, + {file = "torchvision-0.16.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4b065143d1a720fe8a9077fd4be35d491f98819ec80b3dbbc3ec64d0b707a906"}, + {file = "torchvision-0.16.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bc5f274e4ecd1b86062063cdf4fd385a1d39d147a3a2685fbbde9ff08bb720b8"}, + {file = "torchvision-0.16.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:335959c43b371c0474af34c1ef2a52efdc7603c45700d29e4475eeb02984170c"}, + {file = "torchvision-0.16.2-cp38-cp38-win_amd64.whl", hash = "sha256:7fd22d86e08eba321af70cad291020c2cdeac069b00ce88b923ca52e06174769"}, + {file = "torchvision-0.16.2-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:56115268b37f0b75364e3654e47ad9abc66ac34c1f9e5e3dfa89a22d6a40017a"}, + {file = "torchvision-0.16.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:82805f8445b094f9d1e770390ee6cc86855e89955e08ce34af2e2274fc0e5c45"}, + {file = "torchvision-0.16.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3f4bd5fcbc361476e2e78016636ac7d5509e59d9962521f06eb98e6803898182"}, + {file = "torchvision-0.16.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:8199acdf8ab066a28b84a5b6f4d97b58976d9e164b1acc3a9d14fccfaf74bb3a"}, + {file = "torchvision-0.16.2-cp39-cp39-win_amd64.whl", hash = "sha256:41dd4fa9f176d563fe9f1b9adef3b7e582cdfb60ce8c9bc51b094a025be687c9"}, +] + +[package.dependencies] +numpy = "*" +pillow = ">=5.3.0,<8.3.dev0 || >=8.4.dev0" +requests = "*" +torch = "2.1.2" + +[package.extras] +scipy = ["scipy"] + +[[package]] +name = "tqdm" +version = "4.66.1" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.1-py3-none-any.whl", hash = "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386"}, + {file = "tqdm-4.66.1.tar.gz", hash = "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "transformers" +version = "4.36.2" +description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "transformers-4.36.2-py3-none-any.whl", hash = "sha256:462066c4f74ee52516f12890dcc9ec71d1a5e97998db621668455117a54330f6"}, + {file = "transformers-4.36.2.tar.gz", hash = "sha256:d8068e897e47793281501e547d2bbdfc5b8556409c2cb6c3d9e2ca77d4c0b4ec"}, +] + +[package.dependencies] +filelock = "*" +huggingface-hub = ">=0.19.3,<1.0" +numpy = ">=1.17" +packaging = ">=20.0" +pyyaml = ">=5.1" +regex = "!=2019.12.17" +requests = "*" +safetensors = ">=0.3.1" +tokenizers = ">=0.14,<0.19" +tqdm = ">=4.27" + +[package.extras] +accelerate = ["accelerate (>=0.21.0)"] +agents = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch (>=1.10,!=1.12.0)"] +all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "torchaudio", "torchvision"] +audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] +codecarbon = ["codecarbon (==1.2.0)"] +deepspeed = ["accelerate (>=0.21.0)", "deepspeed (>=0.9.3)"] +deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.21.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"] +dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.14,<0.19)", "urllib3 (<2.0.0)"] +dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +docs = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "torchaudio", "torchvision"] +docs-specific = ["hf-doc-builder"] +flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"] +flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] +ftfy = ["ftfy"] +integrations = ["optuna", "ray[tune] (>=2.7.0)", "sigopt"] +ja = ["fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "rhoknp (>=1.1.0,<1.3.1)", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)"] +modelcreation = ["cookiecutter (==1.7.3)"] +natten = ["natten (>=0.14.6)"] +onnx = ["onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "tf2onnx"] +onnxruntime = ["onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)"] +optuna = ["optuna"] +quality = ["GitPython (<3.1.19)", "datasets (!=2.5.0)", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "ruff (==0.1.5)", "urllib3 (<2.0.0)"] +ray = ["ray[tune] (>=2.7.0)"] +retrieval = ["datasets (!=2.5.0)", "faiss-cpu"] +sagemaker = ["sagemaker (>=2.31.0)"] +sentencepiece = ["protobuf", "sentencepiece (>=0.1.91,!=0.1.92)"] +serving = ["fastapi", "pydantic (<2)", "starlette", "uvicorn"] +sigopt = ["sigopt"] +sklearn = ["scikit-learn"] +speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] +testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "tensorboard", "timeout-decorator"] +tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] +tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] +tf-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] +timm = ["timm"] +tokenizers = ["tokenizers (>=0.14,<0.19)"] +torch = ["accelerate (>=0.21.0)", "torch (>=1.10,!=1.12.0)"] +torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] +torch-vision = ["Pillow (>=10.0.1,<=15.0)", "torchvision"] +torchhub = ["filelock", "huggingface-hub (>=0.19.3,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "tqdm (>=4.27)"] +video = ["av (==9.2.0)", "decord (==0.6.0)"] +vision = ["Pillow (>=10.0.1,<=15.0)"] + +[[package]] +name = "triton" +version = "2.1.0" +description = "A language and compiler for custom Deep Learning operations" +optional = false +python-versions = "*" +files = [ + {file = "triton-2.1.0-0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:66439923a30d5d48399b08a9eae10370f6c261a5ec864a64983bae63152d39d7"}, + {file = "triton-2.1.0-0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:919b06453f0033ea52c13eaf7833de0e57db3178d23d4e04f9fc71c4f2c32bf8"}, + {file = "triton-2.1.0-0-cp37-cp37m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae4bb8a91de790e1866405211c4d618379781188f40d5c4c399766914e84cd94"}, + {file = "triton-2.1.0-0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39f6fb6bdccb3e98f3152e3fbea724f1aeae7d749412bbb1fa9c441d474eba26"}, + {file = "triton-2.1.0-0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21544e522c02005a626c8ad63d39bdff2f31d41069592919ef281e964ed26446"}, + {file = "triton-2.1.0-0-pp37-pypy37_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:143582ca31dd89cd982bd3bf53666bab1c7527d41e185f9e3d8a3051ce1b663b"}, + {file = "triton-2.1.0-0-pp38-pypy38_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82fc5aeeedf6e36be4e4530cbdcba81a09d65c18e02f52dc298696d45721f3bd"}, + {file = "triton-2.1.0-0-pp39-pypy39_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:81a96d110a738ff63339fc892ded095b31bd0d205e3aace262af8400d40b6fa8"}, +] + +[package.dependencies] +filelock = "*" + +[package.extras] +build = ["cmake (>=3.18)", "lit"] +tests = ["autopep8", "flake8", "isort", "numpy", "pytest", "scipy (>=1.7.1)"] +tutorials = ["matplotlib", "pandas", "tabulate"] + +[[package]] +name = "typer" +version = "0.9.0" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.6" +files = [ + {file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"}, + {file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"}, +] + +[package.dependencies] +click = ">=7.1.1,<9.0.0" +typing-extensions = ">=3.7.4.3" + +[package.extras] +all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] +dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] +doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] +test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] + +[[package]] +name = "typing-extensions" +version = "4.9.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, +] + +[[package]] +name = "typing-inspect" +version = "0.9.0" +description = "Runtime inspection utilities for typing module." +optional = false +python-versions = "*" +files = [ + {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, + {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, +] + +[package.dependencies] +mypy-extensions = ">=0.3.0" +typing-extensions = ">=3.7.4" + +[[package]] +name = "urllib3" +version = "2.0.7" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.7" +files = [ + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "uvicorn" +version = "0.23.2" +description = "The lightning-fast ASGI server." +optional = false +python-versions = ">=3.8" +files = [ + {file = "uvicorn-0.23.2-py3-none-any.whl", hash = "sha256:1f9be6558f01239d4fdf22ef8126c39cb1ad0addf76c40e760549d2c2f43ab53"}, + {file = "uvicorn-0.23.2.tar.gz", hash = "sha256:4d3cc12d7727ba72b64d12d3cc7743124074c0a69f7b201512fc50c3e3f1569a"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} +h11 = ">=0.8" +httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""} +python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} +uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} +watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} + +[package.extras] +standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] + +[[package]] +name = "uvloop" +version = "0.19.0" +description = "Fast implementation of asyncio event loop on top of libuv" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"}, + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"}, + {file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"}, +] + +[package.extras] +docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] + +[[package]] +name = "watchfiles" +version = "0.21.0" +description = "Simple, modern and high performance file watching and code reload in python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa"}, + {file = "watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d"}, + {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c"}, + {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9"}, + {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9"}, + {file = "watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293"}, + {file = "watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235"}, + {file = "watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7"}, + {file = "watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d"}, + {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7"}, + {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0"}, + {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365"}, + {file = "watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400"}, + {file = "watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe"}, + {file = "watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078"}, + {file = "watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a"}, + {file = "watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7"}, + {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c"}, + {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235"}, + {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7"}, + {file = "watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3"}, + {file = "watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094"}, + {file = "watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6"}, + {file = "watchfiles-0.21.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99"}, + {file = "watchfiles-0.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765"}, + {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562"}, + {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19"}, + {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0"}, + {file = "watchfiles-0.21.0-cp38-none-win32.whl", hash = "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214"}, + {file = "watchfiles-0.21.0-cp38-none-win_amd64.whl", hash = "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca"}, + {file = "watchfiles-0.21.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e"}, + {file = "watchfiles-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c"}, + {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28"}, + {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6"}, + {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49"}, + {file = "watchfiles-0.21.0-cp39-none-win32.whl", hash = "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94"}, + {file = "watchfiles-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c"}, + {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895"}, + {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85"}, + {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097"}, + {file = "watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3"}, +] + +[package.dependencies] +anyio = ">=3.0.0" + +[[package]] +name = "websocket-client" +version = "1.7.0" +description = "WebSocket client for Python with low level API options" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websocket-client-1.7.0.tar.gz", hash = "sha256:10e511ea3a8c744631d3bd77e61eb17ed09304c413ad42cf6ddfa4c7787e8fe6"}, + {file = "websocket_client-1.7.0-py3-none-any.whl", hash = "sha256:f4c3d22fec12a2461427a29957ff07d35098ee2d976d3ba244e688b8b4057588"}, +] + +[package.extras] +docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"] +optional = ["python-socks", "wsaccel"] +test = ["websockets"] + +[[package]] +name = "websockets" +version = "12.0" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, + {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, + {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, + {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, + {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, + {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, + {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, + {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, + {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, + {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, + {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, + {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, + {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, + {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, + {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, + {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, + {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, + {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, + {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, + {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, + {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, + {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, + {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, + {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, + {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, +] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[[package]] +name = "yarl" +version = "1.9.4" +description = "Yet another URL library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, + {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, + {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, + {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, + {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, + {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, + {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, +] + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" + +[[package]] +name = "zipp" +version = "3.17.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "05aa4db63c592f8c68e48c3f9aa71e7d376852faaaef9a95c0d0ae74d848bae0" diff --git a/apps/api/pyproject.toml b/apps/api/pyproject.toml index 227f374c..882b0940 100644 --- a/apps/api/pyproject.toml +++ b/apps/api/pyproject.toml @@ -1,3 +1,44 @@ [tool.ruff] # E501 line too long (82 > 79 characters) ignore = ["E501"] + +[tool.poetry] +name = "learnhouse-api" +version = "0.1.0" +description = "Learnhouse Backend" +authors = ["Badr B. (swve)"] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.11" +fastapi = "0.104.1" +pydantic = {version = ">=1.8.0,<2.0.0", extras = ["email"]} +sqlmodel = "0.0.10" +uvicorn = "0.23.2" +pymongo = "4.3.3" +motor = "3.1.1" +psycopg2 = "^2.9.9" +python-multipart = "^0.0.6" +boto3 = "^1.34.17" +botocore = "^1.34.17" +python-jose = "^3.3.0" +passlib = "^1.7.4" +fastapi-jwt-auth = "^0.5.0" +pytest = "^7.4.4" +httpx = "^0.26.0" +faker = "^22.2.0" +requests = "^2.31.0" +pyyaml = "^6.0.1" +sentry-sdk = {extras = ["fastapi"], version = "^1.39.2"} +langchain = "0.1.0" +tiktoken = "^0.5.2" +openai = "^1.7.1" +chromadb = "^0.4.22" +sentence-transformers = "^2.2.2" +python-dotenv = "^1.0.0" +redis = "^5.0.1" +langchain-community = "^0.0.11" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/apps/api/requirements.txt b/apps/api/requirements.txt index 5e21e2f0..bce51e62 100644 --- a/apps/api/requirements.txt +++ b/apps/api/requirements.txt @@ -18,7 +18,8 @@ requests pyyaml sentry-sdk[fastapi] pydantic[email]>=1.8.0,<2.0.0 -langchain +langchain==0.1.0 +langchain-community tiktoken openai chromadb From 982ba037f5857a59b41d06c06319c7c11ab28102 Mon Sep 17 00:00:00 2001 From: swve Date: Thu, 11 Jan 2024 23:57:20 +0100 Subject: [PATCH 11/18] fix: unused import --- apps/web/app/layout.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index e4dea8d8..d476f380 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,7 +1,6 @@ "use client"; import "../styles/globals.css"; import StyledComponentsRegistry from "../components/Utils/libs/styled-registry"; -import { GeistSans } from 'geist/font/sans'; import { motion } from "framer-motion"; From de93d569453a58e56c8822bdffdddd9af6a8a58f Mon Sep 17 00:00:00 2001 From: swve Date: Sat, 13 Jan 2024 15:25:04 +0100 Subject: [PATCH 12/18] feat: init organizationconfig --- apps/api/src/db/organization_config.py | 68 +++++++++++++++ apps/api/src/db/organization_settings.py | 21 ----- apps/api/src/db/organizations.py | 12 ++- apps/api/src/services/ai/ai.py | 1 - apps/api/src/services/ai/base.py | 9 +- apps/api/src/services/orgs/orgs.py | 104 +++++++++++++++++++++-- 6 files changed, 178 insertions(+), 37 deletions(-) create mode 100644 apps/api/src/db/organization_config.py delete mode 100644 apps/api/src/db/organization_settings.py diff --git a/apps/api/src/db/organization_config.py b/apps/api/src/db/organization_config.py new file mode 100644 index 00000000..3608666b --- /dev/null +++ b/apps/api/src/db/organization_config.py @@ -0,0 +1,68 @@ +from json import JSONEncoder +import json +from typing import Literal, Optional +from click import Option +from pydantic import BaseModel +from sqlalchemy import JSON, BigInteger, Column, ForeignKey +from sqlmodel import Field, SQLModel + + +# AI +class AILimitsSettings(BaseModel): + limits_enabled: bool = False + max_asks: int = 0 + + +class AIEnabledFeatures(BaseModel): + editor: bool = False + activity_ask: bool = False + course_ask: bool = False + global_ai_ask: bool = False + + +class AIConfig(BaseModel): + limits: AILimitsSettings = AILimitsSettings() + embeddings: Literal[ + "text-embedding-ada-002", "all-MiniLM-L6-v2" + ] = "all-MiniLM-L6-v2" + ai_model: Literal["gpt-3.5-turbo", "gpt-4-1106-preview"] = "gpt-3.5-turbo" + features: AIEnabledFeatures = AIEnabledFeatures() + + +class OrgUserConfig(BaseModel): + signup_mechanism: Literal["open", "inviteOnly"] = "open" + + +# Limits +class LimitSettings(BaseModel): + limits_enabled: bool = False + max_users: int = 0 + max_storage: int = 0 + max_staff: int = 0 + + +# General +class GeneralConfig(BaseModel): + color: str = "" + limits: LimitSettings = LimitSettings() + users: OrgUserConfig = OrgUserConfig() + active: bool = True + + +class OrganizationConfigBase(SQLModel): + GeneralConfig: GeneralConfig + AIConfig: AIConfig + +class OrganizationConfig(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + org_id: int = Field( + sa_column=Column(BigInteger, ForeignKey("organization.id", ondelete="CASCADE")) + ) + # TODO: fix this to use the correct type GeneralConfig + config: dict = Field(default={}, sa_column=Column(JSON)) + creation_date: Optional[str] + update_date: Optional[str] + + + + diff --git a/apps/api/src/db/organization_settings.py b/apps/api/src/db/organization_settings.py deleted file mode 100644 index babdef08..00000000 --- a/apps/api/src/db/organization_settings.py +++ /dev/null @@ -1,21 +0,0 @@ -from typing import Optional -from sqlalchemy import BigInteger, Column, ForeignKey -from sqlmodel import Field, SQLModel -from enum import Enum - - -class HeaderTypeEnum(str, Enum): - LOGO_MENU_SETTINGS = "LOGO_MENU_SETTINGS" - MENU_LOGO_SETTINGS = "MENU_LOGO_SETTINGS" - - -class OrganizationSettings(SQLModel, table=True): - id: Optional[int] = Field(default=None, primary_key=True) - org_id: int = Field( - sa_column=Column(BigInteger, ForeignKey("organization.id", ondelete="CASCADE")) - ) - logo_image: Optional[str] = "" - header_type: HeaderTypeEnum = HeaderTypeEnum.LOGO_MENU_SETTINGS - color: str = "" - creation_date: str - update_date: str diff --git a/apps/api/src/db/organizations.py b/apps/api/src/db/organizations.py index c16d3809..57b5bbf8 100644 --- a/apps/api/src/db/organizations.py +++ b/apps/api/src/db/organizations.py @@ -1,13 +1,14 @@ from typing import Optional from sqlmodel import Field, SQLModel +from src.db.organization_config import OrganizationConfig class OrganizationBase(SQLModel): name: str - description: Optional[str] + description: Optional[str] slug: str email: str - logo_image: Optional[str] + logo_image: Optional[str] class Organization(OrganizationBase, table=True): @@ -16,9 +17,11 @@ class Organization(OrganizationBase, table=True): creation_date: str = "" update_date: str = "" + class OrganizationUpdate(OrganizationBase): pass + class OrganizationCreate(OrganizationBase): pass @@ -26,5 +29,6 @@ class OrganizationCreate(OrganizationBase): class OrganizationRead(OrganizationBase): id: int org_uuid: str - creation_date: str - update_date: str + config: OrganizationConfig | dict + creation_date: str + update_date: str diff --git a/apps/api/src/services/ai/ai.py b/apps/api/src/services/ai/ai.py index e0e21e3e..3ad79a56 100644 --- a/apps/api/src/services/ai/ai.py +++ b/apps/api/src/services/ai/ai.py @@ -7,7 +7,6 @@ from src.core.events.database import get_db_session from src.db.users import PublicUser from src.db.activities import Activity, ActivityRead from src.security.auth import get_current_user -from langchain.memory.chat_message_histories import RedisChatMessageHistory from src.services.ai.base import ask_ai, get_chat_session_history from src.services.ai.schemas.ai import ( diff --git a/apps/api/src/services/ai/base.py b/apps/api/src/services/ai/base.py index f2356fa2..798f2c06 100644 --- a/apps/api/src/services/ai/base.py +++ b/apps/api/src/services/ai/base.py @@ -3,16 +3,15 @@ from uuid import uuid4 from langchain.agents import AgentExecutor from langchain.text_splitter import CharacterTextSplitter from langchain.embeddings.sentence_transformer import SentenceTransformerEmbeddings -from langchain.vectorstores import Chroma -from langchain_core.messages import BaseMessage +from langchain_community.vectorstores import Chroma from langchain.agents.openai_functions_agent.base import OpenAIFunctionsAgent from langchain.prompts import MessagesPlaceholder -from langchain.memory.chat_message_histories import RedisChatMessageHistory +from langchain_community.chat_message_histories import RedisChatMessageHistory from langchain_core.messages import SystemMessage from langchain.agents.openai_functions_agent.agent_token_buffer_memory import ( AgentTokenBufferMemory, ) -from langchain.chat_models import ChatOpenAI +from langchain_community.chat_models import ChatOpenAI from langchain.agents.agent_toolkits import ( create_retriever_tool, ) @@ -54,7 +53,7 @@ def ask_ai( ) tools = [tool] - llm = ChatOpenAI(temperature=0, api_key=openai_api_key) + llm = ChatOpenAI(temperature=0, api_key=openai_api_key, model_name="gpt-3.5-turbo") memory_key = "history" diff --git a/apps/api/src/services/orgs/orgs.py b/apps/api/src/services/orgs/orgs.py index b3735390..3b673dd5 100644 --- a/apps/api/src/services/orgs/orgs.py +++ b/apps/api/src/services/orgs/orgs.py @@ -1,7 +1,20 @@ +import json +import logging from datetime import datetime +from logging import config from typing import Literal from uuid import uuid4 from sqlmodel import Session, select +from src.db.organization_config import ( + AIConfig, + AIEnabledFeatures, + AILimitsSettings, + GeneralConfig, + LimitSettings, + OrgUserConfig, + OrganizationConfig, + OrganizationConfigBase, +) from src.security.rbac.rbac import ( authorization_verify_based_on_roles_and_authorship, authorization_verify_if_user_is_anon, @@ -23,7 +36,7 @@ async def get_organization( org_id: str, db_session: Session, current_user: PublicUser | AnonymousUser, -): +) -> OrganizationRead: statement = select(Organization).where(Organization.id == org_id) result = db_session.exec(statement) @@ -38,7 +51,18 @@ async def get_organization( # RBAC check await rbac_check(request, org.org_uuid, current_user, "read", db_session) - org = OrganizationRead.from_orm(org) + # Get org config + statement = select(OrganizationConfig).where(OrganizationConfig.org_id == org.id) + result = db_session.exec(statement) + + org_config = result.first() + + if org_config is None: + logging.error(f"Organization {org_id} has no config") + + config = OrganizationConfig.from_orm(org_config) if org_config else {} + + org = OrganizationRead(**org.dict(), config=config) return org @@ -48,7 +72,7 @@ async def get_organization_by_slug( org_slug: str, db_session: Session, current_user: PublicUser | AnonymousUser, -): +) -> OrganizationRead: statement = select(Organization).where(Organization.slug == org_slug) result = db_session.exec(statement) @@ -63,7 +87,18 @@ async def get_organization_by_slug( # RBAC check await rbac_check(request, org.org_uuid, current_user, "read", db_session) - org = OrganizationRead.from_orm(org) + # Get org config + statement = select(OrganizationConfig).where(OrganizationConfig.org_id == org.id) + result = db_session.exec(statement) + + org_config = result.first() + + if org_config is None: + logging.error(f"Organization {org_slug} has no config") + + config = OrganizationConfig.from_orm(org_config) if org_config else {} + + org = OrganizationRead(**org.dict(), config=config) return org @@ -87,7 +122,7 @@ async def create_org( org = Organization.from_orm(org_object) - if isinstance(current_user,AnonymousUser): + if isinstance(current_user, AnonymousUser): raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="You should be logged in to be able to achieve this action", @@ -115,7 +150,64 @@ async def create_org( db_session.commit() db_session.refresh(user_org) - return OrganizationRead.from_orm(org) + org_config = OrganizationConfigBase( + GeneralConfig=GeneralConfig( + color="#000000", + limits=LimitSettings( + limits_enabled=False, + max_users=0, + max_storage=0, + max_staff=0, + ), + users=OrgUserConfig( + signup_mechanism="open", + ), + active=True, + ), + AIConfig=AIConfig( + limits=AILimitsSettings( + limits_enabled=False, + max_asks=0, + ), + embeddings="all-MiniLM-L6-v2", + ai_model="gpt-3.5-turbo", + features=AIEnabledFeatures( + editor=False, + activity_ask=False, + course_ask=False, + global_ai_ask=False, + ), + ), + ) + + org_config = json.loads(org_config.json()) + + # OrgSettings + org_settings = OrganizationConfig( + org_id=int(org.id if org.id else 0), + config=org_config, + creation_date=str(datetime.now()), + update_date=str(datetime.now()), + ) + + db_session.add(org_settings) + db_session.commit() + db_session.refresh(org_settings) + + # Get org config + statement = select(OrganizationConfig).where(OrganizationConfig.org_id == org.id) + result = db_session.exec(statement) + + org_config = result.first() + + if org_config is None: + logging.error(f"Organization {org.id} has no config") + + config = OrganizationConfig.from_orm(org_config) + + org = OrganizationRead(**org.dict(), config=config) + + return org async def update_org( From 077c26ce15be9e696d7732f1e3967a972182d31a Mon Sep 17 00:00:00 2001 From: swve Date: Sun, 14 Jan 2024 11:58:09 +0100 Subject: [PATCH 13/18] feat: org wide ai features check --- .devcontainer/devcontainer.json | 9 +- apps/api/Dockerfile | 18 ++- apps/api/poetry.lock | 51 +++++--- apps/api/pyproject.toml | 2 + apps/api/requirements.txt | 1 + apps/api/src/db/organization_config.py | 4 +- apps/api/src/db/organizations.py | 2 +- apps/api/src/routers/orgs.py | 21 +++- apps/api/src/services/ai/ai.py | 101 ++++++++++++---- apps/api/src/services/ai/base.py | 25 +++- apps/api/src/services/ai/utils.py | 114 ++++++++++++++++++ .../block_types/imageBlock/imageBlock.py | 4 +- .../src/services/courses/activities/utils.py | 47 ++++---- apps/api/src/services/orgs/orgs.py | 82 +++++++++++++ .../activity/[activityid]/activity.tsx | 2 +- .../components/AI/Hooks/useGetAIFeatures.tsx | 39 ++++++ .../Contexts/AI/AIChatBotContext.tsx | 2 +- .../Contexts/AI/AIEditorContext.tsx | 2 +- .../Activities}/AI/AIActivityAsk.tsx | 48 +++++--- .../{Elements => AI}/AICanvaToolkit.tsx | 45 ++++--- .../Activities/DynamicCanva/DynamicCanva.tsx | 2 +- .../Objects/Editor/AI/AIEditorToolkit.tsx | 90 ++++++++------ apps/web/components/Objects/Editor/Editor.tsx | 17 ++- .../Objects/Editor/EditorWrapper.tsx | 8 +- 24 files changed, 573 insertions(+), 163 deletions(-) create mode 100644 apps/api/src/services/ai/utils.py create mode 100644 apps/web/components/AI/Hooks/useGetAIFeatures.tsx rename apps/web/components/{ => Objects/Activities}/AI/AIActivityAsk.tsx (90%) rename apps/web/components/Objects/Activities/DynamicCanva/{Elements => AI}/AICanvaToolkit.tsx (71%) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ff600b2a..29ab464b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -15,8 +15,13 @@ "esbenp.prettier-vscode", "ms-python.isort", "redhat.vscode-yaml" - ] + ], + "settings": { + "[python]": { + "editor.defaultFormatter": "ms-python.python" + } + } } }, "shutdownAction": "stopCompose" -} +} \ No newline at end of file diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index baad3124..d4ccca4c 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -7,13 +7,19 @@ RUN pip install poetry # WORKDIR /usr/learnhouse/apps/api -# -COPY ./requirements.txt /usr/learnhouse/requirements.txt +# Copy poetry.lock* in case it doesn't exist in the repo +COPY ./poetry.lock* /usr/learnhouse/ -# -RUN poetry config virtualenvs.create false \ - && pip install --upgrade pip \ - && pip install -r /usr/learnhouse/requirements.txt +# Copy project requirement files here to ensure they will be cached. +COPY pyproject.toml /usr/learnhouse/ + +# Install poetry +RUN pip install --upgrade pip \ + && pip install poetry \ + && poetry config virtualenvs.create false + +# Install project dependencies. +RUN poetry install --no-interaction --no-ansi # COPY ./ /usr/learnhouse diff --git a/apps/api/poetry.lock b/apps/api/poetry.lock index 6b19a34b..8a262db2 100644 --- a/apps/api/poetry.lock +++ b/apps/api/poetry.lock @@ -226,17 +226,17 @@ typecheck = ["mypy"] [[package]] name = "boto3" -version = "1.34.17" +version = "1.34.18" description = "The AWS SDK for Python" optional = false python-versions = ">= 3.8" files = [ - {file = "boto3-1.34.17-py3-none-any.whl", hash = "sha256:1efc02be786884034d503d59c018cf7650d0cff9fcb37cd2eb49b802a6fe6111"}, - {file = "boto3-1.34.17.tar.gz", hash = "sha256:8ca248cc84e7e859e4e276eb9c4309fa01a3e58473bf48d6c33448be870c2bb8"}, + {file = "boto3-1.34.18-py3-none-any.whl", hash = "sha256:ae7cfdf45f4dfd33bd3e84e36afcfbf0517e64a32e647989a068f34d053572b8"}, + {file = "boto3-1.34.18.tar.gz", hash = "sha256:5e38ca63007e903a7efe0a1751a0374d287b50d7bc148b9d3d495cdf74a0b712"}, ] [package.dependencies] -botocore = ">=1.34.17,<1.35.0" +botocore = ">=1.34.18,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -245,13 +245,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.17" +version = "1.34.18" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">= 3.8" files = [ - {file = "botocore-1.34.17-py3-none-any.whl", hash = "sha256:7272c39032c6f1d62781e4c8445d9a1d9140c2bf52ba7ee66bf6db559c4b2427"}, - {file = "botocore-1.34.17.tar.gz", hash = "sha256:e48a662f3a6919219276b55085e8f73c3347966675f55e9d448be30cf79678ee"}, + {file = "botocore-1.34.18-py3-none-any.whl", hash = "sha256:2067d8385c11b7cf2d336227d8fa5aea632fe61afbadb3168dc169dcc13d8c3e"}, + {file = "botocore-1.34.18.tar.gz", hash = "sha256:85a77e72560a45b0dfdad94f92f5e114c82be07a51bb2d19dd310dab8be158cf"}, ] [package.dependencies] @@ -1362,13 +1362,13 @@ extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15. [[package]] name = "langchain-core" -version = "0.1.9" +version = "0.1.10" description = "Building applications with LLMs through composability" optional = false python-versions = ">=3.8.1,<4.0" files = [ - {file = "langchain_core-0.1.9-py3-none-any.whl", hash = "sha256:1dd45aec185ce3afb1c19fb2e88cdbc19fafa7ae929d8107799a7c82ef69ea9f"}, - {file = "langchain_core-0.1.9.tar.gz", hash = "sha256:4b51fdbdbc06027c26ea89a6da809cae2e404c9daa95dc6c10e3eae383d8ea6a"}, + {file = "langchain_core-0.1.10-py3-none-any.whl", hash = "sha256:d89952f6d0766cfc88d9f1e25b84d56f8d7bd63a45ad8ec1a9a038c9b49df16d"}, + {file = "langchain_core-0.1.10.tar.gz", hash = "sha256:3c9e1383264c102fcc6f865700dbb9416c4931a25d0ac2195f6311c6b867aa17"}, ] [package.dependencies] @@ -1384,15 +1384,32 @@ tenacity = ">=8.1.0,<9.0.0" [package.extras] extended-testing = ["jinja2 (>=3,<4)"] +[[package]] +name = "langchain-openai" +version = "0.0.2.post1" +description = "An integration package connecting OpenAI and LangChain" +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain_openai-0.0.2.post1-py3-none-any.whl", hash = "sha256:ba468b94c23da9d8ccefe5d5a3c1c65b4b9702292523e53acc689a9110022e26"}, + {file = "langchain_openai-0.0.2.post1.tar.gz", hash = "sha256:f8e78db4a663feeac71d9f036b9422406c199ea3ef4c97d99ff392c93530e073"}, +] + +[package.dependencies] +langchain-core = ">=0.1.7,<0.2" +numpy = ">=1,<2" +openai = ">=1.6.1,<2.0.0" +tiktoken = ">=0.5.2,<0.6.0" + [[package]] name = "langsmith" -version = "0.0.79" +version = "0.0.80" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = ">=3.8.1,<4.0" files = [ - {file = "langsmith-0.0.79-py3-none-any.whl", hash = "sha256:be0374e913c36d9f6a13dd6b6e20a506066d5a0f3abfd476f9cf9e0b086ed744"}, - {file = "langsmith-0.0.79.tar.gz", hash = "sha256:d32639ccd18a92533b302f6f482255619afc8eb007fff91e37ee699d947c5e29"}, + {file = "langsmith-0.0.80-py3-none-any.whl", hash = "sha256:dee1c6ef9e8241b82a8851926624269954d0ff8e22d82e32e73455f387f4e245"}, + {file = "langsmith-0.0.80.tar.gz", hash = "sha256:6d22ee07eb41c65b3f5166b20041a026714952497d9e80d5be6879d3a5c14d84"}, ] [package.dependencies] @@ -2013,13 +2030,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.7.1" +version = "1.7.2" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.7.1-py3-none-any.whl", hash = "sha256:e52ad7ea015331edc584e6e9c98741c819d7ffbbd2ecc50bf1f55c33f9cb3f77"}, - {file = "openai-1.7.1.tar.gz", hash = "sha256:7556e6aa30e20254b1ad68de49bb5ef4d8106bfac5e8a78abdc1daa911fbb1fb"}, + {file = "openai-1.7.2-py3-none-any.whl", hash = "sha256:8f41b90a762f5fd9d182b45851041386fed94c8ad240a70abefee61a68e0ef53"}, + {file = "openai-1.7.2.tar.gz", hash = "sha256:c73c78878258b07f1b468b0602c6591f25a1478f49ecb90b9bd44b7cc80bce73"}, ] [package.dependencies] @@ -4424,4 +4441,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "05aa4db63c592f8c68e48c3f9aa71e7d376852faaaef9a95c0d0ae74d848bae0" +content-hash = "76237f0e04218f9ca9a2593ccf952452bd6d45657066feec87373279fb7fe6a2" diff --git a/apps/api/pyproject.toml b/apps/api/pyproject.toml index 882b0940..1e13bcc5 100644 --- a/apps/api/pyproject.toml +++ b/apps/api/pyproject.toml @@ -38,6 +38,8 @@ sentence-transformers = "^2.2.2" python-dotenv = "^1.0.0" redis = "^5.0.1" langchain-community = "^0.0.11" +langchain-openai = "^0.0.2.post1" + [build-system] requires = ["poetry-core"] diff --git a/apps/api/requirements.txt b/apps/api/requirements.txt index bce51e62..e3c28897 100644 --- a/apps/api/requirements.txt +++ b/apps/api/requirements.txt @@ -20,6 +20,7 @@ sentry-sdk[fastapi] pydantic[email]>=1.8.0,<2.0.0 langchain==0.1.0 langchain-community +langchain-openai tiktoken openai chromadb diff --git a/apps/api/src/db/organization_config.py b/apps/api/src/db/organization_config.py index 3608666b..214a5d0d 100644 --- a/apps/api/src/db/organization_config.py +++ b/apps/api/src/db/organization_config.py @@ -1,7 +1,4 @@ -from json import JSONEncoder -import json from typing import Literal, Optional -from click import Option from pydantic import BaseModel from sqlalchemy import JSON, BigInteger, Column, ForeignKey from sqlmodel import Field, SQLModel @@ -21,6 +18,7 @@ class AIEnabledFeatures(BaseModel): class AIConfig(BaseModel): + enabled : bool = True limits: AILimitsSettings = AILimitsSettings() embeddings: Literal[ "text-embedding-ada-002", "all-MiniLM-L6-v2" diff --git a/apps/api/src/db/organizations.py b/apps/api/src/db/organizations.py index 57b5bbf8..f9257be6 100644 --- a/apps/api/src/db/organizations.py +++ b/apps/api/src/db/organizations.py @@ -29,6 +29,6 @@ class OrganizationCreate(OrganizationBase): class OrganizationRead(OrganizationBase): id: int org_uuid: str - config: OrganizationConfig | dict + config: Optional[OrganizationConfig | dict] creation_date: str update_date: str diff --git a/apps/api/src/routers/orgs.py b/apps/api/src/routers/orgs.py index 1b39c4e8..9870b3db 100644 --- a/apps/api/src/routers/orgs.py +++ b/apps/api/src/routers/orgs.py @@ -1,6 +1,7 @@ from typing import List from fastapi import APIRouter, Depends, Request, UploadFile from sqlmodel import Session +from src.db.organization_config import OrganizationConfigBase from src.db.users import PublicUser from src.db.organizations import ( Organization, @@ -12,6 +13,7 @@ from src.core.events.database import get_db_session from src.security.auth import get_current_user from src.services.orgs.orgs import ( create_org, + create_org_with_config, delete_org, get_organization, get_organization_by_slug, @@ -37,6 +39,23 @@ async def api_create_org( return await create_org(request, org_object, current_user, db_session) +# Temporary pre-alpha code +@router.post("/withconfig/") +async def api_create_org_withconfig( + request: Request, + org_object: OrganizationCreate, + config_object: OrganizationConfigBase, + current_user: PublicUser = Depends(get_current_user), + db_session: Session = Depends(get_db_session), +) -> OrganizationRead: + """ + Create new organization + """ + return await create_org_with_config( + request, org_object, current_user, db_session, config_object + ) + + @router.get("/{org_id}") async def api_get_org( request: Request, @@ -110,7 +129,7 @@ async def api_update_org( """ Update Org by ID """ - return await update_org(request, org_object,org_id, current_user, db_session) + return await update_org(request, org_object, org_id, current_user, db_session) @router.delete("/{org_id}") diff --git a/apps/api/src/services/ai/ai.py b/apps/api/src/services/ai/ai.py index 3ad79a56..833778d6 100644 --- a/apps/api/src/services/ai/ai.py +++ b/apps/api/src/services/ai/ai.py @@ -2,6 +2,9 @@ from uuid import uuid4 from fastapi import Depends, HTTPException, Request from requests import session from sqlmodel import Session, select +from src.db.organization_config import OrganizationConfig +from src.db.organizations import Organization +from src.services.ai.utils import check_limits_and_config, count_ai_ask from src.db.courses import Course, CourseRead from src.core.events.database import get_db_session from src.db.users import PublicUser @@ -29,6 +32,7 @@ def ai_start_activity_chat_session( """ Start a new AI Chat session with a Course Activity """ + # Get the Activity statement = select(Activity).where( Activity.activity_uuid == chat_session_object.activity_uuid @@ -46,6 +50,14 @@ def ai_start_activity_chat_session( course = db_session.exec(statement).first() course = CourseRead.from_orm(course) + # Get the Organization + statement = select(Organization).where(Organization.id == course.org_id) + org = db_session.exec(statement).first() + + # Check limits and usage + check_limits_and_config(db_session, org) # type: ignore + count_ai_ask(org, "increment") # type: ignore + if not activity: raise HTTPException( status_code=404, @@ -61,28 +73,48 @@ def ai_start_activity_chat_session( structured, course, activity ) + # Get Activity Organization + statement = select(Organization).where(Organization.id == course.org_id) + org = db_session.exec(statement).first() + + # Get Organization Config + statement = select(OrganizationConfig).where( + OrganizationConfig.org_id == org.id # type: ignore + ) + result = db_session.exec(statement) + org_config = result.first() + + org_config = OrganizationConfig.from_orm(org_config) + embeddings = org_config.config["AIConfig"]["embeddings"] + ai_model = org_config.config["AIConfig"]["ai_model"] + chat_session = get_chat_session_history() + message = "You are a helpful Education Assistant, and you are helping a student with the associated Course. " + message += "Use the available tools to get context about this question even if the question is not specific enough." + message += "For context, this is the Course name :" + message += course.name + message += " and this is the Lecture name :" + message += activity.name + message += "." + message += "Use your knowledge to help the student if the context is not enough." + response = ask_ai( chat_session_object.message, - chat_session['message_history'], + chat_session["message_history"], ai_friendly_text, - "You are a helpful Education Assistant, and you are helping a student with the associated Course. " - "Use the available tools to get context about this question even if the question is not specific enough." - "For context, this is the Course name :" - + course.name - + " and this is the Lecture name :" - + activity.name - + "." - "Use your knowledge to help the student.", + message, + embeddings, + ai_model, ) return ActivityAIChatSessionResponse( - aichat_uuid=chat_session['aichat_uuid'], + aichat_uuid=chat_session["aichat_uuid"], activity_uuid=activity.activity_uuid, message=response["output"], ) + def ai_send_activity_chat_message( request: Request, chat_session_object: SendActivityAIChatMessage, @@ -109,6 +141,14 @@ def ai_send_activity_chat_message( course = db_session.exec(statement).first() course = CourseRead.from_orm(course) + # Get the Organization + statement = select(Organization).where(Organization.id == course.org_id) + org = db_session.exec(statement).first() + + # Check limits and usage + check_limits_and_config(db_session, org) # type: ignore + count_ai_ask(org, "increment") # type: ignore + if not activity: raise HTTPException( status_code=404, @@ -116,7 +156,7 @@ def ai_send_activity_chat_message( ) # Get Activity Content Blocks - content = activity.content + content = activity.content # Serialize Activity Content Blocks to a text comprehensible by the AI structured = structure_activity_content_by_type(content) @@ -124,24 +164,43 @@ def ai_send_activity_chat_message( structured, course, activity ) + # Get Activity Organization + statement = select(Organization).where(Organization.id == course.org_id) + org = db_session.exec(statement).first() + + # Get Organization Config + statement = select(OrganizationConfig).where( + OrganizationConfig.org_id == org.id # type: ignore + ) + result = db_session.exec(statement) + org_config = result.first() + + org_config = OrganizationConfig.from_orm(org_config) + embeddings = org_config.config["AIConfig"]["embeddings"] + ai_model = org_config.config["AIConfig"]["ai_model"] + chat_session = get_chat_session_history(chat_session_object.aichat_uuid) + message = "You are a helpful Education Assistant, and you are helping a student with the associated Course. " + message += "Use the available tools to get context about this question even if the question is not specific enough." + message += "For context, this is the Course name :" + message += course.name + message += " and this is the Lecture name :" + message += activity.name + message += "." + message += "Use your knowledge to help the student if the context is not enough." + response = ask_ai( chat_session_object.message, - chat_session['message_history'], + chat_session["message_history"], ai_friendly_text, - "You are a helpful Education Assistant, and you are helping a student with the associated Course. " - "Use the available tools to get context about this question even if the question is not specific enough." - "For context, this is the Course name :" - + course.name - + " and this is the Lecture name :" - + activity.name - + "." - "Use your knowledge to help the student if the context is not enough.", + message, + embeddings, + ai_model, ) return ActivityAIChatSessionResponse( - aichat_uuid=chat_session['aichat_uuid'], + aichat_uuid=chat_session["aichat_uuid"], activity_uuid=activity.activity_uuid, message=response["output"], ) diff --git a/apps/api/src/services/ai/base.py b/apps/api/src/services/ai/base.py index 798f2c06..49929b8c 100644 --- a/apps/api/src/services/ai/base.py +++ b/apps/api/src/services/ai/base.py @@ -11,6 +11,7 @@ from langchain_core.messages import SystemMessage from langchain.agents.openai_functions_agent.agent_token_buffer_memory import ( AgentTokenBufferMemory, ) +from langchain_openai import OpenAIEmbeddings from langchain_community.chat_models import ChatOpenAI from langchain.agents.agent_toolkits import ( create_retriever_tool, @@ -31,6 +32,8 @@ def ask_ai( message_history, text_reference: str, message_for_the_prompt: str, + embedding_model_name: str, + openai_model_name: str, ): # Get API Keys LH_CONFIG = get_learnhouse_config() @@ -41,8 +44,20 @@ def ask_ai( documents = text_splitter.create_documents([text_reference]) texts = text_splitter.split_documents(documents) - # create the open-source embedding function - embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2") + embedding_models = { + "all-MiniLM-L6-v2": SentenceTransformerEmbeddings, + "text-embedding-ada-002": OpenAIEmbeddings, + } + + embedding_function = None + + if embedding_model_name in embedding_models: + if embedding_model_name == "text-embedding-ada-002": + embedding_function = embedding_models[embedding_model_name](model=embedding_model_name, api_key=openai_api_key) + if embedding_model_name == "all-MiniLM-L6-v2": + embedding_function = embedding_models[embedding_model_name](model_name=embedding_model_name) + else: + embedding_function = embedding_models[embedding_model_name](model_name=embedding_model_name) # load it into Chroma and use it as a retriever db = Chroma.from_documents(texts, embedding_function) @@ -53,12 +68,14 @@ def ask_ai( ) tools = [tool] - llm = ChatOpenAI(temperature=0, api_key=openai_api_key, model_name="gpt-3.5-turbo") + llm = ChatOpenAI( + temperature=0, api_key=openai_api_key, model_name=openai_model_name + ) memory_key = "history" memory = AgentTokenBufferMemory( - memory_key=memory_key, llm=llm, chat_memory=message_history, max_tokens=1000 + memory_key=memory_key, llm=llm, chat_memory=message_history, max_token_limit=1000 ) system_message = SystemMessage(content=(message_for_the_prompt)) diff --git a/apps/api/src/services/ai/utils.py b/apps/api/src/services/ai/utils.py new file mode 100644 index 00000000..4b708ec1 --- /dev/null +++ b/apps/api/src/services/ai/utils.py @@ -0,0 +1,114 @@ +from typing import Literal +import redis +from fastapi import HTTPException +from sqlmodel import Session, select +from config.config import get_learnhouse_config +from src.db.organization_config import OrganizationConfig +from src.db.organizations import Organization + + +def count_ai_ask( + organization: Organization, + operation: Literal["increment", "decrement"], +): + """ + Count the number of AI asks + """ + + LH_CONFIG = get_learnhouse_config() + redis_conn_string = LH_CONFIG.redis_config.redis_connection_string + + if not redis_conn_string: + raise HTTPException( + status_code=500, + detail="Redis connection string not found", + ) + + # Connect to Redis + r = redis.Redis.from_url(redis_conn_string) + + if not r: + raise HTTPException( + status_code=500, + detail="Could not connect to Redis", + ) + + # Get the number of AI asks + ai_asks = r.get(f"ai_asks:{organization.org_uuid}") + + if ai_asks is None: + ai_asks = 0 + + # Increment or decrement the number of AI asks + if operation == "increment": + ai_asks = int(ai_asks) + 1 + elif operation == "decrement": + ai_asks = int(ai_asks) - 1 + + # Update the number of AI asks + r.set(f"ai_asks:{organization.org_uuid}", ai_asks) + + # Set the expiration time to 30 days + r.expire(f"ai_asks:{organization.org_uuid}", 2592000) + + +def check_limits_and_config(db_session: Session, organization: Organization): + """ + Check the limits and config of an Organization + """ + + # Get the Organization Config + statement = select(OrganizationConfig).where( + OrganizationConfig.org_id == organization.id + ) + result = db_session.exec(statement) + org_config = result.first() + + if org_config is None: + raise HTTPException( + status_code=404, + detail="Organization has no config", + ) + + # Check if the Organizations has AI enabled + if org_config.config["AIConfig"]["enabled"] == False: + raise HTTPException( + status_code=403, + detail="Organization has AI disabled", + ) + + # Check if the Organization has Limits enabled and if the max_asks limit has been reached + if org_config.config["AIConfig"]["limits"]["limits_enabled"] == True: + LH_CONFIG = get_learnhouse_config() + redis_conn_string = LH_CONFIG.redis_config.redis_connection_string + + if not redis_conn_string: + raise HTTPException( + status_code=500, + detail="Redis connection string not found", + ) + + # Connect to Redis + r = redis.Redis.from_url(redis_conn_string) + + if not r: + raise HTTPException( + status_code=500, + detail="Could not connect to Redis", + ) + + # Get the number of AI asks + ai_asks = r.get(f"ai_asks:{organization.org_uuid}") + + # Get a number of AI asks + if ai_asks is None: + ai_asks = 0 + else: + ai_asks = int(ai_asks) + + # Check if the Number of asks is less than the max_asks limit + if org_config.config["AIConfig"]["limits"]["max_asks"] <= ai_asks: + raise HTTPException( + status_code=403, + detail="Organization has reached the max number of AI asks", + ) diff --git a/apps/api/src/services/blocks/block_types/imageBlock/imageBlock.py b/apps/api/src/services/blocks/block_types/imageBlock/imageBlock.py index f32e69e9..8e5ce688 100644 --- a/apps/api/src/services/blocks/block_types/imageBlock/imageBlock.py +++ b/apps/api/src/services/blocks/block_types/imageBlock/imageBlock.py @@ -44,12 +44,12 @@ async def create_image_block( image_file, activity_uuid, block_uuid, - ["jpg", "jpeg", "png", "gif"], + ["jpg", "jpeg", "png", "gif", "webp"], block_type, org.org_uuid, str(course.course_uuid), ) - + # create block block = Block( activity_id=activity.id if activity.id else 0, diff --git a/apps/api/src/services/courses/activities/utils.py b/apps/api/src/services/courses/activities/utils.py index 8e036b8e..1b7b3913 100644 --- a/apps/api/src/services/courses/activities/utils.py +++ b/apps/api/src/services/courses/activities/utils.py @@ -1,30 +1,25 @@ from src.db.activities import ActivityRead from src.db.courses import CourseRead + def structure_activity_content_by_type(activity): ### Get Headings, Texts, Callouts, Answers and Paragraphs from the activity as a big list of strings (text only) and return it + content = activity["content"] - # Get Headings headings = [] - for item in activity["content"]: - if item["type"] == "heading": - headings.append(item["content"][0]["text"]) - - # Get Callouts callouts = [] - for item in activity["content"]: - if item["type"] == "calloutInfo": - # Get every type of text in the callout - text = "" - for text_item in item["content"]: - text += text_item["text"] - callouts.append(text) - - # Get Paragraphs paragraphs = [] - for item in activity["content"]: - if item["type"] == "paragraph": - paragraphs.append(item["content"][0]["text"]) + + for item in content: + if 'content' in item: + if item["type"] == "heading" and "text" in item["content"][0]: + headings.append(item["content"][0]["text"]) + elif item["type"] in ["calloutInfo", "calloutWarning"] and all("text" in text_item for text_item in item["content"]): + callouts.append( + "".join([text_item["text"] for text_item in item["content"]]) + ) + elif item["type"] == "paragraph" and "text" in item["content"][0]: + paragraphs.append(item["content"][0]["text"]) # TODO: Get Questions and Answers (if any) @@ -39,10 +34,14 @@ def structure_activity_content_by_type(activity): # Add Paragraphs data_array.append({"Paragraphs": paragraphs}) + print(data_array) + return data_array -def serialize_activity_text_to_ai_comprehensible_text(data_array, course: CourseRead, activity: ActivityRead): +def serialize_activity_text_to_ai_comprehensible_text( + data_array, course: CourseRead, activity: ActivityRead +): ### Serialize the text to a format that is comprehensible by the AI # Serialize Headings @@ -63,9 +62,13 @@ def serialize_activity_text_to_ai_comprehensible_text(data_array, course: Course # Get a text that is comprehensible by the AI text = ( - 'Use this as a context ' + - 'This is a course about "' + course.name + '". ' - + 'This is a lecture about "' + activity.name + '". ' + "Use this as a context " + + 'This is a course about "' + + course.name + + '". ' + + 'This is a lecture about "' + + activity.name + + '". ' 'These are the headings: "' + serialized_headings + '" These are the callouts: "' diff --git a/apps/api/src/services/orgs/orgs.py b/apps/api/src/services/orgs/orgs.py index 3b673dd5..00dc87cf 100644 --- a/apps/api/src/services/orgs/orgs.py +++ b/apps/api/src/services/orgs/orgs.py @@ -165,6 +165,7 @@ async def create_org( active=True, ), AIConfig=AIConfig( + enabled=False, limits=AILimitsSettings( limits_enabled=False, max_asks=0, @@ -210,6 +211,87 @@ async def create_org( return org +# Temporary pre-alpha code +async def create_org_with_config( + request: Request, + org_object: OrganizationCreate, + current_user: PublicUser | AnonymousUser, + db_session: Session, + submitted_config: OrganizationConfigBase, +): + statement = select(Organization).where(Organization.slug == org_object.slug) + result = db_session.exec(statement) + + org = result.first() + + if org: + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, + detail="Organization already exists", + ) + + org = Organization.from_orm(org_object) + + if isinstance(current_user, AnonymousUser): + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, + detail="You should be logged in to be able to achieve this action", + ) + + # Complete the org object + org.org_uuid = f"org_{uuid4()}" + org.creation_date = str(datetime.now()) + org.update_date = str(datetime.now()) + + db_session.add(org) + db_session.commit() + db_session.refresh(org) + + # Link user to org + user_org = UserOrganization( + user_id=int(current_user.id), + org_id=int(org.id if org.id else 0), + role_id=1, + creation_date=str(datetime.now()), + update_date=str(datetime.now()), + ) + + db_session.add(user_org) + db_session.commit() + db_session.refresh(user_org) + + org_config = submitted_config + + org_config = json.loads(org_config.json()) + + # OrgSettings + org_settings = OrganizationConfig( + org_id=int(org.id if org.id else 0), + config=org_config, + creation_date=str(datetime.now()), + update_date=str(datetime.now()), + ) + + db_session.add(org_settings) + db_session.commit() + db_session.refresh(org_settings) + + # Get org config + statement = select(OrganizationConfig).where(OrganizationConfig.org_id == org.id) + result = db_session.exec(statement) + + org_config = result.first() + + if org_config is None: + logging.error(f"Organization {org.id} has no config") + + config = OrganizationConfig.from_orm(org_config) + + org = OrganizationRead(**org.dict(), config=config) + + return org + + async def update_org( request: Request, org_object: OrganizationUpdate, diff --git a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx index 8119781b..631039fb 100644 --- a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx +++ b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx @@ -13,7 +13,7 @@ import AuthenticatedClientElement from "@components/Security/AuthenticatedClient import { getCourseThumbnailMediaDirectory } from "@services/media/media"; import { useOrg } from "@components/Contexts/OrgContext"; import { CourseProvider } from "@components/Contexts/CourseContext"; -import AIActivityAsk from "@components/AI/AIActivityAsk"; +import AIActivityAsk from "@components/Objects/Activities/AI/AIActivityAsk"; import AIChatBotProvider from "@components/Contexts/AI/AIChatBotContext"; interface ActivityClientProps { diff --git a/apps/web/components/AI/Hooks/useGetAIFeatures.tsx b/apps/web/components/AI/Hooks/useGetAIFeatures.tsx new file mode 100644 index 00000000..fcd65ca0 --- /dev/null +++ b/apps/web/components/AI/Hooks/useGetAIFeatures.tsx @@ -0,0 +1,39 @@ +import { useOrg } from '@components/Contexts/OrgContext' +import React from 'react' + +interface UseGetAIFeatures { + feature: 'editor' | 'activity_ask' | 'course_ask' | 'global_ai_ask', +} + + +function useGetAIFeatures(props: UseGetAIFeatures) { + const org = useOrg() as any + const [isEnabled, setisEnabled] = React.useState(false) + + function checkAvailableAIFeaturesOnOrg(feature: string) { + const config = org.config.config.AIConfig; + if (!config.enabled) { + console.log("AI is not enabled for this Organization."); + return false; + } + + if (!config.features[feature]) { + console.log(`Feature ${feature} is not enabled for this Organization.`); + return false; + } + + return true; + } + + React.useEffect(() => { + if (org) { // Check if org is not null or undefined + let isEnabledStatus = checkAvailableAIFeaturesOnOrg(props.feature) + setisEnabled(isEnabledStatus) + } + }, [org]) + + return isEnabled + +} + +export default useGetAIFeatures \ No newline at end of file diff --git a/apps/web/components/Contexts/AI/AIChatBotContext.tsx b/apps/web/components/Contexts/AI/AIChatBotContext.tsx index d39d93e7..b912bd1a 100644 --- a/apps/web/components/Contexts/AI/AIChatBotContext.tsx +++ b/apps/web/components/Contexts/AI/AIChatBotContext.tsx @@ -1,5 +1,5 @@ 'use client'; -import { AIMessage } from '@components/AI/AIActivityAsk'; +import { AIMessage } from '@components/Objects/Activities/AI/AIActivityAsk'; import React, { createContext, useContext, useReducer } from 'react' export const AIChatBotContext = createContext(null) as any; export const AIChatBotDispatchContext = createContext(null) as any; diff --git a/apps/web/components/Contexts/AI/AIEditorContext.tsx b/apps/web/components/Contexts/AI/AIEditorContext.tsx index aa314032..49be94b3 100644 --- a/apps/web/components/Contexts/AI/AIEditorContext.tsx +++ b/apps/web/components/Contexts/AI/AIEditorContext.tsx @@ -1,5 +1,5 @@ 'use client'; -import { AIMessage } from '@components/AI/AIActivityAsk'; +import { AIMessage } from '@components/Objects/Activities/AI/AIActivityAsk'; import React, { createContext, useContext, useReducer } from 'react' export const AIEditorContext = createContext(null) as any; export const AIEditorDispatchContext = createContext(null) as any; diff --git a/apps/web/components/AI/AIActivityAsk.tsx b/apps/web/components/Objects/Activities/AI/AIActivityAsk.tsx similarity index 90% rename from apps/web/components/AI/AIActivityAsk.tsx rename to apps/web/components/Objects/Activities/AI/AIActivityAsk.tsx index c30f315d..884e0435 100644 --- a/apps/web/components/AI/AIActivityAsk.tsx +++ b/apps/web/components/Objects/Activities/AI/AIActivityAsk.tsx @@ -8,10 +8,11 @@ import Image from 'next/image'; import { send } from 'process'; import learnhouseAI_icon from "public/learnhouse_ai_simple.png"; import learnhouseAI_logo_black from "public/learnhouse_ai_black_logo.png"; -import React, { useEffect, useRef } from 'react' +import React, { use, useEffect, useRef } from 'react' import { AIChatBotStateTypes, useAIChatBot, useAIChatBotDispatch } from '@components/Contexts/AI/AIChatBotContext'; import FeedbackModal from '@components/Objects/Modals/Feedback/Feedback'; import Modal from '@components/StyledElements/Modal/Modal'; +import useGetAIFeatures from '../../../AI/Hooks/useGetAIFeatures'; type AIActivityAskProps = { @@ -20,25 +21,38 @@ type AIActivityAskProps = { function AIActivityAsk(props: AIActivityAskProps) { - + const is_ai_feature_enabled = useGetAIFeatures({ feature: 'activity_ask' }); + const [isButtonAvailable, setIsButtonAvailable] = React.useState(false); const dispatchAIChatBot = useAIChatBotDispatch() as any; + useEffect(() => { + if (is_ai_feature_enabled) { + setIsButtonAvailable(true); + } + } + , [is_ai_feature_enabled]); + return ( -
- -
dispatchAIChatBot({ type: 'setIsModalOpen' })} - style={{ - background: 'conic-gradient(from 32deg at 53.75% 50%, rgb(35, 40, 93) 4deg, rgba(20, 0, 52, 0.95) 59deg, rgba(164, 45, 238, 0.88) 281deg)', - }} - className="rounded-full px-5 drop-shadow-md flex items-center space-x-1.5 p-2.5 text-sm text-white hover:cursor-pointer transition delay-150 duration-300 ease-in-out hover:scale-105"> - {" "} - - - {" "} - Ask AI -
-
+ <> + {isButtonAvailable && ( +
+ +
dispatchAIChatBot({ type: 'setIsModalOpen' })} + style={{ + background: 'conic-gradient(from 32deg at 53.75% 50%, rgb(35, 40, 93) 4deg, rgba(20, 0, 52, 0.95) 59deg, rgba(164, 45, 238, 0.88) 281deg)', + }} + className="rounded-full px-5 drop-shadow-md flex items-center space-x-1.5 p-2.5 text-sm text-white hover:cursor-pointer transition delay-150 duration-300 ease-in-out hover:scale-105"> + {" "} + + + {" "} + Ask AI +
+
+ )} + + ) } diff --git a/apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx b/apps/web/components/Objects/Activities/DynamicCanva/AI/AICanvaToolkit.tsx similarity index 71% rename from apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx rename to apps/web/components/Objects/Activities/DynamicCanva/AI/AICanvaToolkit.tsx index 4d53d921..3bb2a041 100644 --- a/apps/web/components/Objects/Activities/DynamicCanva/Elements/AICanvaToolkit.tsx +++ b/apps/web/components/Objects/Activities/DynamicCanva/AI/AICanvaToolkit.tsx @@ -7,6 +7,7 @@ import { BubbleMenu } from '@tiptap/react'; import ToolTip from '@components/StyledElements/Tooltip/Tooltip'; import { AIChatBotStateTypes, useAIChatBot, useAIChatBotDispatch } from '@components/Contexts/AI/AIChatBotContext'; import { sendActivityAIChatMessage, startActivityAIChatSession } from '@services/ai/ai'; +import useGetAIFeatures from '../../../../AI/Hooks/useGetAIFeatures'; @@ -16,23 +17,35 @@ type AICanvaToolkitProps = { } function AICanvaToolkit(props: AICanvaToolkitProps) { + const is_ai_feature_enabled = useGetAIFeatures({ feature: 'activity_ask' }); + const [isBubbleMenuAvailable, setIsButtonAvailable] = React.useState(false); + + React.useEffect(() => { + if (is_ai_feature_enabled) { + setIsButtonAvailable(true); + } + }, [is_ai_feature_enabled]) + + return ( - -
-
AI
-
- + <> + {isBubbleMenuAvailable && +
+
AI
+
+ +
+
+ + + + +
-
- - - - -
-
- + } + ) } @@ -45,7 +58,7 @@ function AIActionButton(props: { editor: Editor, label: string, activity: any }) const prompt = getPrompt(label, selection); dispatchAIChatBot({ type: 'setIsModalOpen' }); await sendMessage(prompt); - + } const getTipTapEditorSelectedText = () => { diff --git a/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx b/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx index d4685919..55d487bf 100644 --- a/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx +++ b/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx @@ -24,7 +24,7 @@ import python from 'highlight.js/lib/languages/python' import java from 'highlight.js/lib/languages/java' import { NoTextInput } from "@components/Objects/Editor/Extensions/NoTextInput/NoTextInput"; import EditorOptionsProvider from "@components/Contexts/Editor/EditorContext"; -import AICanvaToolkit from "./Elements/AICanvaToolkit"; +import AICanvaToolkit from "./AI/AICanvaToolkit"; interface Editor { diff --git a/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx index b4a7824b..efdd29af 100644 --- a/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx +++ b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx @@ -7,6 +7,7 @@ import { Editor } from '@tiptap/react'; import { AIChatBotStateTypes, useAIChatBot, useAIChatBotDispatch } from '@components/Contexts/AI/AIChatBotContext'; import { AIEditorStateTypes, useAIEditor, useAIEditorDispatch } from '@components/Contexts/AI/AIEditorContext'; import { sendActivityAIChatMessage, startActivityAIChatSession } from '@services/ai/ai'; +import useGetAIFeatures from '@components/AI/Hooks/useGetAIFeatures'; type AIEditorToolkitProps = { editor: Editor, @@ -22,48 +23,61 @@ type AIPromptsLabels = { function AIEditorToolkit(props: AIEditorToolkitProps) { const dispatchAIEditor = useAIEditorDispatch() as any; const aiEditorState = useAIEditor() as AIEditorStateTypes; + const is_ai_feature_enabled = useGetAIFeatures({ feature: 'editor' }); + const [isToolkitAvailable, setIsToolkitAvailable] = React.useState(true); + + React.useEffect(() => { + if (is_ai_feature_enabled) { + setIsToolkitAvailable(true); + } + }, [is_ai_feature_enabled]) return ( - - {aiEditorState.isModalOpen && - <> - {aiEditorState.isFeedbackModalOpen && } -
-
-
-
- -
AI Editor
- -
-
-
- - - + <> + {isToolkitAvailable &&
+ + {aiEditorState.isModalOpen && + <> + {aiEditorState.isFeedbackModalOpen && } +
+
+
+
+ +
AI Editor
+ +
+
+
+ + + + + +
+
+ Promise.all([dispatchAIEditor({ type: 'setIsModalClose' }), dispatchAIEditor({ type: 'setIsFeedbackModalClose' })])} size={20} className='text-white/50 hover:cursor-pointer bg-white/10 p-1 rounded-full items-center' /> +
+
+
+
} +
+
} + - -
-
- Promise.all([dispatchAIEditor({ type: 'setIsModalClose' }), dispatchAIEditor({ type: 'setIsFeedbackModalClose' })])} size={20} className='text-white/50 hover:cursor-pointer bg-white/10 p-1 rounded-full items-center' /> -
-
-
-
} -
) } diff --git a/apps/web/components/Objects/Editor/Editor.tsx b/apps/web/components/Objects/Editor/Editor.tsx index 6da8402e..586f78e0 100644 --- a/apps/web/components/Objects/Editor/Editor.tsx +++ b/apps/web/components/Objects/Editor/Editor.tsx @@ -39,10 +39,9 @@ import html from 'highlight.js/lib/languages/xml' import python from 'highlight.js/lib/languages/python' import java from 'highlight.js/lib/languages/java' import { CourseProvider } from "@components/Contexts/CourseContext"; -import { OrgProvider } from "@components/Contexts/OrgContext"; import { useSession } from "@components/Contexts/SessionContext"; -import AIEditorTools from "./AI/AIEditorToolkit"; import AIEditorToolkit from "./AI/AIEditorToolkit"; +import useGetAIFeatures from "@components/AI/Hooks/useGetAIFeatures"; interface Editor { @@ -59,6 +58,14 @@ function Editor(props: Editor) { const session = useSession() as any; const dispatchAIEditor = useAIEditorDispatch() as any; const aiEditorState = useAIEditor() as AIEditorStateTypes; + const is_ai_feature_enabled = useGetAIFeatures({ feature: 'editor' }); + const [isButtonAvailable, setIsButtonAvailable] = React.useState(false); + + React.useEffect(() => { + if (is_ai_feature_enabled) { + setIsButtonAvailable(true); + } + }, [is_ai_feature_enabled]) // remove course_ from course_uuid const course_uuid = props.course.course_uuid.substring(7); @@ -137,7 +144,6 @@ function Editor(props: Editor) { return ( -
-
dispatchAIEditor({ type: aiEditorState.isModalOpen ? 'setIsModalClose' : 'setIsModalOpen' })} style={{ background: 'conic-gradient(from 32deg at 53.75% 50%, rgb(35, 40, 93) 4deg, rgba(20, 0, 52, 0.95) 59deg, rgba(164, 45, 238, 0.88) 281deg)', @@ -183,7 +189,7 @@ function Editor(props: Editor) { {" "} AI Editor -
+
}
@@ -224,7 +230,6 @@ function Editor(props: Editor) { - ); } diff --git a/apps/web/components/Objects/Editor/EditorWrapper.tsx b/apps/web/components/Objects/Editor/EditorWrapper.tsx index 8367b6f8..7549eb4a 100644 --- a/apps/web/components/Objects/Editor/EditorWrapper.tsx +++ b/apps/web/components/Objects/Editor/EditorWrapper.tsx @@ -5,6 +5,7 @@ import Editor from "./Editor"; import { updateActivity } from "@services/courses/activities"; import { toast } from "react-hot-toast"; import Toast from "@components/StyledElements/Toast/Toast"; +import { OrgProvider } from "@components/Contexts/OrgContext"; interface EditorWrapperProps { content: string; @@ -26,7 +27,7 @@ function EditorWrapper(props: EditorWrapperProps): JSX.Element { // setProviderState(provider); setIsLoading(false); } - + @@ -50,8 +51,9 @@ function EditorWrapper(props: EditorWrapperProps): JSX.Element { } else { return <> - ; - + + ; + } } From af7d5edd80f343901df841ad21466af94def6cb4 Mon Sep 17 00:00:00 2001 From: swve Date: Sun, 14 Jan 2024 21:23:32 +0100 Subject: [PATCH 14/18] fix: AI config null check --- apps/web/components/AI/Hooks/useGetAIFeatures.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/web/components/AI/Hooks/useGetAIFeatures.tsx b/apps/web/components/AI/Hooks/useGetAIFeatures.tsx index fcd65ca0..0639aa81 100644 --- a/apps/web/components/AI/Hooks/useGetAIFeatures.tsx +++ b/apps/web/components/AI/Hooks/useGetAIFeatures.tsx @@ -11,7 +11,13 @@ function useGetAIFeatures(props: UseGetAIFeatures) { const [isEnabled, setisEnabled] = React.useState(false) function checkAvailableAIFeaturesOnOrg(feature: string) { - const config = org.config.config.AIConfig; + const config = org?.config?.config?.AIConfig; + + if (!config) { + console.log("AI or Organization config is not defined."); + return false; + } + if (!config.enabled) { console.log("AI is not enabled for this Organization."); return false; From 854c7dd415163a06f549f27e18e10c67f47a80cf Mon Sep 17 00:00:00 2001 From: swve Date: Tue, 16 Jan 2024 23:23:13 +0100 Subject: [PATCH 15/18] feat: better errors feedback --- .../Contexts/AI/AIChatBotContext.tsx | 13 +++- .../Contexts/AI/AIEditorContext.tsx | 14 ++++- .../Objects/Activities/AI/AIActivityAsk.tsx | 46 +++++++++++--- .../Objects/Editor/AI/AIEditorToolkit.tsx | 63 ++++++++++++++----- apps/web/services/ai/ai.ts | 17 +++-- 5 files changed, 118 insertions(+), 35 deletions(-) diff --git a/apps/web/components/Contexts/AI/AIChatBotContext.tsx b/apps/web/components/Contexts/AI/AIChatBotContext.tsx index b912bd1a..dbe2e510 100644 --- a/apps/web/components/Contexts/AI/AIChatBotContext.tsx +++ b/apps/web/components/Contexts/AI/AIChatBotContext.tsx @@ -5,12 +5,18 @@ export const AIChatBotContext = createContext(null) as any; export const AIChatBotDispatchContext = createContext(null) as any; export type AIChatBotStateTypes = { - messages: AIMessage[], isModalOpen: boolean, aichat_uuid: string, isWaitingForResponse: boolean, chatInputValue: string + error: AIError +} + +type AIError = { + isError: boolean + status: number + error_message: string } function AIChatBotProvider({ children }: { children: React.ReactNode }) { @@ -20,7 +26,8 @@ function AIChatBotProvider({ children }: { children: React.ReactNode }) { isModalOpen: false, aichat_uuid: null, isWaitingForResponse: false, - chatInputValue: '' + chatInputValue: '', + error: { isError: false, status: 0, error_message: ' ' } as AIError } ); return ( @@ -60,6 +67,8 @@ function aiChatBotReducer(state: any, action: any) { return { ...state, isWaitingForResponse: false }; case 'setChatInputValue': return { ...state, chatInputValue: action.payload }; + case 'setError': + return { ...state, error: action.payload }; default: throw new Error(`Unhandled action type: ${action.type}`) diff --git a/apps/web/components/Contexts/AI/AIEditorContext.tsx b/apps/web/components/Contexts/AI/AIEditorContext.tsx index 49be94b3..efd9be04 100644 --- a/apps/web/components/Contexts/AI/AIEditorContext.tsx +++ b/apps/web/components/Contexts/AI/AIEditorContext.tsx @@ -14,6 +14,13 @@ export type AIEditorStateTypes = { chatInputValue: string, selectedTool: 'Writer' | 'ContinueWriting' | 'MakeLonger' | 'GenerateQuiz' | 'Translate' isUserInputEnabled: boolean + error: AIError +} + +type AIError = { + isError: boolean + status: number + error_message: string } function AIEditorProvider({ children }: { children: React.ReactNode }) { @@ -26,7 +33,8 @@ function AIEditorProvider({ children }: { children: React.ReactNode }) { isWaitingForResponse: false, chatInputValue: '', selectedTool: 'Writer', - isUserInputEnabled: true + isUserInputEnabled: true, + error: { isError: false, status: 0, error_message: ' ' } as AIError } ); return ( @@ -74,7 +82,9 @@ function aIEditorReducer(state: any, action: any) { return { ...state, isFeedbackModalOpen: false }; case 'setIsUserInputEnabled': return { ...state, isUserInputEnabled: action.payload }; - + case 'setError': + return { ...state, error: action.payload }; + default: throw new Error(`Unhandled action type: ${action.type}`) diff --git a/apps/web/components/Objects/Activities/AI/AIActivityAsk.tsx b/apps/web/components/Objects/Activities/AI/AIActivityAsk.tsx index 884e0435..a1fcff3d 100644 --- a/apps/web/components/Objects/Activities/AI/AIActivityAsk.tsx +++ b/apps/web/components/Objects/Activities/AI/AIActivityAsk.tsx @@ -1,6 +1,6 @@ import { useSession } from '@components/Contexts/SessionContext' import { sendActivityAIChatMessage, startActivityAIChatSession } from '@services/ai/ai'; -import { BadgeInfo, NotebookTabs } from 'lucide-react'; +import { AlertTriangle, BadgeInfo, NotebookTabs } from 'lucide-react'; import Avvvatars from 'avvvatars-react'; import { motion, AnimatePresence } from 'framer-motion'; import { FlaskConical, Keyboard, MessageCircle, MessageSquareIcon, Sparkle, Sparkles, X } from 'lucide-react' @@ -34,7 +34,7 @@ function AIActivityAsk(props: AIActivityAskProps) { return ( <> - {isButtonAvailable && ( + {isButtonAvailable && (
- {aiChatBotState.messages.length > 0 ? ( + {aiChatBotState.messages.length > 0 && !aiChatBotState.error.isError ? (
{aiChatBotState.messages.map((message: AIMessage, index: number) => { return ( @@ -177,6 +189,19 @@ function ActivityChatMessageBox(props: ActivityChatMessageBoxProps) { ) : ( )} + {aiChatBotState.error.isError && ( +
+
+ +
+

Something wrong happened

+ {aiChatBotState.error.error_message} +
+
+
+ + ) + }
@@ -235,10 +260,11 @@ function AIMessage(props: AIMessageProps) { const AIMessagePlaceHolder = (props: { activity_uuid: string, sendMessage: any }) => { const session = useSession() as any; - const [feedbackModal, setFeedbackModal] = React.useState(false); - return ( -
+ const aiChatBotState = useAIChatBot() as AIChatBotStateTypes; + + if (!aiChatBotState.error.isError) { + return
- ) + } } const AIChatPredefinedQuestion = (props: { sendMessage: any, label: string }) => { diff --git a/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx index efdd29af..86ea38e2 100644 --- a/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx +++ b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx @@ -2,7 +2,7 @@ import React from 'react' import learnhouseAI_icon from "public/learnhouse_ai_simple.png"; import { motion, AnimatePresence } from 'framer-motion'; import Image from 'next/image'; -import { BetweenHorizontalStart, FastForward, Feather, FileStack, HelpCircle, Languages, MessageCircle, MoreVertical, Pen, X } from 'lucide-react'; +import { AlertTriangle, BetweenHorizontalStart, FastForward, Feather, FileStack, HelpCircle, Languages, MessageCircle, MoreVertical, Pen, X } from 'lucide-react'; import { Editor } from '@tiptap/react'; import { AIChatBotStateTypes, useAIChatBot, useAIChatBotDispatch } from '@components/Contexts/AI/AIChatBotContext'; import { AIEditorStateTypes, useAIEditor, useAIEditorDispatch } from '@components/Contexts/AI/AIEditorContext'; @@ -96,20 +96,38 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => { await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); await dispatchAIEditor({ type: 'setIsWaitingForResponse' }); const response = await sendActivityAIChatMessage(message, aiEditorState.aichat_uuid, props.activity.activity_uuid) + if (response.success === false) { + await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIEditor({ type: 'setIsModalClose' }); + // wait for 200ms before opening the modal again + await new Promise(resolve => setTimeout(resolve, 200)); + await dispatchAIEditor({ type: 'setError', payload: { isError: true, status: response.status, error_message: response.data.detail } }); + await dispatchAIEditor({ type: 'setIsModalOpen' }); + return ''; + } await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); await dispatchAIEditor({ type: 'setChatInputValue', payload: '' }); - await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); - return response.message; + await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'ai', message: response.data.message, type: 'ai' } }); + return response.data.message; } else { await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); await dispatchAIEditor({ type: 'setIsWaitingForResponse' }); const response = await startActivityAIChatSession(message, props.activity.activity_uuid) - await dispatchAIEditor({ type: 'setAichat_uuid', payload: response.aichat_uuid }); + if (response.success === false) { + await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIEditor({ type: 'setIsModalClose' }); + // wait for 200ms before opening the modal again + await new Promise(resolve => setTimeout(resolve, 200)); + await dispatchAIEditor({ type: 'setError', payload: { isError: true, status: response.status, error_message: response.data.detail } }); + await dispatchAIEditor({ type: 'setIsModalOpen' }); + return ''; + } + await dispatchAIEditor({ type: 'setAichat_uuid', payload: response.data.aichat_uuid }); await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); await dispatchAIEditor({ type: 'setChatInputValue', payload: '' }); - await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); - return response.message; + await dispatchAIEditor({ type: 'addMessage', payload: { sender: 'ai', message: response.data.message, type: 'ai' } }); + return response.data.message; } } @@ -158,10 +176,7 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => { await dispatchAIEditor({ type: 'setIsNoLongerWaitingForResponse' }); } } else if (label === 'GenerateQuiz') { - // Send message to AI - // Wait for response - // Add response to editor - // Close modal + // will be implemented in future stages } else if (label === 'Translate') { let ai_message = ''; let text_selection = getTipTapEditorSelectedText(); @@ -211,6 +226,7 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => { // Wait for 0.3 seconds before adding the next word await new Promise(resolve => setTimeout(resolve, 120)); + } } @@ -313,7 +329,7 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => {
- {aiEditorState.isUserInputEnabled &&
+ {aiEditorState.isUserInputEnabled && !aiEditorState.error.isError &&
@@ -379,11 +395,11 @@ const AiEditorActionScreen = ({ handleOperation }: { handleOperation: any }) => return (
- {aiEditorState.selectedTool === 'Writer' && !aiEditorState.isWaitingForResponse && + {aiEditorState.selectedTool === 'Writer' && !aiEditorState.isWaitingForResponse && !aiEditorState.error.isError &&
Write about...
} - {aiEditorState.selectedTool === 'ContinueWriting' && !aiEditorState.isWaitingForResponse && + {aiEditorState.selectedTool === 'ContinueWriting' && !aiEditorState.isWaitingForResponse && !aiEditorState.error.isError &&

Place your cursor at the end of a sentence to continue writing

{ @@ -393,7 +409,7 @@ const AiEditorActionScreen = ({ handleOperation }: { handleOperation: any }) =>
} - {aiEditorState.selectedTool === 'MakeLonger' && !aiEditorState.isWaitingForResponse && + {aiEditorState.selectedTool === 'MakeLonger' && !aiEditorState.isWaitingForResponse && !aiEditorState.error.isError &&

Select text to make longer

{ @@ -403,7 +419,7 @@ const AiEditorActionScreen = ({ handleOperation }: { handleOperation: any }) =>
} - {aiEditorState.selectedTool === 'Translate' && !aiEditorState.isWaitingForResponse && + {aiEditorState.selectedTool === 'Translate' && !aiEditorState.isWaitingForResponse && !aiEditorState.error.isError &&

Translate selected text to

@@ -416,8 +432,7 @@ const AiEditorActionScreen = ({ handleOperation }: { handleOperation: any }) =>
} - {aiEditorState.isWaitingForResponse &&
- + {aiEditorState.isWaitingForResponse && !aiEditorState.error.isError &&
@@ -425,6 +440,20 @@ const AiEditorActionScreen = ({ handleOperation }: { handleOperation: any }) =>

Thinking...

} + {aiEditorState.error.isError && ( +
+
+ +
+

Something wrong happened

+ {aiEditorState.error.error_message} +
+
+
+ + ) + } +
) } diff --git a/apps/web/services/ai/ai.ts b/apps/web/services/ai/ai.ts index 07f1e522..a3b8e871 100644 --- a/apps/web/services/ai/ai.ts +++ b/apps/web/services/ai/ai.ts @@ -7,8 +7,12 @@ export async function startActivityAIChatSession(message: string, activity_uuid: activity_uuid, }; const result = await fetch(`${getAPIUrl()}ai/start/activity_chat_session`, RequestBody("POST", data, null)); - const res = await result.json(); - return res; + const json = await result.json(); + if (result.status === 200) { + return { success: true, data: json, status: result.status, HTTPmessage: result.statusText }; + } else { + return { success: false, data: json, status: result.status, HTTPmessage: result.statusText }; + } } export async function sendActivityAIChatMessage(message: string, aichat_uuid: string, activity_uuid: string) { @@ -18,6 +22,11 @@ export async function sendActivityAIChatMessage(message: string, aichat_uuid: st activity_uuid, }; const result = await fetch(`${getAPIUrl()}ai/send/activity_chat_message`, RequestBody("POST", data, null)); - const res = await result.json(); - return res; + + const json = await result.json(); + if (result.status === 200) { + return { success: true, data: json, status: result.status, HTTPmessage: result.statusText }; + } else { + return { success: false, data: json, status: result.status, HTTPmessage: result.statusText }; + } } From c77cc50ac3e6eb5a50a887efc775b010a8428df4 Mon Sep 17 00:00:00 2001 From: swve Date: Tue, 16 Jan 2024 23:29:32 +0100 Subject: [PATCH 16/18] fix: include error feedback on AICanvaToolkit --- .../DynamicCanva/AI/AICanvaToolkit.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/web/components/Objects/Activities/DynamicCanva/AI/AICanvaToolkit.tsx b/apps/web/components/Objects/Activities/DynamicCanva/AI/AICanvaToolkit.tsx index 3bb2a041..d71cc41c 100644 --- a/apps/web/components/Objects/Activities/DynamicCanva/AI/AICanvaToolkit.tsx +++ b/apps/web/components/Objects/Activities/DynamicCanva/AI/AICanvaToolkit.tsx @@ -58,7 +58,6 @@ function AIActionButton(props: { editor: Editor, label: string, activity: any }) const prompt = getPrompt(label, selection); dispatchAIChatBot({ type: 'setIsModalOpen' }); await sendMessage(prompt); - } const getTipTapEditorSelectedText = () => { @@ -86,18 +85,30 @@ function AIActionButton(props: { editor: Editor, label: string, activity: any }) await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); await dispatchAIChatBot({ type: 'setIsWaitingForResponse' }); const response = await sendActivityAIChatMessage(message, aiChatBotState.aichat_uuid, props.activity.activity_uuid) + if (response.success == false) { + await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' }); + await dispatchAIChatBot({ type: 'setError', payload: { isError: true, status: response.status, error_message: response.data.detail } }); + return; + } await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' }); await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' }); - await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'ai', message: response.data.message, type: 'ai' } }); } else { await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'user', message: message, type: 'user' } }); await dispatchAIChatBot({ type: 'setIsWaitingForResponse' }); const response = await startActivityAIChatSession(message, props.activity.activity_uuid) - await dispatchAIChatBot({ type: 'setAichat_uuid', payload: response.aichat_uuid }); + if (response.success == false) { + await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' }); + await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' }); + await dispatchAIChatBot({ type: 'setError', payload: { isError: true, status: response.status, error_message: response.data.detail } }); + return; + } + await dispatchAIChatBot({ type: 'setAichat_uuid', payload: response.data.aichat_uuid }); await dispatchAIChatBot({ type: 'setIsNoLongerWaitingForResponse' }); await dispatchAIChatBot({ type: 'setChatInputValue', payload: '' }); - await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'ai', message: response.message, type: 'ai' } }); + await dispatchAIChatBot({ type: 'addMessage', payload: { sender: 'ai', message: response.data.message, type: 'ai' } }); } } From 436d3535e3cae6fe6a46076526e4ab9049a70eb1 Mon Sep 17 00:00:00 2001 From: swve Date: Tue, 16 Jan 2024 23:39:53 +0100 Subject: [PATCH 17/18] fix: not working send button --- apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx index 86ea38e2..7ff15559 100644 --- a/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx +++ b/apps/web/components/Objects/Editor/AI/AIEditorToolkit.tsx @@ -331,7 +331,7 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => {
{aiEditorState.isUserInputEnabled && !aiEditorState.error.isError &&
-
+
handleOperation(aiEditorState.selectedTool, aiEditorState.chatInputValue)} className='bg-white/10 px-3 rounded-md outline outline-1 outline-neutral-200/20 py-2 hover:bg-white/20 hover:outline-neutral-200/40 delay-75 ease-linear transition-all'>
} From 2552016a36c57947c5d999751430cac893de4440 Mon Sep 17 00:00:00 2001 From: swve Date: Tue, 16 Jan 2024 23:49:08 +0100 Subject: [PATCH 18/18] fix: package lock --- apps/api/pyproject.toml | 2 +- apps/api/src/services/ai/ai.py | 2 - apps/api/src/services/orgs/orgs.py | 1 - apps/web/package-lock.json | 16 +--- pnpm-lock.yaml | 133 +++++++++++++++-------------- 5 files changed, 72 insertions(+), 82 deletions(-) diff --git a/apps/api/pyproject.toml b/apps/api/pyproject.toml index 1e13bcc5..ba16002d 100644 --- a/apps/api/pyproject.toml +++ b/apps/api/pyproject.toml @@ -1,6 +1,6 @@ [tool.ruff] # E501 line too long (82 > 79 characters) -ignore = ["E501"] +ignore = ["E501", "E712"] [tool.poetry] name = "learnhouse-api" diff --git a/apps/api/src/services/ai/ai.py b/apps/api/src/services/ai/ai.py index 833778d6..9cd18064 100644 --- a/apps/api/src/services/ai/ai.py +++ b/apps/api/src/services/ai/ai.py @@ -1,6 +1,4 @@ -from uuid import uuid4 from fastapi import Depends, HTTPException, Request -from requests import session from sqlmodel import Session, select from src.db.organization_config import OrganizationConfig from src.db.organizations import Organization diff --git a/apps/api/src/services/orgs/orgs.py b/apps/api/src/services/orgs/orgs.py index 00dc87cf..3ef6b304 100644 --- a/apps/api/src/services/orgs/orgs.py +++ b/apps/api/src/services/orgs/orgs.py @@ -1,7 +1,6 @@ import json import logging from datetime import datetime -from logging import config from typing import Literal from uuid import uuid4 from sqlmodel import Session, select diff --git a/apps/web/package-lock.json b/apps/web/package-lock.json index 0f9ded12..a806572c 100644 --- a/apps/web/package-lock.json +++ b/apps/web/package-lock.json @@ -28,7 +28,7 @@ "formik": "^2.2.9", "framer-motion": "^10.16.1", "lowlight": "^3.0.0", - "lucide-react": "^0.268.0", + "lucide-react": "^0.307.0", "next": "14.0.4", "re-resizable": "^6.9.9", "react": "^18.2.0", @@ -5919,14 +5919,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/geist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/geist/-/geist-1.2.0.tgz", - "integrity": "sha512-RZsgCkGnSi1IV1Ozg3s6Ou4r/jzLff9+47ChjpJ5yX8ncEC/RwdStGwhdFzDcnSv0xU0+9J/fTX5Kht0NajTXA==", - "peerDependencies": { - "next": "^13.2 || ^14" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -6986,9 +6978,9 @@ } }, "node_modules/lucide-react": { - "version": "0.268.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.268.0.tgz", - "integrity": "sha512-XP/xY3ASJAViqNqVnDRcEfdxfRB7uNST8sqTLwZhL983ikmHMQ7qQak7ZxrnXOVhB3QDBawdr3ANq0P+iWHP/g==", + "version": "0.307.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.307.0.tgz", + "integrity": "sha512-+vZ+vUiWPZTMnLHURg4aoIaz6NHOWXVVcVd8iLROu1k4LbyjcnHIKmbjXHCmulz7XAYLWRVXzhJJgIr+Aq3vOg==", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7c9c1e5b..10ac1539 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,8 +42,8 @@ importers: specifier: ^1.0.5 version: 1.0.7(@types/react-dom@18.0.6)(@types/react@18.2.8)(react-dom@18.2.0)(react@18.2.0) '@sentry/nextjs': - specifier: ^7.88.0 - version: 7.88.0(next@14.0.4)(react@18.2.0) + specifier: ^7.92.0 + version: 7.93.0(next@14.0.4)(react@18.2.0) '@stitches/react': specifier: ^1.2.8 version: 1.2.8(react@18.2.0) @@ -2429,34 +2429,34 @@ packages: resolution: {integrity: sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA==} dev: true - /@sentry-internal/feedback@7.88.0: - resolution: {integrity: sha512-lbK6jgO1I0M96nZQ99mcLSZ55ebwPAP6LhEWhkmc+eAfy97VpiY+qsbmgsmOzCEPqMmEUCEcI0rEZ7fiye2v2Q==} + /@sentry-internal/feedback@7.93.0: + resolution: {integrity: sha512-4G7rMeQbYGfCHxEoFroABX+UREYc2BSbFqjLmLbIcWowSpgzcwweLLphWHKOciqK6f7DnNDK0jZzx3u7NrkWHw==} engines: {node: '>=12'} dependencies: - '@sentry/core': 7.88.0 - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 + '@sentry/core': 7.93.0 + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 dev: false - /@sentry-internal/tracing@7.88.0: - resolution: {integrity: sha512-xXQdcYhsS+ourzJHjXNjZC9zakuc97udmpgaXRjEP7FjPYclIx+YXwgFBdHM2kzAwZLFOsEce5dr46GVXUDfZw==} + /@sentry-internal/tracing@7.93.0: + resolution: {integrity: sha512-DjuhmQNywPp+8fxC9dvhGrqgsUb6wI/HQp25lS2Re7VxL1swCasvpkg8EOYP4iBniVQ86QK0uITkOIRc5tdY1w==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.88.0 - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 + '@sentry/core': 7.93.0 + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 dev: false - /@sentry/browser@7.88.0: - resolution: {integrity: sha512-il4x3PB99nuU/OJQw2RltgYYbo8vtnYoIgneOeEiw4m0ppK1nKkMkd3vDRipGL6E/0i7IUmQfYYy6U10J5Rx+g==} + /@sentry/browser@7.93.0: + resolution: {integrity: sha512-MtLTcQ7y3rfk+aIvnnwCfSJvYhTJnIJi+Mf6y/ap6SKObdlsKMbQoJLlRViglGLq+nKxHLAvU0fONiCEmKfV6A==} engines: {node: '>=8'} dependencies: - '@sentry-internal/feedback': 7.88.0 - '@sentry-internal/tracing': 7.88.0 - '@sentry/core': 7.88.0 - '@sentry/replay': 7.88.0 - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 + '@sentry-internal/feedback': 7.93.0 + '@sentry-internal/tracing': 7.93.0 + '@sentry/core': 7.93.0 + '@sentry/replay': 7.93.0 + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 dev: false /@sentry/cli@1.77.1: @@ -2476,26 +2476,26 @@ packages: - supports-color dev: false - /@sentry/core@7.88.0: - resolution: {integrity: sha512-Jzbb7dcwiCO7kI0a1w+32UzWxbEn2OcZWzp55QMEeAh6nZ/5CXhXwpuHi0tW7doPj+cJdmxMTMu9LqMVfdGkzQ==} + /@sentry/core@7.93.0: + resolution: {integrity: sha512-vZQSUiDn73n+yu2fEcH+Wpm4GbRmtxmnXnYCPgM6IjnXqkVm3awWAkzrheADblx3kmxrRiOlTXYHw9NTWs56fg==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 dev: false - /@sentry/integrations@7.88.0: - resolution: {integrity: sha512-YBYPAtJeylMaaCmGntgiDpp1nk3IT6+FBXsmHxMdTKlrpt5ELj/jcc8gEgaRNeSBjx4Kv1OVzmZcYyWwEhkR4Q==} + /@sentry/integrations@7.93.0: + resolution: {integrity: sha512-uGQ8+DiqUr6SbhdJJHyIqDJ6kHnFuSv8nZWtj2tJ1I8q8u8MX8t8Om6R/R4ap45gCkWg/zqZq7B+gQV6TYewjQ==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.88.0 - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 + '@sentry/core': 7.93.0 + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 localforage: 1.10.0 dev: false - /@sentry/nextjs@7.88.0(next@14.0.4)(react@18.2.0): - resolution: {integrity: sha512-tvP9KU7SeL65szenGoexABdPqCVMUTWEP9DroNvBDvTtqfETOf8RbGw8zE+bFNxQ9bjAzhJPibu6oWNcpYvXMA==} + /@sentry/nextjs@7.93.0(next@14.0.4)(react@18.2.0): + resolution: {integrity: sha512-/O4Xl+hMSEM6/sVfmKXCZhLUUGNJbi+L0tasTiw4wB4EQQeMDKf4cBfx8e4mNBMzhA2SZnfQZAwJGqhvFJniPQ==} engines: {node: '>=8'} peerDependencies: next: ^10.0.8 || ^11.0 || ^12.0 || ^13.0 || ^14.0 @@ -2506,13 +2506,13 @@ packages: optional: true dependencies: '@rollup/plugin-commonjs': 24.0.0(rollup@2.78.0) - '@sentry/core': 7.88.0 - '@sentry/integrations': 7.88.0 - '@sentry/node': 7.88.0 - '@sentry/react': 7.88.0(react@18.2.0) - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 - '@sentry/vercel-edge': 7.88.0 + '@sentry/core': 7.93.0 + '@sentry/integrations': 7.93.0 + '@sentry/node': 7.93.0 + '@sentry/react': 7.93.0(react@18.2.0) + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 + '@sentry/vercel-edge': 7.93.0 '@sentry/webpack-plugin': 1.21.0 chalk: 3.0.0 next: 14.0.4(@babel/core@7.23.2)(react-dom@18.2.0)(react@18.2.0) @@ -2525,62 +2525,63 @@ packages: - supports-color dev: false - /@sentry/node@7.88.0: - resolution: {integrity: sha512-X6Xyh7AEitnWqn1CHQrmsUqRn0GKj/6nPE5VC2DLQfHiFH1Fknrt+csFzDchQ/86awXYwuY4Le5ECEH//X/WzQ==} + /@sentry/node@7.93.0: + resolution: {integrity: sha512-nUXPCZQm5Y9Ipv7iWXLNp5dbuyi1VvbJ3RtlwD7utgsNkRYB4ixtKE9w2QU8DZZAjaEF6w2X94OkYH6C932FWw==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.88.0 - '@sentry/core': 7.88.0 - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 + '@sentry-internal/tracing': 7.93.0 + '@sentry/core': 7.93.0 + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 https-proxy-agent: 5.0.1 transitivePeerDependencies: - supports-color dev: false - /@sentry/react@7.88.0(react@18.2.0): - resolution: {integrity: sha512-iDOImijbsc0cYLWNBXlYKhh/sG/czPK/51GcMi3GcEBkhHDDcdWSZ7cNjFAqHfdrMkPf26bYgDPIL6aJsBZwpQ==} + /@sentry/react@7.93.0(react@18.2.0): + resolution: {integrity: sha512-B0bzziV1lEyN7xd0orUPyJdpoK6CtcyodmQkfY0WsHLm/1d9xi95M05lObHnsMWO1js6c9B9d9kO8RlKFz947A==} engines: {node: '>=8'} peerDependencies: react: 15.x || 16.x || 17.x || 18.x dependencies: - '@sentry/browser': 7.88.0 - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 + '@sentry/browser': 7.93.0 + '@sentry/core': 7.93.0 + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 hoist-non-react-statics: 3.3.2 react: 18.2.0 dev: false - /@sentry/replay@7.88.0: - resolution: {integrity: sha512-em5dPKLPG7c/HGDbpIj3aHrWbA4iMwqjevqTzn+++KNO1YslkOosCaGsb1whU3AL1T9c3aIFIhZ4u3rNo+DxcA==} + /@sentry/replay@7.93.0: + resolution: {integrity: sha512-dMlLU8v+OkUeGCrPvTu5NriH7BGj3el4rGHWWAYicfJ2QXqTTq50vfasQBP1JeVNcFqnf1y653TdEIvo4RH4tw==} engines: {node: '>=12'} dependencies: - '@sentry-internal/tracing': 7.88.0 - '@sentry/core': 7.88.0 - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 + '@sentry-internal/tracing': 7.93.0 + '@sentry/core': 7.93.0 + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 dev: false - /@sentry/types@7.88.0: - resolution: {integrity: sha512-FvwvmX1pWAZKicPj4EpKyho8Wm+C4+r5LiepbbBF8oKwSPJdD2QV1fo/LWxsrzNxWOllFIVIXF5Ed3nPYQWpTw==} + /@sentry/types@7.93.0: + resolution: {integrity: sha512-UnzUccNakhFRA/esWBWP+0v7cjNg+RilFBQC03Mv9OEMaZaS29zSbcOGtRzuFOXXLBdbr44BWADqpz3VW0XaNw==} engines: {node: '>=8'} dev: false - /@sentry/utils@7.88.0: - resolution: {integrity: sha512-ukminfRmdBXTzk49orwJf3Lu3hR60ZRHjE2a4IXwYhyDT6JJgJqgsq1hzGXx0AyFfyS4WhfZ6QUBy7fu3BScZQ==} + /@sentry/utils@7.93.0: + resolution: {integrity: sha512-Iovj7tUnbgSkh/WrAaMrd5UuYjW7AzyzZlFDIUrwidsyIdUficjCG2OIxYzh76H6nYIx9SxewW0R54Q6XoB4uA==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.88.0 + '@sentry/types': 7.93.0 dev: false - /@sentry/vercel-edge@7.88.0: - resolution: {integrity: sha512-PfaOiPPRw7y4CcOeP337NsPGyERpO6OlSAmLIaUkKJRjnGNmg1tSzUNfG0lg//fQ8XsZsXIun/ND+XXYtEJFDw==} + /@sentry/vercel-edge@7.93.0: + resolution: {integrity: sha512-3jddd6gVUpGX8Sis9gxODL7zPR+lZohYYvOJVhf8UMglZSiWa3/xYJQ5VISj3UH6sVSxvfMxgssmQEHcvuubHQ==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.88.0 - '@sentry/core': 7.88.0 - '@sentry/types': 7.88.0 - '@sentry/utils': 7.88.0 + '@sentry-internal/tracing': 7.93.0 + '@sentry/core': 7.93.0 + '@sentry/types': 7.93.0 + '@sentry/utils': 7.93.0 dev: false /@sentry/webpack-plugin@1.21.0: