diff --git a/.gitignore b/.gitignore index a6dd346572..c18c41c6d0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,13 @@ node_modules/ /playwright-report/ /blob-report/ /playwright/.cache/ +scripts/ +.env +.env.local +.env.development.local +.env.test.local +.env.production.local +.env.development +.env.test +.env.production +.DS_Store diff --git a/backend/Dockerfile b/backend/Dockerfile index 44c53f0365..d8e5910677 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,43 +1,33 @@ -FROM python:3.10 +FROM python:3.10 as dev ENV PYTHONUNBUFFERED=1 WORKDIR /app/ -# Install uv -# Ref: https://docs.astral.sh/uv/guides/integration/docker/#installing-uv -COPY --from=ghcr.io/astral-sh/uv:0.5.11 /uv /uvx /bin/ +# Install build dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ + libpq-dev \ + python3-dev \ + && rm -rf /var/lib/apt/lists/* -# Place executables in the environment at the front of the path -# Ref: https://docs.astral.sh/uv/guides/integration/docker/#using-the-environment -ENV PATH="/app/.venv/bin:$PATH" +# Copy dependency files +COPY ./pyproject.toml ./alembic.ini /app/ -# Compile bytecode -# Ref: https://docs.astral.sh/uv/guides/integration/docker/#compiling-bytecode -ENV UV_COMPILE_BYTECODE=1 - -# uv Cache -# Ref: https://docs.astral.sh/uv/guides/integration/docker/#caching -ENV UV_LINK_MODE=copy - -# Install dependencies -# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers -RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=bind,source=uv.lock,target=uv.lock \ - --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ - uv sync --frozen --no-install-project - -ENV PYTHONPATH=/app +# Install pip and build tools +RUN pip install --no-cache-dir pip setuptools wheel hatchling +# Copy application code +COPY ./app /app/app COPY ./scripts /app/scripts -COPY ./pyproject.toml ./uv.lock ./alembic.ini /app/ +# Install the package and its dependencies +RUN pip install --no-cache-dir . -COPY ./app /app/app +ENV PYTHONPATH=/app -# Sync the project -# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers -RUN --mount=type=cache,target=/root/.cache/uv \ - uv sync +# Make scripts executable +RUN chmod +x /app/scripts/prestart.sh -CMD ["fastapi", "run", "--workers", "4", "app/main.py"] +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] diff --git a/backend/app/alembic/versions/002_remove_sharing_tables.py b/backend/app/alembic/versions/002_remove_sharing_tables.py new file mode 100644 index 0000000000..852cca978c --- /dev/null +++ b/backend/app/alembic/versions/002_remove_sharing_tables.py @@ -0,0 +1,72 @@ +"""remove_sharing_tables + +Revision ID: 002_remove_sharing_tables +Revises: 8cf5c34c4462 +Create Date: 2024-03-19 10:00:00.000000 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '002_remove_sharing_tables' +down_revision = '8cf5c34c4462' +branch_labels = None +depends_on = None + + +def upgrade(): + # Drop sharing-related tables + op.drop_table('sharedchatmessage') + op.drop_table('sharedchatsession') + op.drop_table('aisoulentityshare') + + +def downgrade(): + # Recreate sharing tables + op.create_table( + 'aisoulentityshare', + sa.Column('id', postgresql.UUID(), nullable=False), + sa.Column('name', sa.String(length=255), nullable=False), + sa.Column('description', sa.String(length=1000), nullable=True), + sa.Column('is_public', sa.Boolean(), nullable=False), + sa.Column('allow_anonymous', sa.Boolean(), nullable=False), + sa.Column('share_code', sa.String(length=50), nullable=False), + sa.Column('owner_id', postgresql.UUID(), nullable=False), + sa.Column('ai_soul_id', postgresql.UUID(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.Column('access_count', sa.Integer(), nullable=False), + sa.Column('last_accessed', sa.DateTime(), nullable=True), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.ForeignKeyConstraint(['owner_id'], ['user.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('share_code') + ) + + op.create_table( + 'sharedchatsession', + sa.Column('id', postgresql.UUID(), nullable=False), + sa.Column('session_name', sa.String(length=255), nullable=True), + sa.Column('share_id', postgresql.UUID(), nullable=False), + sa.Column('visitor_identifier', sa.String(length=255), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('last_message_at', sa.DateTime(), nullable=False), + sa.Column('message_count', sa.Integer(), nullable=False), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.ForeignKeyConstraint(['share_id'], ['aisoulentityshare.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + + op.create_table( + 'sharedchatmessage', + sa.Column('id', postgresql.UUID(), nullable=False), + sa.Column('session_id', postgresql.UUID(), nullable=False), + sa.Column('content', sa.String(length=5000), nullable=False), + sa.Column('is_from_visitor', sa.Boolean(), nullable=False), + sa.Column('timestamp', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['session_id'], ['sharedchatsession.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) \ No newline at end of file diff --git a/backend/app/alembic/versions/26ef24513797_increase_embedding_field_size.py b/backend/app/alembic/versions/26ef24513797_increase_embedding_field_size.py new file mode 100644 index 0000000000..29c4549889 --- /dev/null +++ b/backend/app/alembic/versions/26ef24513797_increase_embedding_field_size.py @@ -0,0 +1,51 @@ +"""increase_embedding_field_size + +Revision ID: 26ef24513797 +Revises: 002_remove_sharing_tables +Create Date: 2025-07-07 16:47:51.022514 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = '26ef24513797' +down_revision = '002_remove_sharing_tables' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('documentchunk', 'embedding', + existing_type=sa.VARCHAR(length=10000), + type_=sqlmodel.sql.sqltypes.AutoString(length=50000), + existing_nullable=True) + op.alter_column('trainingdocumentchunk', 'embedding', + existing_type=sa.VARCHAR(length=10000), + type_=sqlmodel.sql.sqltypes.AutoString(length=50000), + existing_nullable=True) + op.alter_column('trainingmessage', 'embedding', + existing_type=sa.VARCHAR(length=10000), + type_=sqlmodel.sql.sqltypes.AutoString(length=50000), + existing_nullable=True) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('trainingmessage', 'embedding', + existing_type=sqlmodel.sql.sqltypes.AutoString(length=50000), + type_=sa.VARCHAR(length=10000), + existing_nullable=True) + op.alter_column('trainingdocumentchunk', 'embedding', + existing_type=sqlmodel.sql.sqltypes.AutoString(length=50000), + type_=sa.VARCHAR(length=10000), + existing_nullable=True) + op.alter_column('documentchunk', 'embedding', + existing_type=sqlmodel.sql.sqltypes.AutoString(length=50000), + type_=sa.VARCHAR(length=10000), + existing_nullable=True) + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/28bdd6e65dbb_add_counselor_override_and_analytics_.py b/backend/app/alembic/versions/28bdd6e65dbb_add_counselor_override_and_analytics_.py new file mode 100644 index 0000000000..d70b449bea --- /dev/null +++ b/backend/app/alembic/versions/28bdd6e65dbb_add_counselor_override_and_analytics_.py @@ -0,0 +1,215 @@ +"""add_counselor_override_and_analytics_system + +Revision ID: 28bdd6e65dbb +Revises: 6f83bac06955 +Create Date: 2025-07-09 07:59:06.326213 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = '28bdd6e65dbb' +down_revision = '6f83bac06955' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('organization', + sa.Column('name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('domain', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=True), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.Column('max_users', sa.Integer(), nullable=False), + sa.Column('max_ai_souls', sa.Integer(), nullable=False), + sa.Column('settings', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('domain') + ) + op.create_table('dailyusagemetrics', + sa.Column('date', sa.DateTime(), nullable=False), + sa.Column('total_conversations', sa.Integer(), nullable=False), + sa.Column('total_messages', sa.Integer(), nullable=False), + sa.Column('unique_users', sa.Integer(), nullable=False), + sa.Column('ai_responses_generated', sa.Integer(), nullable=False), + sa.Column('counselor_interventions', sa.Integer(), nullable=False), + sa.Column('high_risk_conversations', sa.Integer(), nullable=False), + sa.Column('average_response_time_ms', sa.Float(), nullable=True), + sa.Column('user_satisfaction_average', sa.Float(), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('organization_id', sa.Uuid(), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_dailyusagemetrics_date'), 'dailyusagemetrics', ['date'], unique=False) + op.create_table('counselor', + sa.Column('specializations', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False), + sa.Column('license_number', sqlmodel.sql.sqltypes.AutoString(length=100), nullable=True), + sa.Column('license_type', sqlmodel.sql.sqltypes.AutoString(length=100), nullable=True), + sa.Column('is_available', sa.Boolean(), nullable=False), + sa.Column('max_concurrent_cases', sa.Integer(), nullable=False), + sa.Column('notification_preferences', sqlmodel.sql.sqltypes.AutoString(length=2000), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('organization_id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('contentfilteranalytics', + sa.Column('filter_type', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('content_sample', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=True), + sa.Column('severity_level', sqlmodel.sql.sqltypes.AutoString(length=20), nullable=False), + sa.Column('action_taken', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('false_positive', sa.Boolean(), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('organization_id', sa.Uuid(), nullable=True), + sa.Column('detected_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('conversationanalytics', + sa.Column('conversation_duration_seconds', sa.Integer(), nullable=True), + sa.Column('message_count', sa.Integer(), nullable=False), + sa.Column('ai_response_count', sa.Integer(), nullable=False), + sa.Column('risk_assessments_triggered', sa.Integer(), nullable=False), + sa.Column('counselor_interventions', sa.Integer(), nullable=False), + sa.Column('user_satisfaction_score', sa.Float(), nullable=True), + sa.Column('topic_categories', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('organization_id', sa.Uuid(), nullable=True), + sa.Column('session_start', sa.DateTime(), nullable=False), + sa.Column('session_end', sa.DateTime(), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('counselorperformance', + sa.Column('date', sa.DateTime(), nullable=False), + sa.Column('cases_reviewed', sa.Integer(), nullable=False), + sa.Column('average_review_time_seconds', sa.Float(), nullable=True), + sa.Column('approvals', sa.Integer(), nullable=False), + sa.Column('modifications', sa.Integer(), nullable=False), + sa.Column('rejections', sa.Integer(), nullable=False), + sa.Column('escalations', sa.Integer(), nullable=False), + sa.Column('user_feedback_score', sa.Float(), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('counselor_id', sa.Uuid(), nullable=False), + sa.Column('organization_id', sa.Uuid(), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['counselor_id'], ['counselor.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_counselorperformance_date'), 'counselorperformance', ['date'], unique=False) + op.create_table('riskassessment', + sa.Column('risk_level', sqlmodel.sql.sqltypes.AutoString(length=20), nullable=False), + sa.Column('risk_categories', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False), + sa.Column('confidence_score', sa.Float(), nullable=False), + sa.Column('reasoning', sqlmodel.sql.sqltypes.AutoString(length=2000), nullable=True), + sa.Column('requires_human_review', sa.Boolean(), nullable=False), + sa.Column('auto_response_blocked', sa.Boolean(), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('chat_message_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('organization_id', sa.Uuid(), nullable=True), + sa.Column('assessed_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['chat_message_id'], ['chatmessage.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('pendingresponse', + sa.Column('original_user_message', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=False), + sa.Column('ai_generated_response', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=False), + sa.Column('status', sqlmodel.sql.sqltypes.AutoString(length=20), nullable=False), + sa.Column('priority', sqlmodel.sql.sqltypes.AutoString(length=20), nullable=False), + sa.Column('counselor_notes', sqlmodel.sql.sqltypes.AutoString(length=2000), nullable=True), + sa.Column('modified_response', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=True), + sa.Column('response_time_limit', sa.DateTime(), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('chat_message_id', sa.Uuid(), nullable=False), + sa.Column('risk_assessment_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('assigned_counselor_id', sa.Uuid(), nullable=True), + sa.Column('organization_id', sa.Uuid(), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('reviewed_at', sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['assigned_counselor_id'], ['counselor.id'], ondelete='SET NULL'), + sa.ForeignKeyConstraint(['chat_message_id'], ['chatmessage.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['risk_assessment_id'], ['riskassessment.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('counseloraction', + sa.Column('action_type', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('original_response', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=True), + sa.Column('final_response', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=True), + sa.Column('reason', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=True), + sa.Column('time_taken_seconds', sa.Integer(), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('counselor_id', sa.Uuid(), nullable=False), + sa.Column('pending_response_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('organization_id', sa.Uuid(), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['counselor_id'], ['counselor.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['pending_response_id'], ['pendingresponse.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + # Add role column with default value first + op.add_column('user', sa.Column('role', sqlmodel.sql.sqltypes.AutoString(length=20), nullable=True)) + + # Update existing users to have 'user' role + op.execute("UPDATE \"user\" SET role = 'user' WHERE role IS NULL") + + # Make role column non-nullable + op.alter_column('user', 'role', nullable=False) + + op.add_column('user', sa.Column('organization_id', sa.Uuid(), nullable=True)) + op.create_foreign_key(None, 'user', 'organization', ['organization_id'], ['id'], ondelete='SET NULL') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint(None, 'user', type_='foreignkey') + op.drop_column('user', 'organization_id') + op.drop_column('user', 'role') + op.drop_table('counseloraction') + op.drop_table('pendingresponse') + op.drop_table('riskassessment') + op.drop_index(op.f('ix_counselorperformance_date'), table_name='counselorperformance') + op.drop_table('counselorperformance') + op.drop_table('conversationanalytics') + op.drop_table('contentfilteranalytics') + op.drop_table('counselor') + op.drop_index(op.f('ix_dailyusagemetrics_date'), table_name='dailyusagemetrics') + op.drop_table('dailyusagemetrics') + op.drop_table('organization') + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/6f83bac06955_increase_training_chunk_content_size.py b/backend/app/alembic/versions/6f83bac06955_increase_training_chunk_content_size.py new file mode 100644 index 0000000000..848b9ec05f --- /dev/null +++ b/backend/app/alembic/versions/6f83bac06955_increase_training_chunk_content_size.py @@ -0,0 +1,43 @@ +"""increase_training_chunk_content_size + +Revision ID: 6f83bac06955 +Revises: 26ef24513797 +Create Date: 2025-07-08 07:55:50.289876 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = '6f83bac06955' +down_revision = '26ef24513797' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('trainingdocumentchunk', 'content', + existing_type=sa.VARCHAR(length=2000), + type_=sqlmodel.sql.sqltypes.AutoString(length=10000), + existing_nullable=False) + op.alter_column('trainingdocumentchunk', 'chunk_metadata', + existing_type=sa.VARCHAR(length=1000), + type_=sqlmodel.sql.sqltypes.AutoString(length=5000), + existing_nullable=True) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('trainingdocumentchunk', 'chunk_metadata', + existing_type=sqlmodel.sql.sqltypes.AutoString(length=5000), + type_=sa.VARCHAR(length=1000), + existing_nullable=True) + op.alter_column('trainingdocumentchunk', 'content', + existing_type=sqlmodel.sql.sqltypes.AutoString(length=10000), + type_=sa.VARCHAR(length=2000), + existing_nullable=False) + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/8cf5c34c4462_add_enhanced_rag_tables.py b/backend/app/alembic/versions/8cf5c34c4462_add_enhanced_rag_tables.py new file mode 100644 index 0000000000..dba7005bb8 --- /dev/null +++ b/backend/app/alembic/versions/8cf5c34c4462_add_enhanced_rag_tables.py @@ -0,0 +1,140 @@ +"""add_enhanced_rag_tables + +Revision ID: 8cf5c34c4462 +Revises: b716a9118488 +Create Date: 2025-07-06 16:06:07.450512 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = '8cf5c34c4462' +down_revision = 'b716a9118488' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('document_chunk_enhanced', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('document_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=4000), nullable=False), + sa.Column('chunk_index', sa.Integer(), nullable=False), + sa.Column('chunk_metadata', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=True), + sa.Column('semantic_metadata', sqlmodel.sql.sqltypes.AutoString(length=3000), nullable=True), + sa.Column('embedding_model', sqlmodel.sql.sqltypes.AutoString(length=100), nullable=False), + sa.Column('embedding_dimension', sa.Integer(), nullable=False), + sa.Column('search_count', sa.Integer(), nullable=False), + sa.Column('click_count', sa.Integer(), nullable=False), + sa.Column('relevance_score', sa.Float(), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('last_accessed', sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint(['document_id'], ['document.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('document_processing_log', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('document_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('processing_stage', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('status', sqlmodel.sql.sqltypes.AutoString(length=20), nullable=False), + sa.Column('processing_time_ms', sa.Integer(), nullable=True), + sa.Column('chunks_created', sa.Integer(), nullable=True), + sa.Column('total_tokens', sa.Integer(), nullable=True), + sa.Column('embedding_cost', sa.Float(), nullable=True), + sa.Column('error_message', sqlmodel.sql.sqltypes.AutoString(length=2000), nullable=True), + sa.Column('retry_count', sa.Integer(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('completed_at', sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint(['document_id'], ['document.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('rag_configuration', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=True), + sa.Column('chunking_strategy', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('chunk_size', sa.Integer(), nullable=False), + sa.Column('chunk_overlap', sa.Integer(), nullable=False), + sa.Column('embedding_model', sqlmodel.sql.sqltypes.AutoString(length=100), nullable=False), + sa.Column('search_algorithm', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('similarity_threshold', sa.Float(), nullable=False), + sa.Column('max_results', sa.Integer(), nullable=False), + sa.Column('enable_reranking', sa.Boolean(), nullable=False), + sa.Column('advanced_settings', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('searchquery', + sa.Column('query_text', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=True), + sa.Column('filters_applied', sqlmodel.sql.sqltypes.AutoString(length=2000), nullable=True), + sa.Column('results_count', sa.Integer(), nullable=False), + sa.Column('response_time_ms', sa.Integer(), nullable=False), + sa.Column('user_clicked_result', sa.Boolean(), nullable=False), + sa.Column('relevance_feedback', sa.Float(), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('search_result_click', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('search_query_id', sa.Uuid(), nullable=False), + sa.Column('chunk_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('result_position', sa.Integer(), nullable=False), + sa.Column('similarity_score', sa.Float(), nullable=False), + sa.Column('rerank_score', sa.Float(), nullable=True), + sa.Column('time_spent_ms', sa.Integer(), nullable=True), + sa.Column('user_rating', sa.Integer(), nullable=True), + sa.Column('clicked_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['chunk_id'], ['document_chunk_enhanced.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['search_query_id'], ['searchquery.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('training_document_chunk_enhanced', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('training_document_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=4000), nullable=False), + sa.Column('chunk_index', sa.Integer(), nullable=False), + sa.Column('chunk_metadata', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=True), + sa.Column('semantic_metadata', sqlmodel.sql.sqltypes.AutoString(length=3000), nullable=True), + sa.Column('embedding_model', sqlmodel.sql.sqltypes.AutoString(length=100), nullable=False), + sa.Column('embedding_dimension', sa.Integer(), nullable=False), + sa.Column('training_importance', sa.Float(), nullable=True), + sa.Column('usage_count', sa.Integer(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('last_used', sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['training_document_id'], ['trainingdocument.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('training_document_chunk_enhanced') + op.drop_table('search_result_click') + op.drop_table('searchquery') + op.drop_table('rag_configuration') + op.drop_table('document_processing_log') + op.drop_table('document_chunk_enhanced') + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/add_user_ai_soul_interaction_tracking.py b/backend/app/alembic/versions/add_user_ai_soul_interaction_tracking.py new file mode 100644 index 0000000000..472ca298c9 --- /dev/null +++ b/backend/app/alembic/versions/add_user_ai_soul_interaction_tracking.py @@ -0,0 +1,41 @@ +"""add_user_ai_soul_interaction_tracking + +Revision ID: f1a2b3c4d5e6 +Revises: 28bdd6e65dbb +Create Date: 2025-01-10 12:00:00.000000 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = 'f1a2b3c4d5e6' +down_revision = '28bdd6e65dbb' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('user_ai_soul_interaction', + sa.Column('interaction_count', sa.Integer(), nullable=False), + sa.Column('last_interaction', sa.DateTime(), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('user_id', 'ai_soul_id', name='unique_user_ai_soul') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('user_ai_soul_interaction') + # ### end Alembic commands ### \ No newline at end of file diff --git a/backend/app/alembic/versions/b716a9118488_initial_schema.py b/backend/app/alembic/versions/b716a9118488_initial_schema.py new file mode 100644 index 0000000000..de1622944b --- /dev/null +++ b/backend/app/alembic/versions/b716a9118488_initial_schema.py @@ -0,0 +1,199 @@ +"""initial_schema + +Revision ID: b716a9118488 +Revises: +Create Date: 2025-07-05 17:20:34.922342 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = 'b716a9118488' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('user', + sa.Column('email', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.Column('is_superuser', sa.Boolean(), nullable=False), + sa.Column('full_name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('hashed_password', sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_user_email'), 'user', ['email'], unique=True) + op.create_table('aisoulentity', + sa.Column('name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=True), + sa.Column('persona_type', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('specializations', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False), + sa.Column('base_prompt', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=False), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.Column('last_used', sa.DateTime(), nullable=True), + sa.Column('interaction_count', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('document', + sa.Column('filename', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('original_filename', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('file_size', sa.Integer(), nullable=False), + sa.Column('content_type', sqlmodel.sql.sqltypes.AutoString(length=100), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('file_path', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False), + sa.Column('upload_timestamp', sa.DateTime(), nullable=False), + sa.Column('processing_status', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('chunk_count', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('item', + sa.Column('title', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('owner_id', sa.Uuid(), nullable=False), + sa.ForeignKeyConstraint(['owner_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('aisoulentityshare', + sa.Column('name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=True), + sa.Column('is_public', sa.Boolean(), nullable=False), + sa.Column('allow_anonymous', sa.Boolean(), nullable=False), + sa.Column('share_code', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('owner_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.Column('access_count', sa.Integer(), nullable=False), + sa.Column('last_accessed', sa.DateTime(), nullable=True), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['owner_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('share_code') + ) + op.create_table('chatmessage', + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('is_from_user', sa.Boolean(), nullable=False), + sa.Column('timestamp', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('documentchunk', + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=2000), nullable=False), + sa.Column('chunk_index', sa.Integer(), nullable=False), + sa.Column('chunk_metadata', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('document_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('embedding', sqlmodel.sql.sqltypes.AutoString(length=10000), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['document_id'], ['document.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('trainingdocument', + sa.Column('filename', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('original_filename', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('file_size', sa.Integer(), nullable=False), + sa.Column('content_type', sqlmodel.sql.sqltypes.AutoString(length=100), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('file_path', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False), + sa.Column('upload_timestamp', sa.DateTime(), nullable=False), + sa.Column('processing_status', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('chunk_count', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('trainingmessage', + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=False), + sa.Column('is_from_trainer', sa.Boolean(), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('timestamp', sa.DateTime(), nullable=False), + sa.Column('embedding', sqlmodel.sql.sqltypes.AutoString(length=10000), nullable=True), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('sharedchatsession', + sa.Column('session_name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=True), + sa.Column('visitor_identifier', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('share_id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('last_message_at', sa.DateTime(), nullable=False), + sa.Column('message_count', sa.Integer(), nullable=False), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.ForeignKeyConstraint(['share_id'], ['aisoulentityshare.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('trainingdocumentchunk', + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('training_document_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=2000), nullable=False), + sa.Column('chunk_index', sa.Integer(), nullable=False), + sa.Column('chunk_metadata', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=True), + sa.Column('embedding', sqlmodel.sql.sqltypes.AutoString(length=10000), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['training_document_id'], ['trainingdocument.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('sharedchatmessage', + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=False), + sa.Column('is_from_visitor', sa.Boolean(), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('session_id', sa.Uuid(), nullable=False), + sa.Column('timestamp', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['session_id'], ['sharedchatsession.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('sharedchatmessage') + op.drop_table('trainingdocumentchunk') + op.drop_table('sharedchatsession') + op.drop_table('trainingmessage') + op.drop_table('trainingdocument') + op.drop_table('documentchunk') + op.drop_table('chatmessage') + op.drop_table('aisoulentityshare') + op.drop_table('item') + op.drop_table('document') + op.drop_table('aisoulentity') + op.drop_index(op.f('ix_user_email'), table_name='user') + op.drop_table('user') + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/backup/0db8c0ab6f26_add_chat_message_table.py b/backend/app/alembic/versions/backup/0db8c0ab6f26_add_chat_message_table.py new file mode 100644 index 0000000000..6dece97c0b --- /dev/null +++ b/backend/app/alembic/versions/backup/0db8c0ab6f26_add_chat_message_table.py @@ -0,0 +1,37 @@ +"""add_chat_message_table + +Revision ID: 0db8c0ab6f26 +Revises: badd0344d461 +Create Date: 2025-07-04 11:33:33.013695 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = '0db8c0ab6f26' +down_revision = 'badd0344d461' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('chatmessage', + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=2000), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('is_from_user', sa.Boolean(), nullable=False), + sa.Column('timestamp', sqlmodel.sql.sqltypes.AutoString(), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('chatmessage') + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/1a31ce608336_add_cascade_delete_relationships.py b/backend/app/alembic/versions/backup/1a31ce608336_add_cascade_delete_relationships.py similarity index 100% rename from backend/app/alembic/versions/1a31ce608336_add_cascade_delete_relationships.py rename to backend/app/alembic/versions/backup/1a31ce608336_add_cascade_delete_relationships.py diff --git a/backend/app/alembic/versions/backup/6db2043f1466_add_document_and_chunk_tables.py b/backend/app/alembic/versions/backup/6db2043f1466_add_document_and_chunk_tables.py new file mode 100644 index 0000000000..7f66b4b801 --- /dev/null +++ b/backend/app/alembic/versions/backup/6db2043f1466_add_document_and_chunk_tables.py @@ -0,0 +1,58 @@ +"""add_document_and_chunk_tables + +Revision ID: 6db2043f1466 +Revises: add_training_models +Create Date: 2024-03-24 14:00:00.000000 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes +from sqlalchemy.dialects import postgresql + + +# revision identifiers, used by Alembic. +revision = '6db2043f1466' +down_revision = 'add_training_models' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('document', + sa.Column('filename', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('original_filename', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('file_size', sa.Integer(), nullable=False), + sa.Column('content_type', sqlmodel.sql.sqltypes.AutoString(length=100), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('file_path', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=False), + sa.Column('upload_timestamp', sa.DateTime(), nullable=False), + sa.Column('processing_status', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('chunk_count', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('documentchunk', + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=2000), nullable=False), + sa.Column('chunk_index', sa.Integer(), nullable=False), + sa.Column('chunk_metadata', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('document_id', sa.Uuid(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('embedding', sqlmodel.sql.sqltypes.AutoString(length=10000), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['document_id'], ['document.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('documentchunk') + op.drop_table('document') + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/backup/761fc0db81d3_update_chat_message_timestamp_type.py b/backend/app/alembic/versions/backup/761fc0db81d3_update_chat_message_timestamp_type.py new file mode 100644 index 0000000000..d841287673 --- /dev/null +++ b/backend/app/alembic/versions/backup/761fc0db81d3_update_chat_message_timestamp_type.py @@ -0,0 +1,33 @@ +"""update_chat_message_timestamp_type + +Revision ID: 761fc0db81d3 +Revises: 0db8c0ab6f26 +Create Date: 2025-07-04 11:34:04.180039 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = '761fc0db81d3' +down_revision = '0db8c0ab6f26' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + # Drop the column first and then recreate it with the correct type + op.drop_column('chatmessage', 'timestamp') + op.add_column('chatmessage', sa.Column('timestamp', sa.DateTime(), nullable=False)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + # Drop the column first and then recreate it with the previous type + op.drop_column('chatmessage', 'timestamp') + op.add_column('chatmessage', sa.Column('timestamp', sa.VARCHAR(), nullable=False)) + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/backup/7c3ae6534636_increase_chat_message_content_length.py b/backend/app/alembic/versions/backup/7c3ae6534636_increase_chat_message_content_length.py new file mode 100644 index 0000000000..62f9429202 --- /dev/null +++ b/backend/app/alembic/versions/backup/7c3ae6534636_increase_chat_message_content_length.py @@ -0,0 +1,35 @@ +"""increase_chat_message_content_length + +Revision ID: 7c3ae6534636 +Revises: 761fc0db81d3 +Create Date: 2025-07-04 12:17:33.100203 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = '7c3ae6534636' +down_revision = '761fc0db81d3' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('chatmessage', 'content', + existing_type=sa.VARCHAR(length=2000), + type_=sqlmodel.sql.sqltypes.AutoString(length=5000), + existing_nullable=False) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('chatmessage', 'content', + existing_type=sqlmodel.sql.sqltypes.AutoString(length=5000), + type_=sa.VARCHAR(length=2000), + existing_nullable=False) + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/9c0a54914c78_add_max_length_for_string_varchar_.py b/backend/app/alembic/versions/backup/9c0a54914c78_add_max_length_for_string_varchar_.py similarity index 100% rename from backend/app/alembic/versions/9c0a54914c78_add_max_length_for_string_varchar_.py rename to backend/app/alembic/versions/backup/9c0a54914c78_add_max_length_for_string_varchar_.py diff --git a/backend/app/alembic/versions/backup/add_ai_soul_entity_models.py b/backend/app/alembic/versions/backup/add_ai_soul_entity_models.py new file mode 100644 index 0000000000..e5f3a9b3c8 --- /dev/null +++ b/backend/app/alembic/versions/backup/add_ai_soul_entity_models.py @@ -0,0 +1,89 @@ +"""add_ai_soul_entity_models + +Revision ID: add_ai_soul_entity_models +Revises: add_timestamps_to_user +Create Date: 2024-03-24 12:00:00.000000 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import sqlmodel +from sqlalchemy.dialects import postgresql +from datetime import datetime +import uuid +import bcrypt + + +# revision identifiers, used by Alembic. +revision: str = 'add_ai_soul_entity_models' +down_revision: Union[str, None] = 'add_timestamps_to_user' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # Create AI Soul Entity table + op.create_table( + 'aisoulentity', + sa.Column('id', postgresql.UUID(), nullable=False), + sa.Column('name', sa.String(length=255), nullable=False), + sa.Column('description', sa.String(length=1000), nullable=True), + sa.Column('persona_type', sa.String(length=50), nullable=False), + sa.Column('specializations', sa.String(length=500), nullable=False), + sa.Column('base_prompt', sa.String(length=5000), nullable=False), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.Column('last_used', sa.DateTime(), nullable=True), + sa.Column('interaction_count', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + + # Create default AI Soul for existing chat messages + default_user_id = uuid.uuid4() + hashed_password = bcrypt.hashpw('password'.encode(), bcrypt.gensalt()).decode() + + # Create default user if not exists + op.execute(f""" + INSERT INTO "user" ( + id, email, hashed_password, is_active, is_superuser, created_at, updated_at + ) VALUES ( + '{default_user_id}', + 'admin@example.com', + '{hashed_password}', + true, + true, + NOW(), + NOW() + ) + ON CONFLICT (email) DO NOTHING + """) + + # Get the user ID (either the one we just created or the existing one) + op.execute(""" + INSERT INTO aisoulentity ( + id, name, description, persona_type, specializations, base_prompt, + is_active, user_id, created_at, updated_at, interaction_count + ) VALUES ( + '00000000-0000-0000-0000-000000000000', + 'Default AI Soul', + 'Default AI Soul for existing chat messages', + 'default', + 'general', + 'You are a helpful AI assistant.', + true, + (SELECT id FROM "user" WHERE email = 'admin@example.com' LIMIT 1), + NOW(), + NOW(), + 0 + ) + """) + + +def downgrade() -> None: + # Drop AI Soul Entity table + op.drop_table('aisoulentity') \ No newline at end of file diff --git a/backend/app/alembic/versions/backup/add_timestamps_to_user.py b/backend/app/alembic/versions/backup/add_timestamps_to_user.py new file mode 100644 index 0000000000..57d4df3919 --- /dev/null +++ b/backend/app/alembic/versions/backup/add_timestamps_to_user.py @@ -0,0 +1,41 @@ +"""add_timestamps_to_user + +Revision ID: add_timestamps_to_user +Revises: d98dd8ec85a3 +Create Date: 2024-03-24 12:00:00.000000 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +from datetime import datetime + +# revision identifiers, used by Alembic. +revision: str = 'add_timestamps_to_user' +down_revision: Union[str, None] = 'd98dd8ec85a3' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # Add created_at and updated_at columns to user table + op.add_column('user', sa.Column('created_at', sa.DateTime(), nullable=True)) + op.add_column('user', sa.Column('updated_at', sa.DateTime(), nullable=True)) + + # Set default values for existing rows + op.execute(""" + UPDATE "user" + SET created_at = NOW(), + updated_at = NOW() + """) + + # Make the columns non-nullable + op.alter_column('user', 'created_at', nullable=False) + op.alter_column('user', 'updated_at', nullable=False) + + +def downgrade() -> None: + # Remove created_at and updated_at columns from user table + op.drop_column('user', 'created_at') + op.drop_column('user', 'updated_at') \ No newline at end of file diff --git a/backend/app/alembic/versions/backup/add_training_models.py b/backend/app/alembic/versions/backup/add_training_models.py new file mode 100644 index 0000000000..f2bf6d48f8 --- /dev/null +++ b/backend/app/alembic/versions/backup/add_training_models.py @@ -0,0 +1,82 @@ +"""add_training_models + +Revision ID: add_training_models +Revises: add_ai_soul_entity_models +Create Date: 2024-03-24 13:00:00.000000 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import sqlmodel +from sqlalchemy.dialects import postgresql + + +# revision identifiers, used by Alembic. +revision: str = 'add_training_models' +down_revision: Union[str, None] = 'add_ai_soul_entity_models' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # Create TrainingMessage table + op.create_table( + 'trainingmessage', + sa.Column('id', postgresql.UUID(), nullable=False), + sa.Column('content', sa.String(length=5000), nullable=False), + sa.Column('is_from_trainer', sa.Boolean(), nullable=False), + sa.Column('ai_soul_id', postgresql.UUID(), nullable=False), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('timestamp', sa.DateTime(), nullable=False), + sa.Column('embedding', sa.String(length=10000), nullable=True), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + + # Create TrainingDocument table + op.create_table( + 'trainingdocument', + sa.Column('id', postgresql.UUID(), nullable=False), + sa.Column('filename', sa.String(length=255), nullable=False), + sa.Column('original_filename', sa.String(length=255), nullable=False), + sa.Column('file_size', sa.Integer(), nullable=False), + sa.Column('content_type', sa.String(length=100), nullable=False), + sa.Column('description', sa.String(length=500), nullable=True), + sa.Column('ai_soul_id', postgresql.UUID(), nullable=False), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('file_path', sa.String(length=500), nullable=False), + sa.Column('upload_timestamp', sa.DateTime(), nullable=False), + sa.Column('processing_status', sa.String(length=50), nullable=False), + sa.Column('chunk_count', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + + # Create TrainingDocumentChunk table + op.create_table( + 'trainingdocumentchunk', + sa.Column('id', postgresql.UUID(), nullable=False), + sa.Column('training_document_id', postgresql.UUID(), nullable=False), + sa.Column('ai_soul_id', postgresql.UUID(), nullable=False), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('content', sa.String(length=2000), nullable=False), + sa.Column('chunk_index', sa.Integer(), nullable=False), + sa.Column('chunk_metadata', sa.String(length=1000), nullable=True), + sa.Column('embedding', sa.String(length=10000), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['training_document_id'], ['trainingdocument.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + + +def downgrade() -> None: + # Drop tables in reverse order + op.drop_table('trainingdocumentchunk') + op.drop_table('trainingdocument') + op.drop_table('trainingmessage') \ No newline at end of file diff --git a/backend/app/alembic/versions/backup/add_uuid_extension.py b/backend/app/alembic/versions/backup/add_uuid_extension.py new file mode 100644 index 0000000000..6650398f4b --- /dev/null +++ b/backend/app/alembic/versions/backup/add_uuid_extension.py @@ -0,0 +1,27 @@ +"""add_uuid_extension + +Revision ID: add_uuid_extension +Revises: e2412789c190 +Create Date: 2024-03-24 10:00:00.000000 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision: str = 'add_uuid_extension' +down_revision: Union[str, None] = 'e2412789c190' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # Add uuid-ossp extension + op.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"') + + +def downgrade() -> None: + # Remove uuid-ossp extension + op.execute('DROP EXTENSION IF EXISTS "uuid-ossp"') \ No newline at end of file diff --git a/backend/app/alembic/versions/backup/b10ccce35e94_merge_all_heads.py b/backend/app/alembic/versions/backup/b10ccce35e94_merge_all_heads.py new file mode 100644 index 0000000000..677c37d949 --- /dev/null +++ b/backend/app/alembic/versions/backup/b10ccce35e94_merge_all_heads.py @@ -0,0 +1,25 @@ +"""merge_all_heads + +Revision ID: b10ccce35e94 +Revises: 1a31ce608336, 6db2043f1466, 7c3ae6534636, 9c0a54914c78 +Create Date: 2025-07-05 17:14:31.891148 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = 'b10ccce35e94' +down_revision = ('1a31ce608336', '6db2043f1466', '7c3ae6534636', '9c0a54914c78') +branch_labels = None +depends_on = None + + +def upgrade(): + pass + + +def downgrade(): + pass diff --git a/backend/app/alembic/versions/backup/badd0344d461_add_sharing_tables.py b/backend/app/alembic/versions/backup/badd0344d461_add_sharing_tables.py new file mode 100644 index 0000000000..433fc59966 --- /dev/null +++ b/backend/app/alembic/versions/backup/badd0344d461_add_sharing_tables.py @@ -0,0 +1,70 @@ +"""add_sharing_tables + +Revision ID: badd0344d461 +Revises: add_ai_soul_entity_models +Create Date: 2025-07-04 12:35:25.858894 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = 'badd0344d461' +down_revision = 'add_ai_soul_entity_models' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('aisoulentityshare', + sa.Column('name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=1000), nullable=True), + sa.Column('is_public', sa.Boolean(), nullable=False), + sa.Column('allow_anonymous', sa.Boolean(), nullable=False), + sa.Column('share_code', sqlmodel.sql.sqltypes.AutoString(length=50), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('owner_id', sa.Uuid(), nullable=False), + sa.Column('ai_soul_id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.Column('access_count', sa.Integer(), nullable=False), + sa.Column('last_accessed', sa.DateTime(), nullable=True), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.ForeignKeyConstraint(['owner_id'], ['user.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['ai_soul_id'], ['aisoulentity.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('share_code') + ) + op.create_table('sharedchatsession', + sa.Column('session_name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=True), + sa.Column('visitor_identifier', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('share_id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('last_message_at', sa.DateTime(), nullable=False), + sa.Column('message_count', sa.Integer(), nullable=False), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.ForeignKeyConstraint(['share_id'], ['aisoulentityshare.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('sharedchatmessage', + sa.Column('content', sqlmodel.sql.sqltypes.AutoString(length=5000), nullable=False), + sa.Column('is_from_visitor', sa.Boolean(), nullable=False), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('session_id', sa.Uuid(), nullable=False), + sa.Column('timestamp', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['session_id'], ['sharedchatsession.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('sharedchatmessage') + op.drop_table('sharedchatsession') + op.drop_table('aisoulentityshare') + # ### end Alembic commands ### diff --git a/backend/app/alembic/versions/backup/d98dd8ec85a3_edit_replace_id_integers_in_all_models_.py b/backend/app/alembic/versions/backup/d98dd8ec85a3_edit_replace_id_integers_in_all_models_.py new file mode 100755 index 0000000000..97e83547db --- /dev/null +++ b/backend/app/alembic/versions/backup/d98dd8ec85a3_edit_replace_id_integers_in_all_models_.py @@ -0,0 +1,55 @@ +"""edit_replace_id_integers_in_all_models + +Revision ID: d98dd8ec85a3 +Revises: add_uuid_extension +Create Date: 2024-03-24 11:00:00.000000 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision: str = 'd98dd8ec85a3' +down_revision: Union[str, None] = 'add_uuid_extension' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # Temporarily drop foreign key constraints + op.drop_constraint('item_owner_id_fkey', 'item', type_='foreignkey') + + # Alter user table + op.alter_column('user', 'id', + type_=postgresql.UUID(), + postgresql_using='uuid_generate_v4()', + existing_type=sa.Integer(), + nullable=False) + + # Alter item table + op.alter_column('item', 'id', + type_=postgresql.UUID(), + postgresql_using='uuid_generate_v4()', + existing_type=sa.Integer(), + nullable=False) + op.alter_column('item', 'owner_id', + type_=postgresql.UUID(), + postgresql_using='uuid_generate_v4()', + existing_type=sa.Integer(), + nullable=False) + + # Recreate foreign key constraints with UUID types + op.create_foreign_key( + 'item_owner_id_fkey', + 'item', 'user', + ['owner_id'], ['id'], + ondelete='CASCADE' + ) + + +def downgrade() -> None: + # This is a one-way migration - downgrade would lose data + raise Exception("Downgrade not supported for UUID conversion") diff --git a/backend/app/alembic/versions/e2412789c190_initialize_models.py b/backend/app/alembic/versions/backup/e2412789c190_initialize_models.py similarity index 100% rename from backend/app/alembic/versions/e2412789c190_initialize_models.py rename to backend/app/alembic/versions/backup/e2412789c190_initialize_models.py diff --git a/backend/app/alembic/versions/d98dd8ec85a3_edit_replace_id_integers_in_all_models_.py b/backend/app/alembic/versions/d98dd8ec85a3_edit_replace_id_integers_in_all_models_.py deleted file mode 100755 index 37af1fa215..0000000000 --- a/backend/app/alembic/versions/d98dd8ec85a3_edit_replace_id_integers_in_all_models_.py +++ /dev/null @@ -1,90 +0,0 @@ -"""Edit replace id integers in all models to use UUID instead - -Revision ID: d98dd8ec85a3 -Revises: 9c0a54914c78 -Create Date: 2024-07-19 04:08:04.000976 - -""" -from alembic import op -import sqlalchemy as sa -import sqlmodel.sql.sqltypes -from sqlalchemy.dialects import postgresql - - -# revision identifiers, used by Alembic. -revision = 'd98dd8ec85a3' -down_revision = '9c0a54914c78' -branch_labels = None -depends_on = None - - -def upgrade(): - # Ensure uuid-ossp extension is available - op.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"') - - # Create a new UUID column with a default UUID value - op.add_column('user', sa.Column('new_id', postgresql.UUID(as_uuid=True), default=sa.text('uuid_generate_v4()'))) - op.add_column('item', sa.Column('new_id', postgresql.UUID(as_uuid=True), default=sa.text('uuid_generate_v4()'))) - op.add_column('item', sa.Column('new_owner_id', postgresql.UUID(as_uuid=True), nullable=True)) - - # Populate the new columns with UUIDs - op.execute('UPDATE "user" SET new_id = uuid_generate_v4()') - op.execute('UPDATE item SET new_id = uuid_generate_v4()') - op.execute('UPDATE item SET new_owner_id = (SELECT new_id FROM "user" WHERE "user".id = item.owner_id)') - - # Set the new_id as not nullable - op.alter_column('user', 'new_id', nullable=False) - op.alter_column('item', 'new_id', nullable=False) - - # Drop old columns and rename new columns - op.drop_constraint('item_owner_id_fkey', 'item', type_='foreignkey') - op.drop_column('item', 'owner_id') - op.alter_column('item', 'new_owner_id', new_column_name='owner_id') - - op.drop_column('user', 'id') - op.alter_column('user', 'new_id', new_column_name='id') - - op.drop_column('item', 'id') - op.alter_column('item', 'new_id', new_column_name='id') - - # Create primary key constraint - op.create_primary_key('user_pkey', 'user', ['id']) - op.create_primary_key('item_pkey', 'item', ['id']) - - # Recreate foreign key constraint - op.create_foreign_key('item_owner_id_fkey', 'item', 'user', ['owner_id'], ['id']) - -def downgrade(): - # Reverse the upgrade process - op.add_column('user', sa.Column('old_id', sa.Integer, autoincrement=True)) - op.add_column('item', sa.Column('old_id', sa.Integer, autoincrement=True)) - op.add_column('item', sa.Column('old_owner_id', sa.Integer, nullable=True)) - - # Populate the old columns with default values - # Generate sequences for the integer IDs if not exist - op.execute('CREATE SEQUENCE IF NOT EXISTS user_id_seq AS INTEGER OWNED BY "user".old_id') - op.execute('CREATE SEQUENCE IF NOT EXISTS item_id_seq AS INTEGER OWNED BY item.old_id') - - op.execute('SELECT setval(\'user_id_seq\', COALESCE((SELECT MAX(old_id) + 1 FROM "user"), 1), false)') - op.execute('SELECT setval(\'item_id_seq\', COALESCE((SELECT MAX(old_id) + 1 FROM item), 1), false)') - - op.execute('UPDATE "user" SET old_id = nextval(\'user_id_seq\')') - op.execute('UPDATE item SET old_id = nextval(\'item_id_seq\'), old_owner_id = (SELECT old_id FROM "user" WHERE "user".id = item.owner_id)') - - # Drop new columns and rename old columns back - op.drop_constraint('item_owner_id_fkey', 'item', type_='foreignkey') - op.drop_column('item', 'owner_id') - op.alter_column('item', 'old_owner_id', new_column_name='owner_id') - - op.drop_column('user', 'id') - op.alter_column('user', 'old_id', new_column_name='id') - - op.drop_column('item', 'id') - op.alter_column('item', 'old_id', new_column_name='id') - - # Create primary key constraint - op.create_primary_key('user_pkey', 'user', ['id']) - op.create_primary_key('item_pkey', 'item', ['id']) - - # Recreate foreign key constraint - op.create_foreign_key('item_owner_id_fkey', 'item', 'user', ['owner_id'], ['id']) diff --git a/backend/app/api/deps.py b/backend/app/api/deps.py index c2b83c841d..026495c68b 100644 --- a/backend/app/api/deps.py +++ b/backend/app/api/deps.py @@ -1,17 +1,25 @@ from collections.abc import Generator from typing import Annotated +from enum import Enum import jwt from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from jwt.exceptions import InvalidTokenError from pydantic import ValidationError -from sqlmodel import Session +from sqlmodel import Session, select from app.core import security from app.core.config import settings from app.core.db import engine -from app.models import TokenPayload, User +from app.models import Counselor, TokenPayload, User + +class UserRole(str, Enum): + USER = "user" + TRAINER = "trainer" + COUNSELOR = "counselor" + ADMIN = "admin" + SUPER_ADMIN = "super_admin" reusable_oauth2 = OAuth2PasswordBearer( tokenUrl=f"{settings.API_V1_STR}/login/access-token" @@ -49,9 +57,120 @@ def get_current_user(session: SessionDep, token: TokenDep) -> User: CurrentUser = Annotated[User, Depends(get_current_user)] +def get_user_role(user: User) -> UserRole: + """Get user role based on current user data.""" + # Check explicit role field first + if user.role: + role_lower = user.role.lower() + if role_lower in ["admin", "super_admin"] or user.is_superuser: + return UserRole.ADMIN + elif role_lower == "counselor": + return UserRole.COUNSELOR + elif role_lower == "trainer": + return UserRole.TRAINER + elif role_lower == "user": + return UserRole.USER + + # Fallback to is_superuser for backwards compatibility + if user.is_superuser: + return UserRole.ADMIN + + return UserRole.USER + + def get_current_active_superuser(current_user: CurrentUser) -> User: if not current_user.is_superuser: raise HTTPException( status_code=403, detail="The user doesn't have enough privileges" ) return current_user + + +def get_current_active_user(current_user: CurrentUser) -> User: + if not current_user.is_active: + raise HTTPException( + status_code=400, + detail="Inactive user" + ) + return current_user + + +def get_current_admin(current_user: CurrentUser) -> User: + """Check if current user is an admin.""" + if get_user_role(current_user) != UserRole.ADMIN: + raise HTTPException( + status_code=403, + detail="Admin privileges required" + ) + return current_user + + +def get_current_trainer_or_admin(current_user: CurrentUser) -> User: + """Check if current user is a trainer or admin.""" + role = get_user_role(current_user) + if role not in [UserRole.TRAINER, UserRole.ADMIN]: + raise HTTPException( + status_code=403, + detail="Trainer or admin privileges required" + ) + return current_user + + +# Dependency annotations for common use cases +CurrentAdmin = Annotated[User, Depends(get_current_admin)] +CurrentTrainerOrAdmin = Annotated[User, Depends(get_current_trainer_or_admin)] +CurrentActiveUser = Annotated[User, Depends(get_current_active_user)] + +async def get_current_counselor_or_admin( + current_user: CurrentActiveUser, + db: SessionDep, +) -> User: + """ + Get current user if they are a counselor or admin. + + This function checks: + 1. If user has admin role or is_superuser -> allow access + 2. If user has counselor role -> check if counselor record exists + 3. If user has counselor record but no role -> update role and allow access + """ + role = get_user_role(current_user) + + # Admin users always have access + if role == UserRole.ADMIN or current_user.is_superuser: + return current_user + + # Check if user has counselor role + if role == UserRole.COUNSELOR: + # Verify counselor record exists + counselor = db.exec( + select(Counselor).where(Counselor.user_id == current_user.id) + ).first() + + if counselor: + return current_user + else: + # User has counselor role but no counselor record + raise HTTPException( + status_code=403, + detail="Counselor role detected but no counselor profile found. Please contact administrator." + ) + + # Check if user has counselor record but wrong role (legacy data) + counselor = db.exec( + select(Counselor).where(Counselor.user_id == current_user.id) + ).first() + + if counselor: + # User has counselor record but wrong role - fix it + current_user.role = "counselor" + db.add(current_user) + db.commit() + return current_user + + # User is neither admin nor counselor + raise HTTPException( + status_code=403, + detail="Access denied. Counselor or administrator privileges required." + ) + +CurrentCounselorOrAdmin = Annotated[User, Depends(get_current_counselor_or_admin)] diff --git a/backend/app/api/main.py b/backend/app/api/main.py index eac18c8e8f..27d3859b2f 100644 --- a/backend/app/api/main.py +++ b/backend/app/api/main.py @@ -1,14 +1,32 @@ from fastapi import APIRouter -from app.api.routes import items, login, private, users, utils +from app.api.routes import ( + ai_souls, + chat, + counselor, + documents, + enhanced_rag, + items, + login, + private, + training, + users, + utils, +) from app.core.config import settings api_router = APIRouter() -api_router.include_router(login.router) -api_router.include_router(users.router) -api_router.include_router(utils.router) -api_router.include_router(items.router) - +api_router.include_router(login.router, tags=["login"]) +api_router.include_router(users.router, prefix="/users", tags=["users"]) +api_router.include_router(utils.router, prefix="/utils", tags=["utils"]) +api_router.include_router(items.router, prefix="/items", tags=["items"]) +api_router.include_router(private.router, prefix="/private", tags=["private"]) +api_router.include_router(ai_souls.router, prefix="/ai-souls", tags=["ai-souls"]) +api_router.include_router(chat.router, prefix="/chat", tags=["chat"]) +api_router.include_router(counselor.router, prefix="/counselor", tags=["counselor"]) +api_router.include_router(documents.router, prefix="/documents", tags=["documents"]) +api_router.include_router(training.router, prefix="/training", tags=["training"]) +api_router.include_router(enhanced_rag.router, prefix="/rag", tags=["enhanced-rag"]) if settings.ENVIRONMENT == "local": api_router.include_router(private.router) diff --git a/backend/app/api/routes/__init__.py b/backend/app/api/routes/__init__.py index e69de29bb2..9899e292c9 100644 --- a/backend/app/api/routes/__init__.py +++ b/backend/app/api/routes/__init__.py @@ -0,0 +1,26 @@ +from fastapi import APIRouter + +from app.api.routes import ( + ai_souls, + chat, + documents, + enhanced_rag, + items, + login, + private, + training, + users, + utils, +) + +api_router = APIRouter() +api_router.include_router(login.router, tags=["login"]) +api_router.include_router(users.router, prefix="/users", tags=["users"]) +api_router.include_router(utils.router, prefix="/utils", tags=["utils"]) +api_router.include_router(items.router, prefix="/items", tags=["items"]) +api_router.include_router(private.router, prefix="/private", tags=["private"]) +api_router.include_router(chat.router, prefix="/chat", tags=["chat"]) +api_router.include_router(documents.router, prefix="/documents", tags=["documents"]) +api_router.include_router(ai_souls.router, prefix="/ai-souls", tags=["ai-souls"]) +api_router.include_router(enhanced_rag.router, prefix="/rag", tags=["enhanced-rag"]) +api_router.include_router(training.router, prefix="/training", tags=["training"]) diff --git a/backend/app/api/routes/ai_souls.py b/backend/app/api/routes/ai_souls.py new file mode 100644 index 0000000000..f5a5118894 --- /dev/null +++ b/backend/app/api/routes/ai_souls.py @@ -0,0 +1,196 @@ +from uuid import UUID + +from fastapi import APIRouter, Depends, HTTPException +from sqlmodel import Session, select + +from app.api.deps import ( + CurrentActiveUser, + CurrentTrainerOrAdmin, + CurrentAdmin, + SessionDep, + get_user_role, + UserRole, +) +from app.models import ( + AISoulEntity, + AISoulEntityCreate, + AISoulEntityPublic, + AISoulEntityUpdate, + AISoulEntityWithUserInteraction, + UserAISoulInteraction, +) + +router = APIRouter() + + +@router.post("/", response_model=AISoulEntityPublic) +def create_ai_soul( + *, + db: SessionDep, + current_user: CurrentTrainerOrAdmin, + ai_soul_create: AISoulEntityCreate, +) -> AISoulEntity: + """ + Create a new AI soul. + Only trainers and admins can create souls. + """ + ai_soul = AISoulEntity( + **ai_soul_create.dict(), + user_id=current_user.id, + ) + db.add(ai_soul) + db.commit() + db.refresh(ai_soul) + return ai_soul + + +@router.get("/", response_model=list[AISoulEntityWithUserInteraction]) +def get_ai_souls( + *, + db: SessionDep, + current_user: CurrentActiveUser, + skip: int = 0, + limit: int = 100, +) -> list[AISoulEntityWithUserInteraction]: + """ + Get all AI souls with role-based interaction counts. + Regular users see their own interaction counts. + Admins and counselors see global interaction counts. + """ + statement = select(AISoulEntity).offset(skip).limit(limit) + ai_souls = db.exec(statement).all() + + user_role = get_user_role(current_user) + is_admin_or_counselor = user_role in [UserRole.ADMIN, UserRole.COUNSELOR] + + result = [] + for soul in ai_souls: + if is_admin_or_counselor: + # Show global interaction count for admins and counselors + interaction_count = soul.interaction_count + else: + # Show user-specific interaction count for regular users + user_interaction = db.exec( + select(UserAISoulInteraction).where( + UserAISoulInteraction.user_id == current_user.id, + UserAISoulInteraction.ai_soul_id == soul.id + ) + ).first() + interaction_count = user_interaction.interaction_count if user_interaction else 0 + + soul_response = AISoulEntityWithUserInteraction( + id=soul.id, + name=soul.name, + description=soul.description, + persona_type=soul.persona_type, + specializations=soul.specializations, + base_prompt=soul.base_prompt, + is_active=soul.is_active, + user_id=soul.user_id, + created_at=soul.created_at, + updated_at=soul.updated_at, + last_used=soul.last_used, + interaction_count=interaction_count + ) + result.append(soul_response) + + return result + + +@router.get("/{ai_soul_id}", response_model=AISoulEntityWithUserInteraction) +def get_ai_soul( + *, + db: SessionDep, + current_user: CurrentActiveUser, + ai_soul_id: UUID, +) -> AISoulEntityWithUserInteraction: + """ + Get a specific AI soul by ID with role-based interaction count. + Regular users see their own interaction count. + Admins and counselors see global interaction count. + """ + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + user_role = get_user_role(current_user) + is_admin_or_counselor = user_role in [UserRole.ADMIN, UserRole.COUNSELOR] + + if is_admin_or_counselor: + # Show global interaction count for admins and counselors + interaction_count = ai_soul.interaction_count + else: + # Show user-specific interaction count for regular users + user_interaction = db.exec( + select(UserAISoulInteraction).where( + UserAISoulInteraction.user_id == current_user.id, + UserAISoulInteraction.ai_soul_id == ai_soul.id + ) + ).first() + interaction_count = user_interaction.interaction_count if user_interaction else 0 + + return AISoulEntityWithUserInteraction( + id=ai_soul.id, + name=ai_soul.name, + description=ai_soul.description, + persona_type=ai_soul.persona_type, + specializations=ai_soul.specializations, + base_prompt=ai_soul.base_prompt, + is_active=ai_soul.is_active, + user_id=ai_soul.user_id, + created_at=ai_soul.created_at, + updated_at=ai_soul.updated_at, + last_used=ai_soul.last_used, + interaction_count=interaction_count + ) + + +@router.put("/{ai_soul_id}", response_model=AISoulEntity) +def update_ai_soul( + *, + db: SessionDep, + current_user: CurrentTrainerOrAdmin, + ai_soul_id: UUID, + ai_soul_update: AISoulEntityUpdate, +) -> AISoulEntity: + """ + Update a specific AI soul. + Only trainers and admins can update souls. + """ + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + # Only allow admins to edit any soul, trainers can only edit their own + user_role = get_user_role(current_user) + if user_role == UserRole.TRAINER and ai_soul.user_id != current_user.id: + raise HTTPException(status_code=403, detail="Not enough permissions") + + # Update fields + for field, value in ai_soul_update.dict(exclude_unset=True).items(): + if field != "user_id": # Prevent changing the owner + setattr(ai_soul, field, value) + + db.add(ai_soul) + db.commit() + db.refresh(ai_soul) + return ai_soul + + +@router.delete("/{ai_soul_id}") +def delete_ai_soul( + *, + db: SessionDep, + current_user: CurrentAdmin, + ai_soul_id: UUID, +) -> None: + """ + Delete a specific AI soul. + Only admins can delete souls. + """ + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + db.delete(ai_soul) + db.commit() diff --git a/backend/app/api/routes/chat.py b/backend/app/api/routes/chat.py new file mode 100644 index 0000000000..8cef5148fc --- /dev/null +++ b/backend/app/api/routes/chat.py @@ -0,0 +1,311 @@ +from uuid import UUID +import uuid +from datetime import datetime +import logging + +from fastapi import APIRouter, Depends, HTTPException +from sqlmodel import Session, select, SQLModel + +logger = logging.getLogger(__name__) + +from app.api.deps import ( + CurrentActiveUser, + SessionDep, +) +from app.models import ( + AISoulEntity, + ChatMessage, + ChatMessageCreate, + ChatMessagePublic, + User, + UserAISoulInteraction, +) +from app.services.ai_soul_service import AISoulService +from app.services.content_filter_service import ContentFilterService +from app.services.risk_assessment_service import RiskAssessmentService +from app.services.counselor_service import CounselorService + +router = APIRouter() + + +class ChatMessagePairResponse(SQLModel): + """Response model for chat message creation containing both user and AI messages""" + user_message: ChatMessagePublic + ai_message: ChatMessagePublic + +@router.post("/{ai_soul_id}/messages", response_model=ChatMessagePairResponse) +async def create_chat_message( + *, + db: SessionDep, + current_user: CurrentActiveUser, + ai_soul_id: UUID, + message_in: ChatMessageCreate, +) -> ChatMessagePairResponse: + """ + Create a new chat message and get AI response with counselor override system. + Any user can chat with any AI soul. + Returns both user message and AI response to prevent message stacking. + """ + # Verify AI soul exists + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + # Check if user has any pending messages under review for this AI soul + from app.models import PendingResponse + pending_statement = ( + select(PendingResponse) + .where( + PendingResponse.user_id == current_user.id, + PendingResponse.ai_soul_id == ai_soul_id, + PendingResponse.status == "pending" + ) + ) + pending_responses = db.exec(pending_statement).all() + + if pending_responses: + raise HTTPException( + status_code=429, + detail="You have messages under review. Please wait for counselor approval before sending new messages." + ) + + # Analyze content for safety and risk assessment + content_filter = ContentFilterService() + content_analysis = await content_filter.analyze_content(message_in.content) + + # Only block content that is truly inappropriate (not crisis-related) + # Crisis-related content should go through risk assessment and counselor review + if (content_analysis.get("flagged") and + "sexual" in content_analysis.get("categories", []) and + content_analysis.get("severity") in ["high", "critical"]): + raise HTTPException( + status_code=400, + detail="Message content violates content safety guidelines", + ) + + # Save user message + user_message = ChatMessage( + content=message_in.content, + user_id=current_user.id, + ai_soul_id=ai_soul_id, + is_from_user=True, + ) + db.add(user_message) + + # Increment global interaction count for this AI soul + ai_soul.interaction_count += 1 + db.add(ai_soul) + + # Update user-specific interaction tracking + user_interaction = db.exec( + select(UserAISoulInteraction).where( + UserAISoulInteraction.user_id == current_user.id, + UserAISoulInteraction.ai_soul_id == ai_soul_id + ) + ).first() + + if user_interaction: + user_interaction.interaction_count += 1 + user_interaction.last_interaction = datetime.utcnow() + user_interaction.updated_at = datetime.utcnow() + else: + user_interaction = UserAISoulInteraction( + user_id=current_user.id, + ai_soul_id=ai_soul_id, + interaction_count=1, + last_interaction=datetime.utcnow() + ) + db.add(user_interaction) + + db.commit() + db.refresh(user_message) + + # Perform risk assessment on user message + risk_service = RiskAssessmentService() + risk_assessment = await risk_service.assess_message_risk( + session=db, + user_message=message_in.content, + user_id=str(current_user.id), + ai_soul_id=str(ai_soul_id), + chat_message_id=str(user_message.id), + organization_id=str(current_user.organization_id) if current_user.organization_id else None, + content_analysis=content_analysis + ) + + # Debug logging for risk assessment + logger.info(f"Risk assessment for message '{message_in.content}': {risk_assessment}") + + # Check if counselor review is required - if so, block all responses until approved + if risk_assessment.get("requires_human_review", False): + logger.info(f"Message requires human review - creating temporary response") + + # Create pending response for counselor review first + counselor_service = CounselorService(db) + + # Generate AI response for counselor review but don't send to user + ai_service = AISoulService() + ai_response = await ai_service.generate_ai_response( + db, + str(current_user.id), + str(ai_soul_id), + message_in.content, + risk_assessment + ) + + # Create pending response for counselor review - no message sent to user yet + pending_response = await counselor_service.create_pending_response( + chat_message_id=str(user_message.id), + risk_assessment_id=risk_assessment["assessment_id"], + user_id=str(current_user.id), + ai_soul_id=str(ai_soul_id), + original_message=message_in.content, + ai_response=ai_response, # AI response for counselor to review + organization_id=str(current_user.organization_id) if current_user.organization_id else None + ) + + # Return user message with a temporary AI response indicating review is in progress + # This message is NOT saved to database - it's just for UI feedback + review_message = "Your message is being reviewed by a specialist. You will receive a response shortly." + + # Add crisis resources if needed + crisis_resources = risk_assessment.get("crisis_resources", []) + if crisis_resources: + review_message += "\n\n⚠️ If you need immediate assistance:\n" + "\n".join(crisis_resources) + + return ChatMessagePairResponse( + user_message=ChatMessagePublic( + id=user_message.id, + content=user_message.content, + user_id=user_message.user_id, + ai_soul_id=user_message.ai_soul_id, + is_from_user=user_message.is_from_user, + timestamp=user_message.timestamp, + is_temporary=False + ), + ai_message=ChatMessagePublic( + id=uuid.uuid4(), # Generate temporary UUID - this message is not saved to database + content=review_message, + user_id=user_message.user_id, + ai_soul_id=user_message.ai_soul_id, + is_from_user=False, + timestamp=user_message.timestamp, + is_temporary=True # Mark as temporary + ) + ) + + # If no review required or low risk, generate and send AI response immediately + ai_service = AISoulService() + ai_response = await ai_service.generate_ai_response( + db, + str(current_user.id), + str(ai_soul_id), + message_in.content, + risk_assessment + ) + + ai_message = ChatMessage( + content=ai_response, + user_id=current_user.id, + ai_soul_id=ai_soul_id, + is_from_user=False, + ) + db.add(ai_message) + db.commit() + db.refresh(ai_message) + + # Return both messages to prevent stacking + return ChatMessagePairResponse( + user_message=ChatMessagePublic( + id=user_message.id, + content=user_message.content, + user_id=user_message.user_id, + ai_soul_id=user_message.ai_soul_id, + is_from_user=user_message.is_from_user, + timestamp=user_message.timestamp, + is_temporary=False + ), + ai_message=ChatMessagePublic( + id=ai_message.id, + content=ai_message.content, + user_id=ai_message.user_id, + ai_soul_id=ai_message.ai_soul_id, + is_from_user=ai_message.is_from_user, + timestamp=ai_message.timestamp, + is_temporary=False + ) + ) + + +@router.get("/{ai_soul_id}/messages", response_model=list[ChatMessagePublic]) +def get_chat_messages( + *, + db: SessionDep, + current_user: CurrentActiveUser, + ai_soul_id: UUID, + skip: int = 0, + limit: int = 100, +) -> list[ChatMessagePublic]: + """ + Get chat messages for a specific AI soul. + Users can only see their own chat messages. + Messages are returned in ascending order (oldest first). + """ + # Verify AI soul exists + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + statement = ( + select(ChatMessage) + .where( + ChatMessage.user_id == current_user.id, + ChatMessage.ai_soul_id == ai_soul_id, + ) + .order_by(ChatMessage.timestamp.asc()) + .offset(skip) + .limit(limit) + ) + messages = db.exec(statement).all() + + # Convert to ChatMessagePublic with is_temporary=False for all saved messages + return [ + ChatMessagePublic( + id=msg.id, + content=msg.content, + user_id=msg.user_id, + ai_soul_id=msg.ai_soul_id, + is_from_user=msg.is_from_user, + timestamp=msg.timestamp, + is_temporary=False # All saved messages are not temporary + ) + for msg in messages + ] + + +@router.delete("/{ai_soul_id}/messages") +def delete_chat_messages( + *, + db: SessionDep, + current_user: CurrentActiveUser, + ai_soul_id: UUID, +) -> None: + """ + Delete all chat messages for a specific AI soul. + Users can only delete their own chat messages. + """ + # Verify AI soul exists + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + statement = ( + select(ChatMessage) + .where( + ChatMessage.user_id == current_user.id, + ChatMessage.ai_soul_id == ai_soul_id, + ) + ) + messages = db.exec(statement).all() + for message in messages: + db.delete(message) + db.commit() diff --git a/backend/app/api/routes/counselor.py b/backend/app/api/routes/counselor.py new file mode 100644 index 0000000000..daeb8869e8 --- /dev/null +++ b/backend/app/api/routes/counselor.py @@ -0,0 +1,566 @@ +""" +Counselor API Routes for Review Queue and Approval System + +These routes handle counselor workflows including: +- Review queue management +- Response approvals, modifications, and rejections +- Case escalation +- Performance analytics +""" + +from typing import Any, Dict, List +from uuid import UUID + +from fastapi import APIRouter, Depends, HTTPException, Query +from pydantic import BaseModel +from sqlmodel import Session, select + +from app.api.deps import ( + CurrentCounselorOrAdmin, + SessionDep, +) +from app.models import ( + Counselor, + CounselorAction, + Organization, + PendingResponse, + RiskAssessment, + User, +) +from app.services.counselor_service import CounselorService +from app.services.risk_assessment_service import RiskAssessmentService + +router = APIRouter() + + +# Pydantic models for request/response +class ApproveResponseRequest(BaseModel): + notes: str | None = None + + +class ModifyResponseRequest(BaseModel): + modified_response: str + notes: str | None = None + + +class RejectResponseRequest(BaseModel): + replacement_response: str + reason: str + + +class EscalateRequestRequest(BaseModel): + escalation_reason: str + target_counselor_id: str | None = None + + +class CounselorQueueResponse(BaseModel): + queue_items: List[Dict[str, Any]] + total_count: int + urgent_count: int + high_priority_count: int + + +class PerformanceMetricsResponse(BaseModel): + counselor_id: str + period_days: int + total_cases_reviewed: int + approvals: int + modifications: int + rejections: int + escalations: int + approval_rate: float + average_review_time_seconds: int + current_queue_size: int + cases_per_day: float + + +@router.get("/queue", response_model=CounselorQueueResponse) +async def get_counselor_queue( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + status: str = Query(default="pending", description="Status filter"), + limit: int = Query(default=50, le=100, description="Maximum number of items") +) -> CounselorQueueResponse: + """ + Get the review queue for the current counselor. + """ + # Get counselor record + counselor = db.exec( + select(Counselor).where(Counselor.user_id == current_user.id) + ).first() + + counselor_service = CounselorService(db) + + # For admin users, get all pending responses in organization-wide view + # but with the same data structure as counselor queue for frontend consistency + if not counselor and current_user.is_superuser: + queue_items = await counselor_service.get_admin_queue( + organization_id=str(current_user.organization_id) if current_user.organization_id else None, + status=status, + limit=limit + ) + else: + queue_items = await counselor_service.get_counselor_queue( + counselor_id=str(counselor.id) if counselor else None, + status=status, + limit=limit + ) + + # Calculate priority counts + urgent_count = len([item for item in queue_items if item.get("priority") == "urgent"]) + high_priority_count = len([item for item in queue_items if item.get("priority") == "high"]) + + return CounselorQueueResponse( + queue_items=queue_items, + total_count=len(queue_items), + urgent_count=urgent_count, + high_priority_count=high_priority_count + ) + + +@router.get("/organization-queue") +async def get_organization_queue( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + status: str = Query(default="pending", description="Status filter"), + priority: str | None = Query(default=None, description="Priority filter"), + limit: int = Query(default=100, le=200, description="Maximum number of items") +) -> Dict[str, Any]: + """ + Get the organization-wide review queue (admin/supervisor only). + """ + counselor_service = CounselorService(db) + queue_items = await counselor_service.get_organization_queue( + organization_id=str(current_user.organization_id) if current_user.organization_id else None, + status=status, + priority=priority, + limit=limit + ) + + return { + "queue_items": queue_items, + "total_count": len(queue_items), + "filters": { + "status": status, + "priority": priority + } + } + + +@router.post("/{pending_response_id}/approve") +async def approve_response( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + pending_response_id: UUID, + request: ApproveResponseRequest +) -> Dict[str, Any]: + """ + Approve an AI response without modifications. + """ + # Get counselor record (this should exist due to CurrentCounselorOrAdmin dependency) + counselor = db.exec( + select(Counselor).where(Counselor.user_id == current_user.id) + ).first() + + # Verify pending response exists + pending_response = db.get(PendingResponse, pending_response_id) + if not pending_response: + raise HTTPException( + status_code=404, + detail=f"Pending response {pending_response_id} not found" + ) + + # Check assignment (admins can approve any response) + if not current_user.is_superuser and counselor: + if pending_response.assigned_counselor_id != counselor.id: + raise HTTPException( + status_code=403, + detail="This response is assigned to another counselor. You can only approve responses assigned to you." + ) + + try: + counselor_service = CounselorService(db) + result = await counselor_service.approve_response( + pending_response_id=str(pending_response_id), + counselor_id=str(counselor.id) if counselor else None, + notes=request.notes + ) + + return result + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Failed to approve response: {str(e)}" + ) + + +@router.post("/{pending_response_id}/modify") +async def modify_response( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + pending_response_id: UUID, + request: ModifyResponseRequest +) -> Dict[str, Any]: + """ + Modify an AI response before sending to user. + """ + # Get counselor record (this should exist due to CurrentCounselorOrAdmin dependency) + counselor = db.exec( + select(Counselor).where(Counselor.user_id == current_user.id) + ).first() + + # This should not happen due to our improved dependency, but let's be safe + if not counselor and not current_user.is_superuser: + raise HTTPException( + status_code=403, + detail="Counselor profile not found. Please contact administrator." + ) + + # Verify pending response exists + pending_response = db.get(PendingResponse, pending_response_id) + if not pending_response: + raise HTTPException( + status_code=404, + detail=f"Pending response {pending_response_id} not found" + ) + + # Check assignment (admins can modify any response) + if not current_user.is_superuser and counselor: + if pending_response.assigned_counselor_id != counselor.id: + raise HTTPException( + status_code=403, + detail=f"This response is assigned to another counselor. You can only modify responses assigned to you." + ) + + # Validate request + if not request.modified_response or not request.modified_response.strip(): + raise HTTPException( + status_code=400, + detail="Modified response cannot be empty" + ) + + try: + counselor_service = CounselorService(db) + result = await counselor_service.modify_response( + pending_response_id=str(pending_response_id), + counselor_id=str(counselor.id) if counselor else None, + modified_response=request.modified_response.strip(), + notes=request.notes + ) + + return result + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Failed to modify response: {str(e)}" + ) + + +@router.post("/{pending_response_id}/reject") +async def reject_response( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + pending_response_id: UUID, + request: RejectResponseRequest +) -> Dict[str, Any]: + """ + Reject an AI response and provide a replacement. + """ + # Get counselor record (this should exist due to CurrentCounselorOrAdmin dependency) + counselor = db.exec( + select(Counselor).where(Counselor.user_id == current_user.id) + ).first() + + # This should not happen due to our improved dependency, but let's be safe + if not counselor and not current_user.is_superuser: + raise HTTPException( + status_code=403, + detail="Counselor profile not found. Please contact administrator." + ) + + # Verify pending response exists + pending_response = db.get(PendingResponse, pending_response_id) + if not pending_response: + raise HTTPException( + status_code=404, + detail=f"Pending response {pending_response_id} not found" + ) + + # Check assignment (admins can reject any response) + if not current_user.is_superuser and counselor: + if pending_response.assigned_counselor_id != counselor.id: + raise HTTPException( + status_code=403, + detail="This response is assigned to another counselor. You can only reject responses assigned to you." + ) + + # Validate request + if not request.replacement_response or not request.replacement_response.strip(): + raise HTTPException( + status_code=400, + detail="Replacement response cannot be empty" + ) + + if not request.reason or not request.reason.strip(): + raise HTTPException( + status_code=400, + detail="Rejection reason cannot be empty" + ) + + try: + counselor_service = CounselorService(db) + result = await counselor_service.reject_response( + pending_response_id=str(pending_response_id), + counselor_id=str(counselor.id) if counselor else None, + replacement_response=request.replacement_response.strip(), + reason=request.reason.strip() + ) + + return result + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Failed to reject response: {str(e)}" + ) + + +@router.post("/{pending_response_id}/escalate") +async def escalate_case( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + pending_response_id: UUID, + request: EscalateRequestRequest +) -> Dict[str, Any]: + """ + Escalate a case to another counselor or supervisor. + """ + # Verify counselor permissions + counselor = db.exec( + select(Counselor).where(Counselor.user_id == current_user.id) + ).first() + + if not counselor: + raise HTTPException( + status_code=403, + detail="Only counselors can escalate cases" + ) + + # Verify pending response + pending_response = db.get(PendingResponse, pending_response_id) + if not pending_response: + raise HTTPException(status_code=404, detail="Pending response not found") + + if pending_response.assigned_counselor_id != counselor.id: + raise HTTPException( + status_code=403, + detail="You can only escalate cases assigned to you" + ) + + counselor_service = CounselorService(db) + result = await counselor_service.escalate_case( + pending_response_id=str(pending_response_id), + counselor_id=str(counselor.id), + escalation_reason=request.escalation_reason, + target_counselor_id=request.target_counselor_id + ) + + return result + + +@router.get("/performance", response_model=PerformanceMetricsResponse) +async def get_counselor_performance( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + days: int = Query(default=30, le=365, description="Number of days to analyze") +) -> PerformanceMetricsResponse: + """ + Get performance metrics for the current counselor. + """ + # Get counselor record + counselor = db.exec( + select(Counselor).where(Counselor.user_id == current_user.id) + ).first() + + # If no counselor record but user is admin, allow access with organization-wide metrics + if not counselor and not current_user.is_superuser: + raise HTTPException( + status_code=403, + detail="Only counselors and administrators can view performance metrics" + ) + + counselor_service = CounselorService(db) + + # If admin without counselor record, get organization-wide metrics + if not counselor and current_user.is_superuser: + # For admin users, provide organization-wide performance metrics + metrics = await counselor_service.get_organization_performance( + organization_id=str(current_user.organization_id) if current_user.organization_id else None, + days=days + ) + else: + metrics = await counselor_service.get_counselor_performance( + counselor_id=str(counselor.id), + days=days + ) + + return PerformanceMetricsResponse(**metrics) + + +@router.get("/risk-assessments") +async def get_recent_risk_assessments( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + days: int = Query(default=7, le=30, description="Number of days to look back"), + limit: int = Query(default=50, le=100, description="Maximum number of assessments") +) -> Dict[str, Any]: + """ + Get recent risk assessments for monitoring (counselor/admin only). + """ + # Check permissions + if not current_user.is_superuser and current_user.role not in ["admin", "counselor"]: + raise HTTPException( + status_code=403, + detail="Insufficient permissions to view risk assessments" + ) + + risk_service = RiskAssessmentService() + assessments = await risk_service.get_recent_risk_assessments( + session=db, + organization_id=str(current_user.organization_id) if current_user.organization_id else None, + days=days, + limit=limit + ) + + # Convert to serializable format + assessment_data = [] + for assessment in assessments: + assessment_data.append({ + "id": str(assessment.id), + "risk_level": assessment.risk_level, + "risk_categories": assessment.risk_categories, + "confidence_score": assessment.confidence_score, + "reasoning": assessment.reasoning, + "requires_human_review": assessment.requires_human_review, + "auto_response_blocked": assessment.auto_response_blocked, + "assessed_at": assessment.assessed_at, + "user_id": str(assessment.user_id), + "ai_soul_id": str(assessment.ai_soul_id) + }) + + return { + "assessments": assessment_data, + "total_count": len(assessment_data), + "period_days": days + } + + +@router.get("/high-risk-conversations") +async def get_high_risk_conversations( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + hours: int = Query(default=24, le=168, description="Number of hours to look back") +) -> Dict[str, Any]: + """ + Get conversations with high risk assessments for immediate attention. + """ + # Check permissions + if not current_user.is_superuser and current_user.role not in ["admin", "counselor"]: + raise HTTPException( + status_code=403, + detail="Insufficient permissions to view high-risk conversations" + ) + + risk_service = RiskAssessmentService() + conversations = await risk_service.get_high_risk_conversations( + session=db, + organization_id=str(current_user.organization_id) if current_user.organization_id else None, + hours=hours + ) + + return { + "conversations": conversations, + "total_count": len(conversations), + "period_hours": hours + } + + +@router.post("/auto-approve-expired") +async def auto_approve_expired_responses( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin +) -> Dict[str, Any]: + """ + Manually trigger auto-approval of expired responses (admin only). + """ + # Check admin permissions + if not current_user.is_superuser and current_user.role not in ["admin"]: + raise HTTPException( + status_code=403, + detail="Admin privileges required" + ) + + counselor_service = CounselorService(db) + approved_count = await counselor_service.auto_approve_expired_responses() + + return { + "message": f"Auto-approved {approved_count} expired responses", + "approved_count": approved_count + } + + +@router.get("/counselors") +async def list_counselors( + *, + db: SessionDep, + current_user: CurrentCounselorOrAdmin, + organization_id: UUID | None = Query(default=None, description="Filter by organization") +) -> Dict[str, Any]: + """ + List all counselors (admin only). + """ + # Check admin permissions + if not current_user.is_superuser and current_user.role not in ["admin"]: + raise HTTPException( + status_code=403, + detail="Admin privileges required" + ) + + statement = select(Counselor) + + if organization_id: + statement = statement.where(Counselor.organization_id == organization_id) + elif current_user.organization_id: + statement = statement.where(Counselor.organization_id == current_user.organization_id) + + counselors = db.exec(statement).all() + + counselor_data = [] + for counselor in counselors: + user = db.get(User, counselor.user_id) + counselor_data.append({ + "id": str(counselor.id), + "user_id": str(counselor.user_id), + "user_name": user.full_name if user else "Unknown", + "user_email": user.email if user else "Unknown", + "specializations": counselor.specializations, + "license_number": counselor.license_number, + "license_type": counselor.license_type, + "is_available": counselor.is_available, + "max_concurrent_cases": counselor.max_concurrent_cases, + "created_at": counselor.created_at + }) + + return { + "counselors": counselor_data, + "total_count": len(counselor_data) + } \ No newline at end of file diff --git a/backend/app/api/routes/documents.py b/backend/app/api/routes/documents.py new file mode 100644 index 0000000000..0daf3b9bb9 --- /dev/null +++ b/backend/app/api/routes/documents.py @@ -0,0 +1,233 @@ +import uuid +from typing import Any + +from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile +from sqlmodel import Session, select + +from app.api.deps import CurrentUser, SessionDep, get_current_active_user, get_db +from app.models import Document, DocumentPublic, DocumentsPublic, User +from app.services.enhanced_rag_service import EnhancedRAGService + +router = APIRouter() + + +@router.post("/upload/", response_model=DocumentPublic) +async def upload_document( + *, + db: Session = Depends(get_db), + current_user: User = Depends(get_current_active_user), + file: UploadFile = File(...), + description: str | None = Form(None), +) -> DocumentPublic: + """ + Upload a PDF document for processing. + """ + import os + + from app.core.config import settings + + if not file.content_type == "application/pdf": + raise HTTPException(status_code=400, detail="Only PDF files are supported") + + # Read file content and validate + content = await file.read() + if len(content) > 10 * 1024 * 1024: # 10MB limit + raise HTTPException(status_code=400, detail="File too large") + + # Create upload directory if it doesn't exist + upload_dir = getattr(settings, 'UPLOAD_DIR', 'uploads') + os.makedirs(upload_dir, exist_ok=True) + + # Generate unique filename + import hashlib + file_hash = hashlib.md5(content).hexdigest() + ext = os.path.splitext(file.filename or "document.pdf")[1] + filename = f"{file_hash}{ext}" + file_path = os.path.join(upload_dir, filename) + + # Save file to disk + with open(file_path, "wb") as f: + f.write(content) + + # Create document record + document = Document( + filename=filename, + original_filename=file.filename or "document.pdf", + file_size=len(content), + content_type=file.content_type, + description=description, + file_path=file_path, + user_id=current_user.id, + processing_status="pending", + chunk_count=0, + ) + db.add(document) + db.commit() + db.refresh(document) + + # Process document with Enhanced RAG service + try: + rag_service = EnhancedRAGService(db) + await rag_service.process_document( + document=document, + user_id=str(current_user.id) + ) + + # Update document status + document.processing_status = "completed" + db.commit() + + except Exception as e: + document.processing_status = "failed" + db.commit() + raise HTTPException(status_code=500, detail=f"Failed to process document: {str(e)}") + + return DocumentPublic.from_orm(document) + + +@router.get("/", response_model=DocumentsPublic) +def get_documents( + *, + db: Session = Depends(get_db), + current_user: User = Depends(get_current_active_user), + skip: int = 0, + limit: int = 100, +) -> DocumentsPublic: + """ + Retrieve all documents for the current user. + """ + # Get documents directly from database + query = select(Document).where(Document.user_id == current_user.id) + total = len(db.exec(query).all()) + + documents = db.exec( + query.offset(skip).limit(limit) + ).all() + + return DocumentsPublic( + data=[DocumentPublic.from_orm(doc) for doc in documents], + count=total, + ) + + +@router.delete("/{document_id}") +async def delete_document( + *, + db: Session = Depends(get_db), + current_user: User = Depends(get_current_active_user), + document_id: uuid.UUID, +) -> dict: + """ + Delete a document and its associated file. + """ + # Get the document + document = db.exec( + select(Document).where( + Document.id == document_id, + Document.user_id == current_user.id + ) + ).first() + + if not document: + raise HTTPException(status_code=404, detail="Document not found") + + # Delete from Qdrant + try: + rag_service = EnhancedRAGService(db) + await rag_service.delete_document_from_index( + document_id=str(document_id), + user_id=str(current_user.id) + ) + except Exception as e: + # Log error but don't fail the deletion + print(f"Warning: Failed to delete from Qdrant: {e}") + + # Delete file from disk + import os + if document.file_path and os.path.exists(document.file_path): + try: + os.remove(document.file_path) + except Exception as e: + print(f"Warning: Failed to delete file: {e}") + + # Delete from database + db.delete(document) + db.commit() + + return {"status": "success", "message": "Document deleted"} + + +@router.get("/{document_id}", response_model=DocumentPublic) +def get_document( + *, + db: Session = Depends(get_db), + current_user: User = Depends(get_current_active_user), + document_id: uuid.UUID, +) -> DocumentPublic: + """ + Get a specific document by ID. + """ + document = db.exec( + select(Document).where( + Document.id == document_id, + Document.user_id == current_user.id + ) + ).first() + + if not document: + raise HTTPException(status_code=404, detail="Document not found") + + return DocumentPublic.from_orm(document) + + +@router.post("/search") +async def search_documents( + *, + db: Session = Depends(get_db), + current_user: User = Depends(get_current_active_user), + query: str = Form(...), + limit: int = Form(5) +) -> Any: + """ + Search through uploaded documents using Enhanced RAG. + """ + try: + rag_service = EnhancedRAGService(db) + search_response = await rag_service.hybrid_search( + query=query, + user_id=str(current_user.id), + limit=limit + ) + + return { + "query": query, + "results": search_response.get("results", []), + "total_found": search_response.get("total_found", 0) + } + except Exception as e: + raise HTTPException(status_code=500, detail=f"Error searching documents: {str(e)}") + + +@router.get("/stats/summary") +def get_document_stats(*, session: SessionDep, current_user: CurrentUser) -> Any: + """ + Get document statistics for the current user. + """ + try: + # Get document count by status + statement = select(Document).where(Document.user_id == current_user.id) + documents = session.exec(statement).all() + + stats = { + "total_documents": len(documents), + "completed": len([d for d in documents if d.processing_status == "completed"]), + "processing": len([d for d in documents if d.processing_status == "processing"]), + "pending": len([d for d in documents if d.processing_status == "pending"]), + "failed": len([d for d in documents if d.processing_status == "failed"]), + "total_chunks": sum(d.chunk_count for d in documents), + "total_size_mb": round(sum(d.file_size for d in documents) / (1024 * 1024), 2) + } + + return stats + except Exception as e: + raise HTTPException(status_code=500, detail=f"Error getting document stats: {str(e)}") diff --git a/backend/app/api/routes/enhanced_rag.py b/backend/app/api/routes/enhanced_rag.py new file mode 100644 index 0000000000..c7682aca14 --- /dev/null +++ b/backend/app/api/routes/enhanced_rag.py @@ -0,0 +1,662 @@ +""" +Enhanced RAG API Routes + +Provides REST endpoints for the enhanced RAG system including: +- Document search with hybrid retrieval +- Document processing and indexing +- Search analytics and monitoring +- Configuration management +- Health checks and system status +""" + +import logging +import uuid +from datetime import datetime +from typing import Any + +from fastapi import APIRouter, Depends, HTTPException, Query, status +from pydantic import BaseModel, Field +from sqlmodel import Session + +from app.api.deps import get_current_user, get_db +from app.models import Document, User +from app.services.enhanced_rag_service import EnhancedRAGService + +logger = logging.getLogger(__name__) + +router = APIRouter() + + +# Pydantic models for request/response +class SearchRequest(BaseModel): + """Search request model.""" + query: str = Field(..., min_length=1, max_length=1000, description="Search query") + ai_soul_id: str | None = Field(None, description="AI Soul ID for filtering") + filters: dict[str, Any] | None = Field(None, description="Additional search filters") + limit: int = Field(10, ge=1, le=50, description="Maximum number of results") + + +class SearchResponse(BaseModel): + """Search response model.""" + query: str + results: list[dict[str, Any]] + total_found: int + response_time_ms: int + search_algorithm: str + similarity_threshold: float + reranking_enabled: bool + + +class ProcessDocumentRequest(BaseModel): + """Document processing request model.""" + document_id: str = Field(..., description="Document ID to process") + chunking_strategy: str | None = Field("semantic", description="Chunking strategy") + chunk_size: int | None = Field(500, ge=100, le=2000, description="Chunk size") + chunk_overlap: int | None = Field(50, ge=0, le=500, description="Chunk overlap") + embedding_model: str | None = Field("text-embedding-3-small", description="Embedding model") + + +class ProcessDocumentResponse(BaseModel): + """Document processing response model.""" + status: str + chunks_created: int + processing_time_ms: int + embedding_model: str + chunking_strategy: str + + +class ClickTrackingRequest(BaseModel): + """Click tracking request model.""" + search_query_id: str + chunk_id: str + result_position: int + similarity_score: float + rerank_score: float | None = None + + +class ConfigurationRequest(BaseModel): + """RAG configuration request model.""" + ai_soul_id: str | None = None + chunking_strategy: str = Field("semantic", pattern="^(semantic|sentence|paragraph|simple)$") + chunk_size: int = Field(500, ge=100, le=2000) + chunk_overlap: int = Field(50, ge=0, le=500) + embedding_model: str = Field("text-embedding-3-small") + search_algorithm: str = Field("hybrid", pattern="^(vector|hybrid|keyword)$") + similarity_threshold: float = Field(0.7, ge=0.0, le=1.0) + max_results: int = Field(10, ge=1, le=100) + enable_reranking: bool = True + + +@router.post("/search", response_model=SearchResponse) +async def search_documents( + request: SearchRequest, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Search documents using enhanced RAG with hybrid retrieval. + + Features: + - Semantic vector search + - Keyword matching + - Result reranking + - Caching for performance + - Analytics tracking + """ + try: + rag_service = EnhancedRAGService(db) + + # Perform hybrid search with fallback + results = await rag_service.simple_hybrid_search( + query=request.query, + user_id=str(current_user.id), + ai_soul_id=request.ai_soul_id, + filters=request.filters, + limit=request.limit + ) + + return SearchResponse(**results) + + except Exception as e: + logger.error(f"Search error for user {current_user.id}: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Search failed: {str(e)}" + ) + + +@router.post("/documents/process", response_model=ProcessDocumentResponse) +async def process_document( + request: ProcessDocumentRequest, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Process a document with enhanced chunking and indexing. + + Steps: + 1. Extract text from document + 2. Apply intelligent chunking + 3. Generate embeddings + 4. Store in vector database + 5. Update analytics + """ + try: + # Get document + document = db.get(Document, uuid.UUID(request.document_id)) + if not document: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Document not found" + ) + + # Check ownership + if document.user_id != current_user.id: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Access denied" + ) + + # Create RAG service and process document + rag_service = EnhancedRAGService(db) + + # Create custom config if provided + config = None + if any([ + request.chunking_strategy != "semantic", + request.chunk_size != 500, + request.chunk_overlap != 50, + request.embedding_model != "text-embedding-3-small" + ]): + from app.models import RAGConfiguration + config = RAGConfiguration( + user_id=current_user.id, + chunking_strategy=request.chunking_strategy, + chunk_size=request.chunk_size, + chunk_overlap=request.chunk_overlap, + embedding_model=request.embedding_model, + search_algorithm="hybrid", + similarity_threshold=0.7, + max_results=10, + enable_reranking=True + ) + + result = await rag_service.process_document( + document=document, + user_id=str(current_user.id), + config=config + ) + + return ProcessDocumentResponse(**result) + + except HTTPException: + raise + except Exception as e: + logger.error(f"Document processing error for user {current_user.id}: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Document processing failed: {str(e)}" + ) + + +@router.post("/documents/{document_id}/reindex") +async def reindex_document( + document_id: str, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Reindex an existing document with current configuration. + + This will: + 1. Delete existing chunks from vector database + 2. Reprocess the document with current settings + 3. Create new embeddings and chunks + """ + try: + # Get document + document = db.get(Document, uuid.UUID(document_id)) + if not document: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Document not found" + ) + + # Check ownership + if document.user_id != current_user.id: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Access denied" + ) + + rag_service = EnhancedRAGService(db) + + # Delete existing index + await rag_service.delete_document_from_index( + document_id=document_id, + user_id=str(current_user.id) + ) + + # Reprocess document + result = await rag_service.process_document( + document=document, + user_id=str(current_user.id) + ) + + return { + "message": "Document reindexed successfully", + "document_id": document_id, + **result + } + + except HTTPException: + raise + except Exception as e: + logger.error(f"Document reindexing error: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Reindexing failed: {str(e)}" + ) + + +@router.delete("/documents/{document_id}/index") +async def delete_document_index( + document_id: str, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Delete document chunks from the vector index. + + This removes all chunks and embeddings for the document + but keeps the document record intact. + """ + try: + rag_service = EnhancedRAGService(db) + + success = await rag_service.delete_document_from_index( + document_id=document_id, + user_id=str(current_user.id) + ) + + if not success: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Failed to delete document index" + ) + + return { + "message": "Document index deleted successfully", + "document_id": document_id + } + + except HTTPException: + raise + except Exception as e: + logger.error(f"Document index deletion error: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Index deletion failed: {str(e)}" + ) + + +@router.post("/analytics/click") +async def track_result_click( + request: ClickTrackingRequest, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Track when a user clicks on a search result. + + This helps improve search relevance through user feedback + and provides analytics on result effectiveness. + """ + try: + rag_service = EnhancedRAGService(db) + + await rag_service.track_result_click( + search_query_id=request.search_query_id, + chunk_id=request.chunk_id, + user_id=str(current_user.id), + result_position=request.result_position, + similarity_score=request.similarity_score, + rerank_score=request.rerank_score + ) + + return {"message": "Click tracked successfully"} + + except Exception as e: + logger.error(f"Click tracking error: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Click tracking failed: {str(e)}" + ) + + +@router.get("/analytics/search") +async def get_search_analytics( + days: int = Query(30, ge=1, le=365, description="Number of days to analyze"), + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Get search analytics for the current user. + + Returns: + - Total searches performed + - Average response time + - Click-through rate + - Top search queries + """ + try: + rag_service = EnhancedRAGService(db) + + analytics = await rag_service.get_search_analytics( + user_id=str(current_user.id), + days=days + ) + + return analytics + + except Exception as e: + logger.error(f"Analytics error: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Analytics retrieval failed: {str(e)}" + ) + + +@router.get("/configuration") +async def get_rag_configuration( + ai_soul_id: str | None = Query(None, description="AI Soul ID"), + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """Get RAG configuration for user or specific AI Soul.""" + try: + from sqlmodel import select + + from app.models import RAGConfiguration + + query = select(RAGConfiguration).where( + RAGConfiguration.user_id == current_user.id + ) + + if ai_soul_id: + query = query.where(RAGConfiguration.ai_soul_id == uuid.UUID(ai_soul_id)) + else: + query = query.where(RAGConfiguration.ai_soul_id.is_(None)) + + config = db.exec(query).first() + + if not config: + # Return default configuration + return { + "chunking_strategy": "semantic", + "chunk_size": 500, + "chunk_overlap": 50, + "embedding_model": "text-embedding-3-small", + "search_algorithm": "hybrid", + "similarity_threshold": 0.7, + "max_results": 10, + "enable_reranking": True, + "is_default": True + } + + return { + "id": str(config.id), + "ai_soul_id": str(config.ai_soul_id) if config.ai_soul_id else None, + "chunking_strategy": config.chunking_strategy, + "chunk_size": config.chunk_size, + "chunk_overlap": config.chunk_overlap, + "embedding_model": config.embedding_model, + "search_algorithm": config.search_algorithm, + "similarity_threshold": config.similarity_threshold, + "max_results": config.max_results, + "enable_reranking": config.enable_reranking, + "advanced_settings": config.advanced_settings, + "created_at": config.created_at, + "updated_at": config.updated_at, + "is_default": False + } + + except Exception as e: + logger.error(f"Configuration retrieval error: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Configuration retrieval failed: {str(e)}" + ) + + +@router.post("/configuration") +async def update_rag_configuration( + request: ConfigurationRequest, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """Update RAG configuration for user or specific AI Soul.""" + try: + from datetime import datetime + + from sqlmodel import select + + from app.models import RAGConfiguration + + # Check if configuration exists + query = select(RAGConfiguration).where( + RAGConfiguration.user_id == current_user.id + ) + + if request.ai_soul_id: + query = query.where(RAGConfiguration.ai_soul_id == uuid.UUID(request.ai_soul_id)) + else: + query = query.where(RAGConfiguration.ai_soul_id.is_(None)) + + config = db.exec(query).first() + + if config: + # Update existing configuration + config.chunking_strategy = request.chunking_strategy + config.chunk_size = request.chunk_size + config.chunk_overlap = request.chunk_overlap + config.embedding_model = request.embedding_model + config.search_algorithm = request.search_algorithm + config.similarity_threshold = request.similarity_threshold + config.max_results = request.max_results + config.enable_reranking = request.enable_reranking + config.updated_at = datetime.utcnow() + else: + # Create new configuration + config = RAGConfiguration( + user_id=current_user.id, + ai_soul_id=uuid.UUID(request.ai_soul_id) if request.ai_soul_id else None, + chunking_strategy=request.chunking_strategy, + chunk_size=request.chunk_size, + chunk_overlap=request.chunk_overlap, + embedding_model=request.embedding_model, + search_algorithm=request.search_algorithm, + similarity_threshold=request.similarity_threshold, + max_results=request.max_results, + enable_reranking=request.enable_reranking + ) + db.add(config) + + db.commit() + db.refresh(config) + + return { + "message": "Configuration updated successfully", + "id": str(config.id), + "ai_soul_id": str(config.ai_soul_id) if config.ai_soul_id else None + } + + except Exception as e: + logger.error(f"Configuration update error: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Configuration update failed: {str(e)}" + ) + + +@router.get("/health") +async def health_check( + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Perform health check on RAG system components. + + Checks: + - Qdrant vector database connectivity + - Redis cache availability + - OpenAI API connectivity + - Database connectivity + """ + try: + rag_service = EnhancedRAGService(db) + health = await rag_service.health_check() + + return health + + except Exception as e: + logger.error(f"Health check error: {e}") + return { + "status": "unhealthy", + "error": str(e), + "timestamp": datetime.utcnow().isoformat() + } + + +@router.get("/collections/info") +async def get_collection_info( + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Get information about Qdrant collections. + + Returns collection statistics and status for monitoring. + """ + try: + rag_service = EnhancedRAGService(db) + info = await rag_service.get_collection_info() + + return info + + except Exception as e: + logger.error(f"Collection info error: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Collection info retrieval failed: {str(e)}" + ) + + +@router.get("/suggestions") +async def get_search_suggestions( + query: str = Query(..., min_length=2, max_length=100), + limit: int = Query(5, ge=1, le=20), + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Get search suggestions based on query prefix. + + Returns popular queries that start with the given prefix + to help users with query completion. + """ + try: + from sqlmodel import func, select + + from app.models import SearchQuery + + # Get popular queries that start with the prefix + suggestions = db.exec( + select(SearchQuery.query_text, func.count(SearchQuery.id).label('count')) + .where( + SearchQuery.user_id == current_user.id, + SearchQuery.query_text.ilike(f"{query}%") + ) + .group_by(SearchQuery.query_text) + .order_by(func.count(SearchQuery.id).desc()) + .limit(limit) + ).all() + + return { + "query": query, + "suggestions": [{"text": s.query_text, "count": s.count} for s in suggestions] + } + + except Exception as e: + logger.error(f"Suggestions error: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Suggestions retrieval failed: {str(e)}" + ) + + +@router.post("/bulk-process") +async def bulk_process_documents( + document_ids: list[str], + chunking_strategy: str = "semantic", + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + Process multiple documents in bulk. + + Useful for reprocessing documents after configuration changes + or initial setup of large document collections. + """ + try: + if len(document_ids) > 50: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Maximum 50 documents can be processed at once" + ) + + rag_service = EnhancedRAGService(db) + results = [] + + for doc_id in document_ids: + try: + document = db.get(Document, uuid.UUID(doc_id)) + if not document or document.user_id != current_user.id: + results.append({ + "document_id": doc_id, + "status": "error", + "error": "Document not found or access denied" + }) + continue + + result = await rag_service.process_document( + document=document, + user_id=str(current_user.id) + ) + + results.append({ + "document_id": doc_id, + **result + }) + + except Exception as e: + results.append({ + "document_id": doc_id, + "status": "error", + "error": str(e) + }) + + return { + "message": "Bulk processing completed", + "total_documents": len(document_ids), + "results": results + } + + except HTTPException: + raise + except Exception as e: + logger.error(f"Bulk processing error: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Bulk processing failed: {str(e)}" + ) diff --git a/backend/app/api/routes/items.py b/backend/app/api/routes/items.py index 177dc1e476..67196c2366 100644 --- a/backend/app/api/routes/items.py +++ b/backend/app/api/routes/items.py @@ -7,7 +7,7 @@ from app.api.deps import CurrentUser, SessionDep from app.models import Item, ItemCreate, ItemPublic, ItemsPublic, ItemUpdate, Message -router = APIRouter(prefix="/items", tags=["items"]) +router = APIRouter() @router.get("/", response_model=ItemsPublic) diff --git a/backend/app/api/routes/private.py b/backend/app/api/routes/private.py index 9f33ef1900..cea6c6aa30 100644 --- a/backend/app/api/routes/private.py +++ b/backend/app/api/routes/private.py @@ -10,7 +10,7 @@ UserPublic, ) -router = APIRouter(tags=["private"], prefix="/private") +router = APIRouter() class PrivateUserCreate(BaseModel): diff --git a/backend/app/api/routes/training.py b/backend/app/api/routes/training.py new file mode 100644 index 0000000000..fdefadceb4 --- /dev/null +++ b/backend/app/api/routes/training.py @@ -0,0 +1,242 @@ +from uuid import UUID + +from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile +from sqlmodel import Session, select + +from app.api.deps import ( + CurrentTrainerOrAdmin, + SessionDep, + get_user_role, + UserRole, +) +from app.models import ( + AISoulEntity, + TrainingDocument, + TrainingDocumentPublic, + TrainingMessageCreate, + TrainingMessagePublic, + User, +) +from app.services.training_service import TrainingService + +router = APIRouter() + + +@router.post("/{ai_soul_id}/messages", response_model=TrainingMessagePublic) +async def send_training_message( + *, + db: SessionDep, + current_user: CurrentTrainerOrAdmin, + ai_soul_id: UUID, + message: TrainingMessageCreate +) -> TrainingMessagePublic: + """ + Send a training message for an AI soul. + Only trainers and admins can send training messages. + """ + training_service = TrainingService(db) + + # Verify AI soul exists + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + # Only admins can train any soul, trainers can only train their own + user_role = get_user_role(current_user) + if user_role == UserRole.TRAINER and ai_soul.user_id != current_user.id: + raise HTTPException(status_code=403, detail="Not authorized to train this AI soul") + + training_message = await training_service.send_training_message( + user_id=str(current_user.id), + ai_soul_id=str(ai_soul_id), + content=message.content, + is_from_trainer=message.is_from_trainer + ) + + return TrainingMessagePublic( + id=training_message.id, + content=training_message.content, + is_from_trainer=training_message.is_from_trainer, + ai_soul_id=training_message.ai_soul_id, + user_id=training_message.user_id, + timestamp=training_message.timestamp + ) + + +@router.get("/{ai_soul_id}/messages", response_model=list[TrainingMessagePublic]) +async def get_training_messages( + *, + db: SessionDep, + current_user: CurrentTrainerOrAdmin, + ai_soul_id: UUID, + skip: int = 0, + limit: int = 50 +) -> list[TrainingMessagePublic]: + """ + Get training messages for an AI soul. + Only trainers and admins can view training messages. + """ + training_service = TrainingService(db) + + # Verify AI soul exists + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + # Only admins can view any soul's training, trainers can only view their own + user_role = get_user_role(current_user) + if user_role == UserRole.TRAINER and ai_soul.user_id != current_user.id: + raise HTTPException(status_code=403, detail="Not authorized to view this AI soul's training") + + messages = training_service.get_training_messages( + ai_soul_id=str(ai_soul_id), + user_id=str(current_user.id), + skip=skip, + limit=limit + ) + + return [ + TrainingMessagePublic( + id=message.id, + content=message.content, + is_from_trainer=message.is_from_trainer, + ai_soul_id=message.ai_soul_id, + user_id=message.user_id, + timestamp=message.timestamp + ) + for message in messages + ] + + +@router.post("/{ai_soul_id}/documents", response_model=TrainingDocumentPublic) +async def upload_training_document( + *, + db: SessionDep, + current_user: CurrentTrainerOrAdmin, + ai_soul_id: UUID, + file: UploadFile = File(...), + description: str = Form(None) +) -> TrainingDocumentPublic: + """ + Upload a training document for an AI soul. + Only trainers and admins can upload training documents. + """ + training_service = TrainingService(db) + + # Verify AI soul exists + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + # Only admins can upload to any soul, trainers can only upload to their own + user_role = get_user_role(current_user) + if user_role == UserRole.TRAINER and ai_soul.user_id != current_user.id: + raise HTTPException(status_code=403, detail="Not authorized to upload to this AI soul") + + training_document = await training_service.upload_training_document( + file=file, + user_id=str(current_user.id), + ai_soul_id=str(ai_soul_id), + description=description + ) + + return TrainingDocumentPublic( + id=training_document.id, + filename=training_document.filename, + original_filename=training_document.original_filename, + file_size=training_document.file_size, + content_type=training_document.content_type, + description=training_document.description, + ai_soul_id=training_document.ai_soul_id, + user_id=training_document.user_id, + upload_timestamp=training_document.upload_timestamp, + processing_status=training_document.processing_status, + chunk_count=training_document.chunk_count + ) + + +@router.get("/{ai_soul_id}/documents", response_model=list[TrainingDocumentPublic]) +async def get_training_documents( + *, + db: SessionDep, + current_user: CurrentTrainerOrAdmin, + ai_soul_id: UUID, + skip: int = 0, + limit: int = 20 +) -> list[TrainingDocumentPublic]: + """ + Get training documents for an AI soul. + Only trainers and admins can view training documents. + """ + # Verify AI soul exists + ai_soul = db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul Entity not found") + + # Only admins can view any soul's documents, trainers can only view their own + user_role = get_user_role(current_user) + if user_role == UserRole.TRAINER and ai_soul.user_id != current_user.id: + raise HTTPException(status_code=403, detail="Not authorized to view this AI soul's documents") + + # Get training documents + statement = ( + select(TrainingDocument) + .where(TrainingDocument.ai_soul_id == ai_soul_id) + .offset(skip) + .limit(limit) + ) + documents = db.exec(statement).all() + + return [ + TrainingDocumentPublic( + id=doc.id, + filename=doc.filename, + original_filename=doc.original_filename, + file_size=doc.file_size, + content_type=doc.content_type, + description=doc.description, + ai_soul_id=doc.ai_soul_id, + user_id=doc.user_id, + upload_timestamp=doc.upload_timestamp, + processing_status=doc.processing_status, + chunk_count=doc.chunk_count + ) + for doc in documents + ] + + +@router.delete("/{ai_soul_id}/documents/{document_id}") +async def delete_training_document( + *, + db: SessionDep, + current_user: CurrentTrainerOrAdmin, + ai_soul_id: UUID, + document_id: UUID +) -> None: + """ + Delete a training document. + Only trainers and admins can delete training documents. + """ + import os + + # Get the document + document = db.get(TrainingDocument, document_id) + if not document: + raise HTTPException(status_code=404, detail="Training document not found") + + # Only admins can delete any document, trainers can only delete their own + user_role = get_user_role(current_user) + if user_role == UserRole.TRAINER and document.user_id != current_user.id: + raise HTTPException(status_code=403, detail="Not authorized to delete this document") + + # Delete file from disk + try: + if os.path.exists(document.file_path): + os.remove(document.file_path) + except Exception as e: + # Log error but continue with database deletion + print(f"Error deleting training file {document.file_path}: {e}") + + # Delete from database (will cascade to chunks) + db.delete(document) + db.commit() diff --git a/backend/app/api/routes/users.py b/backend/app/api/routes/users.py index 6429818458..2ff3086675 100644 --- a/backend/app/api/routes/users.py +++ b/backend/app/api/routes/users.py @@ -26,7 +26,7 @@ ) from app.utils import generate_new_account_email, send_email -router = APIRouter(prefix="/users", tags=["users"]) +router = APIRouter() @router.get( diff --git a/backend/app/api/routes/utils.py b/backend/app/api/routes/utils.py index fc093419b3..92f4e047d2 100644 --- a/backend/app/api/routes/utils.py +++ b/backend/app/api/routes/utils.py @@ -1,31 +1,199 @@ -from fastapi import APIRouter, Depends -from pydantic.networks import EmailStr -from app.api.deps import get_current_active_superuser -from app.models import Message -from app.utils import generate_test_email, send_email +import psutil +import time +from datetime import datetime, timedelta +from typing import Any -router = APIRouter(prefix="/utils", tags=["utils"]) +from fastapi import APIRouter, Depends, HTTPException +from sqlmodel import Session, select, func - -@router.post( - "/test-email/", - dependencies=[Depends(get_current_active_superuser)], - status_code=201, +from app.api.deps import CurrentAdmin, SessionDep +from app.models import ( + AISoulEntity, + ChatMessage, + Document, + TrainingDocument, + TrainingMessage, + User, ) -def test_email(email_to: EmailStr) -> Message: +from app.services.enhanced_rag_service import EnhancedRAGService + +router = APIRouter() + + +@router.get("/health-check/", include_in_schema=True) +async def health_check() -> dict: + """ + Health check endpoint to verify the service is running. """ - Test emails. + return {"status": "ok"} + + +@router.get("/system-health/", include_in_schema=True) +async def get_system_health( + *, + db: SessionDep, + current_user: CurrentAdmin, +) -> dict[str, Any]: + """ + Get comprehensive system health metrics. + Only admins can access system health data. """ - email_data = generate_test_email(email_to=email_to) - send_email( - email_to=email_to, - subject=email_data.subject, - html_content=email_data.html_content, - ) - return Message(message="Test email sent") - - -@router.get("/health-check/") -async def health_check() -> bool: - return True + try: + # Get system metrics using psutil + cpu_percent = psutil.cpu_percent(interval=1) + memory = psutil.virtual_memory() + disk = psutil.disk_usage('/') + network = psutil.net_io_counters() + + # Get database statistics + total_users = db.exec(select(func.count(User.id))).one() + total_ai_souls = db.exec(select(func.count(AISoulEntity.id))).one() + total_documents = db.exec(select(func.count(Document.id))).one() + total_training_docs = db.exec(select(func.count(TrainingDocument.id))).one() + total_chat_messages = db.exec(select(func.count(ChatMessage.id))).one() + total_training_messages = db.exec(select(func.count(TrainingMessage.id))).one() + + # Get active connections (approximate) + recent_messages = db.exec( + select(func.count(ChatMessage.id)).where( + ChatMessage.timestamp > datetime.utcnow() - timedelta(hours=1) + ) + ).one() + + # Get RAG service health + rag_service = EnhancedRAGService(db) + rag_health = await rag_service.health_check() + + # Determine service statuses + services = [] + + # Enhanced RAG Service + rag_status = "healthy" if rag_health.get("status") == "healthy" else "degraded" + services.append({ + "name": "Enhanced RAG Service", + "status": rag_status, + "response_time": rag_health.get("response_time_ms", 0), + "last_check": datetime.utcnow().isoformat(), + "uptime": 99.8 if rag_status == "healthy" else 85.0, + "details": rag_health.get("components", {}) + }) + + # Database health (based on successful query) + try: + db_start = time.time() + db.exec(select(func.count(User.id))).one() + db_response_time = int((time.time() - db_start) * 1000) + db_status = "healthy" if db_response_time < 500 else "degraded" + except Exception: + db_status = "down" + db_response_time = 0 + + services.append({ + "name": "PostgreSQL Database", + "status": db_status, + "response_time": db_response_time, + "last_check": datetime.utcnow().isoformat(), + "uptime": 99.5 if db_status == "healthy" else 95.0 + }) + + # Add other services from RAG health check + for component, details in rag_health.get("components", {}).items(): + if component not in ["database", "enhanced_rag"]: + status = "healthy" if details.get("status") == "healthy" else "degraded" + services.append({ + "name": component.replace("_", " ").title(), + "status": status, + "response_time": details.get("response_time_ms", 0), + "last_check": datetime.utcnow().isoformat(), + "uptime": 99.0 if status == "healthy" else 90.0 + }) + + # Calculate network latency (simplified) + network_latency = max(1, min(50, int(cpu_percent / 2))) # Rough estimation + + return { + "status": "healthy" if all(s["status"] in ["healthy", "degraded"] for s in services) else "unhealthy", + "timestamp": datetime.utcnow().isoformat(), + "system_metrics": { + "cpu_usage": round(cpu_percent, 1), + "memory_usage": round(memory.percent, 1), + "disk_usage": round(disk.percent, 1), + "network_latency": network_latency, + "active_connections": recent_messages, + "total_requests": total_chat_messages + total_training_messages, + "memory_total_gb": round(memory.total / (1024**3), 1), + "memory_available_gb": round(memory.available / (1024**3), 1), + "disk_total_gb": round(disk.total / (1024**3), 1), + "disk_free_gb": round(disk.free / (1024**3), 1), + }, + "services": services, + "database_stats": { + "total_users": total_users, + "total_ai_souls": total_ai_souls, + "total_documents": total_documents, + "total_training_documents": total_training_docs, + "total_chat_messages": total_chat_messages, + "total_training_messages": total_training_messages, + "recent_activity": recent_messages + }, + "alerts": _generate_system_alerts(cpu_percent, memory.percent, disk.percent, services) + } + + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Failed to get system health: {str(e)}" + ) + + +def _generate_system_alerts(cpu_usage: float, memory_usage: float, disk_usage: float, services: list) -> list[dict]: + """Generate system alerts based on metrics.""" + alerts = [] + + if cpu_usage > 80: + alerts.append({ + "type": "warning", + "message": f"High CPU usage detected ({cpu_usage:.1f}%)", + "severity": "high" if cpu_usage > 90 else "medium" + }) + + if memory_usage > 80: + alerts.append({ + "type": "warning", + "message": f"High memory usage detected ({memory_usage:.1f}%)", + "severity": "high" if memory_usage > 90 else "medium" + }) + + if disk_usage > 80: + alerts.append({ + "type": "warning", + "message": f"High disk usage detected ({disk_usage:.1f}%)", + "severity": "high" if disk_usage > 90 else "medium" + }) + + # Check for degraded services + degraded_services = [s for s in services if s["status"] == "degraded"] + for service in degraded_services: + alerts.append({ + "type": "warning", + "message": f"{service['name']} performance degraded (response time: {service['response_time']}ms)", + "severity": "medium" + }) + + down_services = [s for s in services if s["status"] == "down"] + for service in down_services: + alerts.append({ + "type": "error", + "message": f"{service['name']} is down", + "severity": "high" + }) + + if not alerts: + alerts.append({ + "type": "info", + "message": "All systems operating normally", + "severity": "low" + }) + + return alerts diff --git a/backend/app/api/utils/health_check.py b/backend/app/api/utils/health_check.py new file mode 100644 index 0000000000..6ac279f86a --- /dev/null +++ b/backend/app/api/utils/health_check.py @@ -0,0 +1,11 @@ +from fastapi import APIRouter + +router = APIRouter() + + +@router.get("/health-check/") +def health_check(): + """ + Health check endpoint to verify the service is running. + """ + return {"status": "ok"} diff --git a/backend/app/celery_app.py b/backend/app/celery_app.py new file mode 100644 index 0000000000..fe6fe71bfe --- /dev/null +++ b/backend/app/celery_app.py @@ -0,0 +1,91 @@ +""" +Celery Application Configuration for AI Soul Entity Backend + +This module configures Celery for background task processing including: +- Document processing and chunking +- Embedding generation +- RAG indexing operations +- Periodic cleanup tasks +""" + +from celery import Celery +from celery.schedules import crontab + +from app.core.config import settings + +# Create Celery instance +celery_app = Celery( + "ai_soul_entity", + broker=settings.REDIS_URL, + backend=settings.REDIS_URL, + include=[ + "app.tasks.document_processing", + "app.tasks.rag_tasks", + "app.tasks.cleanup_tasks", + ] +) + +# Celery configuration +celery_app.conf.update( + # Task routing + task_routes={ + "app.tasks.document_processing.*": {"queue": "document_processing"}, + "app.tasks.rag_tasks.*": {"queue": "rag_processing"}, + "app.tasks.cleanup_tasks.*": {"queue": "cleanup"}, + }, + + # Task serialization + task_serializer="json", + accept_content=["json"], + result_serializer="json", + timezone="UTC", + enable_utc=True, + + # Task execution settings + task_always_eager=False, + task_eager_propagates=True, + task_ignore_result=False, + task_store_eager_result=True, + + # Worker settings + worker_prefetch_multiplier=1, + worker_max_tasks_per_child=1000, + worker_disable_rate_limits=False, + + # Result backend settings + result_expires=3600, # 1 hour + result_backend_transport_options={ + "master_name": "mymaster", + "visibility_timeout": 3600, + }, + + # Beat schedule for periodic tasks + beat_schedule={ + "cleanup-expired-sessions": { + "task": "app.tasks.cleanup_tasks.cleanup_expired_sessions", + "schedule": crontab(minute=0, hour=2), # Daily at 2 AM + }, + "cleanup-old-logs": { + "task": "app.tasks.cleanup_tasks.cleanup_old_processing_logs", + "schedule": crontab(minute=0, hour=3), # Daily at 3 AM + }, + "update-search-analytics": { + "task": "app.tasks.rag_tasks.update_search_analytics", + "schedule": crontab(minute=0, hour=1), # Daily at 1 AM + }, + }, + + # Error handling + task_reject_on_worker_lost=True, + task_acks_late=True, + + # Monitoring + worker_send_task_events=True, + task_send_sent_event=True, +) + +# Auto-discover tasks +celery_app.autodiscover_tasks() + +if __name__ == "__main__": + celery_app.start() diff --git a/backend/app/core/config.py b/backend/app/core/config.py index d58e03c87d..b6e007aeeb 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -51,7 +51,7 @@ def all_cors_origins(self) -> list[str]: PROJECT_NAME: str SENTRY_DSN: HttpUrl | None = None - POSTGRES_SERVER: str + POSTGRES_SERVER: str = "db" POSTGRES_PORT: int = 5432 POSTGRES_USER: str POSTGRES_PASSWORD: str = "" @@ -95,6 +95,38 @@ def emails_enabled(self) -> bool: FIRST_SUPERUSER: EmailStr FIRST_SUPERUSER_PASSWORD: str + # OpenAI Configuration + OPENAI_API_KEY: str | None = None + + # Cohere Configuration + COHERE_API_KEY: str | None = None + COHERE_CHAT_MODEL: str = "command-r-plus" + COHERE_EMBED_MODEL: str = "embed-english-v3.0" + + # Qdrant Configuration + QDRANT_URL: str = "http://qdrant:6333" + + # Redis Configuration + REDIS_URL: str = "redis://redis:6379" + + # File Upload Settings + MAX_FILE_SIZE_MB: int = 10 + MAX_UPLOAD_SIZE: int = 10 * 1024 * 1024 # 10MB in bytes + UPLOAD_DIR: str = "./uploads" + + # RAG Settings + CHUNK_SIZE: int = 1000 + CHUNK_OVERLAP: int = 200 + SIMILARITY_THRESHOLD: float = 0.7 + MAX_CONTEXT_TOKENS: int = 8000 + + # Content Filtering + CONTENT_FILTER_ENABLED: bool = True + CRISIS_RESOURCES_ENABLED: bool = True + + # Analytics + ANALYTICS_ENABLED: bool = True + def _check_default_secret(self, var_name: str, value: str | None) -> None: if value == "changethis": message = ( diff --git a/backend/app/main.py b/backend/app/main.py index 9a95801e74..32f5ed21f3 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -8,7 +8,8 @@ def custom_generate_unique_id(route: APIRoute) -> str: - return f"{route.tags[0]}-{route.name}" + tag = route.tags[0] if route.tags else "untagged" + return f"{tag}-{route.name}" if settings.SENTRY_DSN and settings.ENVIRONMENT != "local": @@ -30,4 +31,12 @@ def custom_generate_unique_id(route: APIRoute) -> str: allow_headers=["*"], ) +# Add health check endpoint +@app.get("/api/utils/health-check/") +async def health_check() -> dict: + """ + Health check endpoint to verify the service is running. + """ + return {"status": "ok"} + app.include_router(api_router, prefix=settings.API_V1_STR) diff --git a/backend/app/models.py b/backend/app/models.py index 2389b4a532..2e55c22881 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -1,7 +1,11 @@ import uuid +from datetime import datetime +from typing import Optional from pydantic import EmailStr from sqlmodel import Field, Relationship, SQLModel +from enum import Enum +from sqlalchemy import UniqueConstraint # Shared properties @@ -15,6 +19,7 @@ class UserBase(SQLModel): # Properties to receive via API on creation class UserCreate(UserBase): password: str = Field(min_length=8, max_length=40) + role: str = Field(default="user", max_length=20) # "user", "trainer", "counselor", "admin", "super_admin" class UserRegister(SQLModel): @@ -27,6 +32,7 @@ class UserRegister(SQLModel): class UserUpdate(UserBase): email: EmailStr | None = Field(default=None, max_length=255) # type: ignore password: str | None = Field(default=None, min_length=8, max_length=40) + role: str | None = Field(default=None, max_length=20) # Allow role updates by admin class UserUpdateMe(SQLModel): @@ -43,12 +49,23 @@ class UpdatePassword(SQLModel): class User(UserBase, table=True): id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) hashed_password: str + role: str = Field(default="user", max_length=20) # "user", "trainer", "counselor", "admin", "super_admin" + organization_id: uuid.UUID | None = Field( + default=None, foreign_key="organization.id", ondelete="SET NULL" + ) + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow) items: list["Item"] = Relationship(back_populates="owner", cascade_delete=True) + ai_souls: list["AISoulEntity"] = Relationship(back_populates="user", cascade_delete=True) + organization: Optional["Organization"] = Relationship(back_populates="users") # Properties to return via API, id is always required class UserPublic(UserBase): id: uuid.UUID + role: str + created_at: datetime + updated_at: datetime class UsersPublic(SQLModel): @@ -111,3 +128,866 @@ class TokenPayload(SQLModel): class NewPassword(SQLModel): token: str new_password: str = Field(min_length=8, max_length=40) + + +# Chat Message models +class ChatMessageBase(SQLModel): + content: str = Field(min_length=1, max_length=5000) + + +class ChatMessageCreate(ChatMessageBase): + pass + + +class ChatMessage(ChatMessageBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + is_from_user: bool = Field(default=True) + timestamp: datetime = Field(default_factory=datetime.utcnow) + + user: User | None = Relationship() + ai_soul: Optional["AISoulEntity"] = Relationship(back_populates="chat_messages") + + +class ChatMessagePublic(ChatMessageBase): + id: uuid.UUID | None # None for temporary messages + user_id: uuid.UUID + ai_soul_id: uuid.UUID + is_from_user: bool + timestamp: datetime + is_temporary: bool = False # Flag to indicate temporary "under review" messages + + +# Document/PDF models for RAG +class DocumentBase(SQLModel): + filename: str = Field(max_length=255) + original_filename: str = Field(max_length=255) + file_size: int + content_type: str = Field(max_length=100) + description: str | None = Field(default=None, max_length=500) + + +class DocumentCreate(DocumentBase): + pass + + +class Document(DocumentBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + file_path: str = Field(max_length=500) + upload_timestamp: datetime = Field(default_factory=datetime.utcnow) + processing_status: str = Field(default="pending", max_length=50) + chunk_count: int = Field(default=0) + user: User | None = Relationship() + + +class DocumentPublic(DocumentBase): + id: uuid.UUID + user_id: uuid.UUID + upload_timestamp: datetime + processing_status: str + chunk_count: int + + +# Document chunks for RAG embeddings +class DocumentChunkBase(SQLModel): + content: str = Field(min_length=1, max_length=2000) + chunk_index: int + chunk_metadata: str | None = Field(default=None, max_length=1000) + + +class DocumentChunk(DocumentChunkBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + document_id: uuid.UUID = Field( + foreign_key="document.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + embedding: str | None = Field(default=None, max_length=50000) # JSON string of embedding vector + created_at: datetime = Field(default_factory=datetime.utcnow) + document: Document | None = Relationship() + + +class DocumentChunkPublic(DocumentChunkBase): + id: uuid.UUID + document_id: uuid.UUID + user_id: uuid.UUID + created_at: datetime + + +class DocumentsPublic(SQLModel): + data: list[DocumentPublic] + count: int + + +# AI Soul Entity models +class AISoulEntityBase(SQLModel): + name: str = Field(max_length=255) + description: str | None = Field(default=None, max_length=1000) + persona_type: str = Field(max_length=50) # e.g., counselor, mentor, coach + specializations: str = Field(max_length=500) # Comma-separated list of specialties + base_prompt: str = Field(max_length=5000) # Custom system prompt for this soul + is_active: bool = Field(default=True) + + +class AISoulEntity(AISoulEntityBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow) + last_used: datetime | None = Field(default=None) + interaction_count: int = Field(default=0) + + user: User | None = Relationship(back_populates="ai_souls") + chat_messages: list["ChatMessage"] = Relationship(back_populates="ai_soul", cascade_delete=True) + training_messages: list["TrainingMessage"] = Relationship(back_populates="ai_soul", cascade_delete=True) + training_documents: list["TrainingDocument"] = Relationship(back_populates="ai_soul", cascade_delete=True) + user_interactions: list["UserAISoulInteraction"] = Relationship(back_populates="ai_soul", cascade_delete=True) + + +class AISoulEntityCreate(SQLModel): + name: str = Field(max_length=255) + description: str | None = Field(default=None, max_length=1000) + persona_type: str = Field(max_length=50) + specializations: str = Field(max_length=500) + base_prompt: str | None = Field(default=None, max_length=5000) + + +class AISoulEntityUpdate(SQLModel): + name: str | None = None + description: str | None = None + persona_type: str | None = None + specializations: str | None = None + base_prompt: str | None = None + is_active: bool | None = None + + +class AISoulEntityPublic(AISoulEntityBase): + id: uuid.UUID + user_id: uuid.UUID + created_at: datetime + updated_at: datetime + last_used: datetime | None + interaction_count: int + + +class AISoulEntityWithUserInteraction(AISoulEntityBase): + """AI Soul Entity with user-specific interaction count for role-based responses""" + id: uuid.UUID + user_id: uuid.UUID + created_at: datetime + updated_at: datetime + last_used: datetime | None + interaction_count: int # This will be either global or user-specific based on role + + +# Training Message models for AI Soul training +class TrainingMessageBase(SQLModel): + content: str = Field(min_length=1, max_length=5000) + is_from_trainer: bool = Field(default=True) # True if from the person training the AI soul + + +class TrainingMessage(TrainingMessageBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + timestamp: datetime = Field(default_factory=datetime.utcnow) + embedding: str | None = Field(default=None, max_length=50000) # JSON string of embedding vector + + ai_soul: AISoulEntity | None = Relationship() + user: User | None = Relationship() + + +class TrainingMessageCreate(TrainingMessageBase): + pass + + +class TrainingMessagePublic(TrainingMessageBase): + id: uuid.UUID + ai_soul_id: uuid.UUID + user_id: uuid.UUID + timestamp: datetime + + +# Training Document models for AI Soul training +class TrainingDocumentBase(SQLModel): + filename: str = Field(max_length=255) + original_filename: str = Field(max_length=255) + file_size: int + content_type: str = Field(max_length=100) + description: str | None = Field(default=None, max_length=500) + + +class TrainingDocument(TrainingDocumentBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + file_path: str = Field(max_length=500) + upload_timestamp: datetime = Field(default_factory=datetime.utcnow) + processing_status: str = Field(default="pending", max_length=50) + chunk_count: int = Field(default=0) + + ai_soul: AISoulEntity | None = Relationship() + user: User | None = Relationship() + + +class TrainingDocumentCreate(TrainingDocumentBase): + pass + + +class TrainingDocumentPublic(TrainingDocumentBase): + id: uuid.UUID + ai_soul_id: uuid.UUID + user_id: uuid.UUID + upload_timestamp: datetime + processing_status: str + chunk_count: int + + +# Training Document chunks for AI Soul training +class TrainingDocumentChunk(SQLModel, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + training_document_id: uuid.UUID = Field( + foreign_key="trainingdocument.id", nullable=False, ondelete="CASCADE" + ) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + content: str = Field(min_length=1, max_length=10000) # Increased from 2000 to 10000 + chunk_index: int + chunk_metadata: str | None = Field(default=None, max_length=5000) # Increased from 1000 to 5000 + embedding: str | None = Field(default=None, max_length=50000) # JSON string of embedding vector + created_at: datetime = Field(default_factory=datetime.utcnow) + + training_document: TrainingDocument | None = Relationship() + ai_soul: AISoulEntity | None = Relationship() + user: User | None = Relationship() + + +# Enhanced RAG System Models for better search and analytics + +# Search Query Analytics +class SearchQueryBase(SQLModel): + query_text: str = Field(max_length=1000) + ai_soul_id: uuid.UUID | None = Field(default=None, foreign_key="aisoulentity.id") + filters_applied: str | None = Field(default=None, max_length=2000) # JSON string + results_count: int = Field(default=0) + response_time_ms: int = Field(default=0) + user_clicked_result: bool = Field(default=False) + relevance_feedback: float | None = Field(default=None) # User feedback score 1-5 + + +class SearchQuery(SearchQueryBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + created_at: datetime = Field(default_factory=datetime.utcnow) + + user: User | None = Relationship() + ai_soul: AISoulEntity | None = Relationship() + + +class SearchQueryPublic(SearchQueryBase): + id: uuid.UUID + user_id: uuid.UUID + created_at: datetime + + +# Enhanced Document Chunk with semantic metadata +class DocumentChunkEnhanced(SQLModel, table=True): + __tablename__ = "document_chunk_enhanced" + + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + document_id: uuid.UUID = Field( + foreign_key="document.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + + # Content and indexing + content: str = Field(min_length=1, max_length=4000) # Increased from 2000 + chunk_index: int + + # Semantic metadata (JSON fields for flexibility) + chunk_metadata: str | None = Field(default=None, max_length=5000) # Increased from 1000 + semantic_metadata: str | None = Field(default=None, max_length=3000) # New field + + # Embedding and search data + embedding_model: str = Field(default="text-embedding-3-small", max_length=100) + embedding_dimension: int = Field(default=1536) + + # Performance tracking + search_count: int = Field(default=0) # How many times this chunk was returned + click_count: int = Field(default=0) # How many times user clicked on this chunk + relevance_score: float | None = Field(default=None) # Average user feedback + + # Timestamps + created_at: datetime = Field(default_factory=datetime.utcnow) + last_accessed: datetime | None = Field(default=None) + + # Relationships + document: Document | None = Relationship() + user: User | None = Relationship() + + +# Document processing analytics +class DocumentProcessingLog(SQLModel, table=True): + __tablename__ = "document_processing_log" + + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + document_id: uuid.UUID = Field( + foreign_key="document.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + + # Processing details + processing_stage: str = Field(max_length=50) # "text_extraction", "chunking", "embedding", "indexing" + status: str = Field(max_length=20) # "started", "completed", "failed" + processing_time_ms: int | None = Field(default=None) + + # Metrics + chunks_created: int | None = Field(default=None) + total_tokens: int | None = Field(default=None) + embedding_cost: float | None = Field(default=None) + + # Error handling + error_message: str | None = Field(default=None, max_length=2000) + retry_count: int = Field(default=0) + + # Timestamps + created_at: datetime = Field(default_factory=datetime.utcnow) + completed_at: datetime | None = Field(default=None) + + # Relationships + document: Document | None = Relationship() + user: User | None = Relationship() + + +# Search result click tracking +class SearchResultClick(SQLModel, table=True): + __tablename__ = "search_result_click" + + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + search_query_id: uuid.UUID = Field( + foreign_key="searchquery.id", nullable=False, ondelete="CASCADE" + ) + chunk_id: uuid.UUID = Field( + foreign_key="document_chunk_enhanced.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + + # Click details + result_position: int # Position in search results (1-based) + similarity_score: float # Cosine similarity score + rerank_score: float | None = Field(default=None) # Cross-encoder score + + # User engagement + time_spent_ms: int | None = Field(default=None) # Time spent viewing the result + user_rating: int | None = Field(default=None) # 1-5 star rating + + # Timestamps + clicked_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + search_query: SearchQuery | None = Relationship() + chunk: DocumentChunkEnhanced | None = Relationship() + user: User | None = Relationship() + + +# Enhanced Training Document Chunks (similar enhancements for training data) +class TrainingDocumentChunkEnhanced(SQLModel, table=True): + __tablename__ = "training_document_chunk_enhanced" + + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + training_document_id: uuid.UUID = Field( + foreign_key="trainingdocument.id", nullable=False, ondelete="CASCADE" + ) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + + # Content and indexing + content: str = Field(min_length=1, max_length=4000) + chunk_index: int + + # Enhanced metadata + chunk_metadata: str | None = Field(default=None, max_length=5000) + semantic_metadata: str | None = Field(default=None, max_length=3000) + + # Embedding info + embedding_model: str = Field(default="text-embedding-3-small", max_length=100) + embedding_dimension: int = Field(default=1536) + + # Training-specific fields + training_importance: float | None = Field(default=None) # How important for training + usage_count: int = Field(default=0) # How many times used in training + + # Timestamps + created_at: datetime = Field(default_factory=datetime.utcnow) + last_used: datetime | None = Field(default=None) + + # Relationships + training_document: TrainingDocument | None = Relationship() + ai_soul: AISoulEntity | None = Relationship() + user: User | None = Relationship() + + +# RAG System Configuration +class RAGConfiguration(SQLModel, table=True): + __tablename__ = "rag_configuration" + + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + ai_soul_id: uuid.UUID | None = Field( + default=None, foreign_key="aisoulentity.id", ondelete="CASCADE" + ) + + # Configuration settings (JSON) + chunking_strategy: str = Field(default="semantic", max_length=50) + chunk_size: int = Field(default=500) + chunk_overlap: int = Field(default=50) + embedding_model: str = Field(default="text-embedding-3-small", max_length=100) + + # Search settings + search_algorithm: str = Field(default="hybrid", max_length=50) + similarity_threshold: float = Field(default=0.7) + max_results: int = Field(default=10) + enable_reranking: bool = Field(default=True) + + # Advanced settings (JSON string) + advanced_settings: str | None = Field(default=None, max_length=5000) + + # Timestamps + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + user: User | None = Relationship() + ai_soul: AISoulEntity | None = Relationship() + + +# ============================================================================= +# COUNSELOR OVERRIDE & MONITORING SYSTEM MODELS +# ============================================================================= + +# Organization/Tenant models for multi-tenant support +class OrganizationBase(SQLModel): + name: str = Field(max_length=255) + domain: str = Field(max_length=255, unique=True) # e.g., "church-name.com" + description: str | None = Field(default=None, max_length=1000) + is_active: bool = Field(default=True) + max_users: int = Field(default=100) # Subscription limits + max_ai_souls: int = Field(default=10) + settings: str | None = Field(default=None, max_length=5000) # JSON configuration + + +class Organization(OrganizationBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + users: list["User"] = Relationship(back_populates="organization") + counselors: list["Counselor"] = Relationship(back_populates="organization") + + +class OrganizationPublic(OrganizationBase): + id: uuid.UUID + created_at: datetime + updated_at: datetime + + +# Enhanced User model with organization and role support +# Note: We'll extend the existing User model in a migration +class UserRole(str, Enum): + USER = "user" + TRAINER = "trainer" + COUNSELOR = "counselor" + ADMIN = "admin" + SUPER_ADMIN = "super_admin" + + +# Counselor model for specialized counselor users +class CounselorBase(SQLModel): + specializations: str = Field(max_length=500) # Comma-separated specialties + license_number: str | None = Field(default=None, max_length=100) + license_type: str | None = Field(default=None, max_length=100) + is_available: bool = Field(default=True) + max_concurrent_cases: int = Field(default=10) + notification_preferences: str | None = Field(default=None, max_length=2000) # JSON + + +class Counselor(CounselorBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + organization_id: uuid.UUID = Field( + foreign_key="organization.id", nullable=False, ondelete="CASCADE" + ) + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + user: User | None = Relationship() + organization: Organization | None = Relationship(back_populates="counselors") + pending_responses: list["PendingResponse"] = Relationship(back_populates="assigned_counselor") + + +class CounselorPublic(CounselorBase): + id: uuid.UUID + user_id: uuid.UUID + organization_id: uuid.UUID + created_at: datetime + updated_at: datetime + + +# Risk Assessment model for AI conversations +class RiskAssessmentBase(SQLModel): + risk_level: str = Field(max_length=20) # "low", "medium", "high", "critical" + risk_categories: str = Field(max_length=500) # JSON array of risk types + confidence_score: float = Field(ge=0.0, le=1.0) + reasoning: str | None = Field(default=None, max_length=2000) + requires_human_review: bool = Field(default=False) + auto_response_blocked: bool = Field(default=False) + + +class RiskAssessment(RiskAssessmentBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + chat_message_id: uuid.UUID = Field( + foreign_key="chatmessage.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + organization_id: uuid.UUID | None = Field( + default=None, foreign_key="organization.id", ondelete="CASCADE" + ) + assessed_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + chat_message: ChatMessage | None = Relationship() + user: User | None = Relationship() + ai_soul: AISoulEntity | None = Relationship() + organization: Organization | None = Relationship() + + +class RiskAssessmentPublic(RiskAssessmentBase): + id: uuid.UUID + chat_message_id: uuid.UUID + user_id: uuid.UUID + ai_soul_id: uuid.UUID + organization_id: uuid.UUID | None + assessed_at: datetime + + +# Pending Response model for counselor review queue +class PendingResponseBase(SQLModel): + original_user_message: str = Field(max_length=5000) + ai_generated_response: str = Field(max_length=5000) + status: str = Field(default="pending", max_length=20) # "pending", "approved", "modified", "rejected" + priority: str = Field(default="normal", max_length=20) # "low", "normal", "high", "urgent" + counselor_notes: str | None = Field(default=None, max_length=2000) + modified_response: str | None = Field(default=None, max_length=5000) + response_time_limit: datetime | None = Field(default=None) # Auto-approve after this time + + +class PendingResponse(PendingResponseBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + chat_message_id: uuid.UUID = Field( + foreign_key="chatmessage.id", nullable=False, ondelete="CASCADE" + ) + risk_assessment_id: uuid.UUID = Field( + foreign_key="riskassessment.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + assigned_counselor_id: uuid.UUID | None = Field( + default=None, foreign_key="counselor.id", ondelete="SET NULL" + ) + organization_id: uuid.UUID | None = Field( + default=None, foreign_key="organization.id", ondelete="CASCADE" + ) + created_at: datetime = Field(default_factory=datetime.utcnow) + reviewed_at: datetime | None = Field(default=None) + + # Relationships + chat_message: ChatMessage | None = Relationship() + risk_assessment: RiskAssessment | None = Relationship() + user: User | None = Relationship() + ai_soul: AISoulEntity | None = Relationship() + assigned_counselor: Counselor | None = Relationship(back_populates="pending_responses") + organization: Organization | None = Relationship() + + +class PendingResponsePublic(PendingResponseBase): + id: uuid.UUID + chat_message_id: uuid.UUID + risk_assessment_id: uuid.UUID + user_id: uuid.UUID + ai_soul_id: uuid.UUID + assigned_counselor_id: uuid.UUID | None + organization_id: uuid.UUID | None + created_at: datetime + reviewed_at: datetime | None + + +# Counselor Action Log for audit trail +class CounselorActionBase(SQLModel): + action_type: str = Field(max_length=50) # "approved", "modified", "rejected", "escalated" + original_response: str | None = Field(default=None, max_length=5000) + final_response: str | None = Field(default=None, max_length=5000) + reason: str | None = Field(default=None, max_length=1000) + time_taken_seconds: int | None = Field(default=None) + + +class CounselorAction(CounselorActionBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + counselor_id: uuid.UUID = Field( + foreign_key="counselor.id", nullable=False, ondelete="CASCADE" + ) + pending_response_id: uuid.UUID = Field( + foreign_key="pendingresponse.id", nullable=False, ondelete="CASCADE" + ) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + organization_id: uuid.UUID | None = Field( + default=None, foreign_key="organization.id", ondelete="CASCADE" + ) + created_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + counselor: Counselor | None = Relationship() + pending_response: PendingResponse | None = Relationship() + user: User | None = Relationship() + organization: Organization | None = Relationship() + + +class CounselorActionPublic(CounselorActionBase): + id: uuid.UUID + counselor_id: uuid.UUID + pending_response_id: uuid.UUID + user_id: uuid.UUID + organization_id: uuid.UUID | None + created_at: datetime + + +# ============================================================================= +# ANALYTICS SYSTEM MODELS +# ============================================================================= + +# Conversation Analytics for tracking usage patterns +class ConversationAnalyticsBase(SQLModel): + conversation_duration_seconds: int | None = Field(default=None) + message_count: int = Field(default=0) + ai_response_count: int = Field(default=0) + risk_assessments_triggered: int = Field(default=0) + counselor_interventions: int = Field(default=0) + user_satisfaction_score: float | None = Field(default=None, ge=1.0, le=5.0) + topic_categories: str | None = Field(default=None, max_length=1000) # JSON array + + +class ConversationAnalytics(ConversationAnalyticsBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + organization_id: uuid.UUID | None = Field( + default=None, foreign_key="organization.id", ondelete="CASCADE" + ) + session_start: datetime = Field(default_factory=datetime.utcnow) + session_end: datetime | None = Field(default=None) + created_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + user: User | None = Relationship() + ai_soul: AISoulEntity | None = Relationship() + organization: Organization | None = Relationship() + + +class ConversationAnalyticsPublic(ConversationAnalyticsBase): + id: uuid.UUID + user_id: uuid.UUID + ai_soul_id: uuid.UUID + organization_id: uuid.UUID | None + session_start: datetime + session_end: datetime | None + created_at: datetime + + +# Daily Usage Metrics for dashboard analytics +class DailyUsageMetricsBase(SQLModel): + date: datetime = Field(index=True) + total_conversations: int = Field(default=0) + total_messages: int = Field(default=0) + unique_users: int = Field(default=0) + ai_responses_generated: int = Field(default=0) + counselor_interventions: int = Field(default=0) + high_risk_conversations: int = Field(default=0) + average_response_time_ms: float | None = Field(default=None) + user_satisfaction_average: float | None = Field(default=None) + + +class DailyUsageMetrics(DailyUsageMetricsBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + organization_id: uuid.UUID | None = Field( + default=None, foreign_key="organization.id", ondelete="CASCADE" + ) + created_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + organization: Organization | None = Relationship() + + +class DailyUsageMetricsPublic(DailyUsageMetricsBase): + id: uuid.UUID + organization_id: uuid.UUID | None + created_at: datetime + + +# Counselor Performance Metrics +class CounselorPerformanceBase(SQLModel): + date: datetime = Field(index=True) + cases_reviewed: int = Field(default=0) + average_review_time_seconds: float | None = Field(default=None) + approvals: int = Field(default=0) + modifications: int = Field(default=0) + rejections: int = Field(default=0) + escalations: int = Field(default=0) + user_feedback_score: float | None = Field(default=None, ge=1.0, le=5.0) + + +class CounselorPerformance(CounselorPerformanceBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + counselor_id: uuid.UUID = Field( + foreign_key="counselor.id", nullable=False, ondelete="CASCADE" + ) + organization_id: uuid.UUID | None = Field( + default=None, foreign_key="organization.id", ondelete="CASCADE" + ) + created_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + counselor: Counselor | None = Relationship() + organization: Organization | None = Relationship() + + +class CounselorPerformancePublic(CounselorPerformanceBase): + id: uuid.UUID + counselor_id: uuid.UUID + organization_id: uuid.UUID | None + created_at: datetime + + +# Content Filter Analytics for tracking blocked content +class ContentFilterAnalyticsBase(SQLModel): + filter_type: str = Field(max_length=50) # "profanity", "violence", "self_harm", etc. + content_sample: str | None = Field(default=None, max_length=500) # Anonymized sample + severity_level: str = Field(max_length=20) # "low", "medium", "high" + action_taken: str = Field(max_length=50) # "blocked", "warned", "flagged" + false_positive: bool | None = Field(default=None) # Manual review result + + +class ContentFilterAnalytics(ContentFilterAnalyticsBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + organization_id: uuid.UUID | None = Field( + default=None, foreign_key="organization.id", ondelete="CASCADE" + ) + detected_at: datetime = Field(default_factory=datetime.utcnow) + + # Relationships + user: User | None = Relationship() + ai_soul: AISoulEntity | None = Relationship() + organization: Organization | None = Relationship() + + +class ContentFilterAnalyticsPublic(ContentFilterAnalyticsBase): + id: uuid.UUID + user_id: uuid.UUID + ai_soul_id: uuid.UUID + organization_id: uuid.UUID | None + detected_at: datetime + + +# User-specific interaction tracking +class UserAISoulInteractionBase(SQLModel): + interaction_count: int = Field(default=0) + last_interaction: datetime | None = Field(default=None) + + +class UserAISoulInteraction(UserAISoulInteractionBase, table=True): + __tablename__ = "user_ai_soul_interaction" + + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + ai_soul_id: uuid.UUID = Field( + foreign_key="aisoulentity.id", nullable=False, ondelete="CASCADE" + ) + created_at: datetime = Field(default_factory=datetime.utcnow) + updated_at: datetime = Field(default_factory=datetime.utcnow) + + user: User | None = Relationship() + ai_soul: AISoulEntity | None = Relationship(back_populates="user_interactions") + + __table_args__ = ( + UniqueConstraint("user_id", "ai_soul_id", name="unique_user_ai_soul"), + ) + + +class UserAISoulInteractionPublic(UserAISoulInteractionBase): + id: uuid.UUID + user_id: uuid.UUID + ai_soul_id: uuid.UUID + created_at: datetime + updated_at: datetime diff --git a/backend/app/services/__init__.py b/backend/app/services/__init__.py new file mode 100644 index 0000000000..0557eb635c --- /dev/null +++ b/backend/app/services/__init__.py @@ -0,0 +1 @@ +# Services module diff --git a/backend/app/services/ai_soul_service.py b/backend/app/services/ai_soul_service.py new file mode 100644 index 0000000000..f7aa590385 --- /dev/null +++ b/backend/app/services/ai_soul_service.py @@ -0,0 +1,482 @@ +import logging +from datetime import datetime +from typing import Any + +from openai import OpenAI +from sqlmodel import Session, select + +from app.core.config import settings +from app.models import AISoulEntity, ChatMessage, User +from app.services.enhanced_rag_service import EnhancedRAGService + +logger = logging.getLogger(__name__) + + +class AISoulService: + def __init__(self): + if not settings.OPENAI_API_KEY: + raise ValueError("OpenAI API key is required") + self.client = OpenAI(api_key=settings.OPENAI_API_KEY) + + def get_user_context(self, session: Session, user_id: str, ai_soul_id: str) -> dict[str, Any]: + """ + Build user context from chat history and profile for personalized responses + """ + # Get user and AI soul info + user = session.get(User, user_id) + ai_soul = session.get(AISoulEntity, ai_soul_id) + if not user or not ai_soul: + return {} + + # Get recent chat history for this specific AI soul + statement = ( + select(ChatMessage) + .where(ChatMessage.user_id == user_id, ChatMessage.ai_soul_id == ai_soul_id) + .order_by(ChatMessage.timestamp.desc()) + .limit(50) + ) + messages = session.exec(statement).all() + + # Build context from user messages only + user_messages = [msg.content for msg in messages if msg.is_from_user] + + # Analyze conversation patterns + context = { + "user_name": user.full_name, + "user_email": user.email, + "ai_soul_name": ai_soul.name, + "ai_soul_persona": ai_soul.persona_type, + "ai_soul_specializations": ai_soul.specializations.split(","), + "message_count": len(user_messages), + "recent_topics": self._extract_topics(user_messages[:10]), + "conversation_style": self._analyze_style(user_messages), + "professional_focus": self._extract_professional_focus(user_messages), + "values_and_beliefs": self._extract_values(user_messages), + } + + return context + + def _extract_topics(self, messages: list[str]) -> list[str]: + """Extract key topics from recent messages""" + topics = [] + keywords = { + "counseling": ["counseling", "therapy", "counselor", "therapist"], + "parenting": ["parenting", "children", "kids", "family"], + "relationships": ["relationship", "marriage", "dating", "partner"], + "spiritual": ["spiritual", "christian", "bible", "god", "faith", "prayer"], + "career": ["career", "job", "work", "professional"], + "emotions": ["emotion", "feeling", "depression", "anxiety", "stress"], + "education": ["education", "learning", "teaching", "school"], + "finance": ["money", "financial", "budget", "investment"], + } + + for message in messages: + message_lower = message.lower() + for topic, topic_keywords in keywords.items(): + if any(keyword in message_lower for keyword in topic_keywords): + if topic not in topics: + topics.append(topic) + + return topics + + def _analyze_style(self, messages: list[str]) -> str: + """Analyze the user's communication style""" + if not messages: + return "supportive" + + # Simple analysis based on message characteristics + avg_length = sum(len(msg) for msg in messages) / len(messages) + question_ratio = sum(1 for msg in messages if "?" in msg) / len(messages) + + if avg_length > 200: + return "detailed" + elif question_ratio > 0.5: + return "inquisitive" + else: + return "supportive" + + def _extract_professional_focus(self, messages: list[str]) -> list[str]: + """Extract professional areas of focus""" + focus_areas = [] + combined_text = " ".join(messages).lower() + + areas = { + "christian_counseling": ["christian", "bible", "scripture", "faith", "god"], + "parenting": ["parenting", "children", "kids", "family"], + "relationships": ["relationship", "marriage", "couples"], + "grief": ["grief", "loss", "death", "mourning"], + "addiction": ["addiction", "substance", "recovery"], + "anxiety": ["anxiety", "worry", "fear", "panic"], + "depression": ["depression", "sad", "hopeless"], + } + + for area, keywords in areas.items(): + if any(keyword in combined_text for keyword in keywords): + focus_areas.append(area.replace("_", " ")) + + return focus_areas + + def _extract_values(self, messages: list[str]) -> list[str]: + """Extract values and beliefs from messages""" + values = [] + combined_text = " ".join(messages).lower() + + value_keywords = { + "empathy": ["empathy", "understanding", "compassion", "caring"], + "family": ["family", "children", "parenting", "home"], + "faith": ["faith", "spiritual", "christian", "bible", "god"], + "growth": ["growth", "learning", "development", "progress"], + "healing": ["healing", "recovery", "wellness", "health"], + "community": ["community", "together", "support", "help"], + } + + for value, keywords in value_keywords.items(): + if any(keyword in combined_text for keyword in keywords): + values.append(value) + + return values + + async def generate_ai_response(self, session: Session, user_id: str, ai_soul_id: str, user_message: str, risk_assessment: dict = None) -> str: + """ + Generate AI Soul Entity response with enhanced context management and crisis handling + """ + try: + # Get user context and AI soul + context = self.get_user_context(session, user_id, ai_soul_id) + ai_soul = session.get(AISoulEntity, ai_soul_id) + if not ai_soul: + return "Error: AI Soul Entity not found" + + # Detect if this is a critical case requiring enhanced response + is_critical_case = False + if risk_assessment: + is_critical_case = risk_assessment.get("risk_level") in ["high", "critical"] + + # Search for relevant document content (RAG) + relevant_content = await self._search_relevant_documents(session, user_id, user_message) + + # Search for relevant training data (personalized knowledge) + training_data = await self._search_training_data(session, ai_soul_id, user_message) + + # Build enhanced conversation history with context window management + conversation_history = self._build_conversation_history_with_context_management( + session, user_id, ai_soul_id, user_message + ) + + # Build system prompt based on AI soul's persona and context + system_prompt = self._build_system_prompt(ai_soul, context, relevant_content, training_data, is_critical_case) + + # Calculate token usage and manage context window + messages = self._manage_context_window([ + {"role": "system", "content": system_prompt}, + *conversation_history, + {"role": "user", "content": user_message} + ]) + + # Adjust generation parameters for critical cases + if is_critical_case: + # Use more conservative parameters for critical cases + response = self.client.chat.completions.create( + model="gpt-4", + messages=messages, + max_tokens=1000, # More space for comprehensive crisis response + temperature=0.3, # Lower temperature for more consistent, empathetic responses + presence_penalty=0.2, + frequency_penalty=0.1, + top_p=0.8 # More focused responses for critical cases + ) + else: + # Standard parameters for regular conversations + response = self.client.chat.completions.create( + model="gpt-4", + messages=messages, + max_tokens=800, # Increased for more detailed responses + temperature=0.7, + presence_penalty=0.1, + frequency_penalty=0.1, + top_p=0.9 # Added for better response quality + ) + + # Update AI soul's usage statistics + ai_soul.last_used = datetime.utcnow() + # Note: interaction_count is incremented in the chat route when user sends a message + # This ensures we count conversation pairs (user message + AI response) as 1 interaction + session.add(ai_soul) + session.commit() + + generated_response = response.choices[0].message.content.strip() + + # Log critical case handling + if is_critical_case: + logger.info(f"Generated enhanced response for critical case - User: {user_id}, AI Soul: {ai_soul_id}, Risk Level: {risk_assessment.get('risk_level')}") + + return generated_response + + except Exception as e: + logger.error(f"Error generating AI response: {str(e)}") + return "I apologize, I'm having trouble processing your message right now. Please try again." + + async def _search_relevant_documents(self, session: Session, user_id: str, query: str) -> list[str]: + """Search for relevant document content using Enhanced RAG""" + try: + rag_service = EnhancedRAGService(session) + search_response = await rag_service.hybrid_search( + query=query, + user_id=user_id, + limit=3 + ) + + relevant_content = [] + for result in search_response.get("results", []): + content = result["content"] + # Truncate content if too long for context + if len(content) > 300: + content = content[:300] + "..." + source = result.get("metadata", {}).get("source", "Document") + relevant_content.append(f"From {source}: {content}") + + return relevant_content + except Exception as e: + logger.error(f"Error searching documents with Enhanced RAG: {str(e)}") + return [] + + async def _search_training_data(self, session: Session, ai_soul_id: str, query: str) -> list[str]: + """Search for relevant training data for the AI soul""" + try: + from app.services.training_service import TrainingService + training_service = TrainingService(session) + + # Get the AI soul owner's user ID + ai_soul = session.get(AISoulEntity, ai_soul_id) + if not ai_soul: + return [] + + training_results = await training_service.get_training_data( + ai_soul_id=ai_soul_id, + user_id=str(ai_soul.user_id), + query=query, + limit=5 + ) + + training_content = [] + for result in training_results: + if result["type"] == "message": + role = "trainer" if result["is_from_trainer"] else "AI" + training_content.append(f"Training conversation ({role}): {result['content']}") + elif result["type"] == "document": + source = result["metadata"].get("source", "training document") + training_content.append(f"From {source}: {result['content']}") + + return training_content + except Exception as e: + logger.error(f"Error searching training data: {str(e)}") + return [] + + def _build_system_prompt(self, ai_soul: AISoulEntity, context: dict[str, Any], relevant_content: list[str] = None, training_data: list[str] = None, is_critical_case: bool = False) -> str: + """Build enhanced system prompt with RAG best practices and crisis handling""" + + # Enhanced crisis handling for critical cases + if is_critical_case: + crisis_prompt = f"""You are {ai_soul.name}, an AI Soul Entity specialized as a {ai_soul.persona_type}. +Your areas of expertise include: {ai_soul.specializations}. + +**CRITICAL CASE HANDLING - ENHANCED RESPONSE REQUIRED** + +This conversation has been flagged as potentially involving crisis, self-harm, or other serious concerns. Your response must be: + +1. **Empathetic and Non-judgmental**: Show deep understanding and compassion +2. **Supportive but Professional**: Provide emotional support while acknowledging limitations +3. **Crisis-Aware**: Recognize signs of distress and respond appropriately +4. **Resource-Oriented**: Guide toward professional help when needed +5. **Safety-Focused**: Prioritize the person's immediate safety and wellbeing + +**CRITICAL RESPONSE GUIDELINES:** +- Acknowledge their pain and validate their feelings +- Express genuine concern for their wellbeing +- Avoid minimizing their struggles or offering simple solutions +- Encourage professional help for serious concerns +- Provide hope while being realistic +- Use warm, caring language that shows you truly understand +- If they mention self-harm or suicide, take it seriously and provide crisis resources + +Remember: You are a supportive presence, but serious mental health crises require professional intervention.""" + + base_prompt = crisis_prompt + else: + # Start with the soul's custom base prompt if available + if ai_soul.base_prompt: + base_prompt = ai_soul.base_prompt + else: + base_prompt = f"""You are {ai_soul.name}, an AI Soul Entity specialized as a {ai_soul.persona_type}. +Your areas of expertise include: {ai_soul.specializations}. + +You are designed to embody and represent the person described in your training knowledge. When responding, you should act as if you ARE that person, using their background, experiences, and personal information naturally in conversation. You are NOT a generic AI assistant - you are a personalized AI entity trained to represent a specific individual.""" + + # Add user context for personalization + if context.get("user_name"): + base_prompt += f"\n\nYou are currently interacting with {context['user_name']}." + + if context.get("professional_focus"): + base_prompt += f"\nBased on previous conversations, you understand their focus areas: {', '.join(context['professional_focus'])}." + + if context.get("values_and_beliefs"): + base_prompt += f"\nYou are aware of their values and beliefs: {', '.join(context['values_and_beliefs'])}." + + # Add conversation style guidance + style = context.get("conversation_style", "supportive") + base_prompt += f"\nYour communication style should be {style} and authentic to your personality." + + # Enhanced RAG integration with best practices + knowledge_sections = [] + + # Add relevant document content with proper attribution + if relevant_content: + doc_context = "\n".join([f"• {content}" for content in relevant_content]) + knowledge_sections.append(f"""**Document Knowledge:** +{doc_context}""") + + # Add training data with clear instructions for usage + if training_data: + logger.info(f"Adding training data to system prompt: {len(training_data)} items") + training_context = "\n".join([f"• {data}" for data in training_data]) + knowledge_sections.append(f"""**Personal Training Knowledge:** +{training_context} + +This training knowledge contains specific information about the user you're talking to, including their preferences, background, and previous conversations. Use this information to provide personalized and contextually appropriate responses.""") + + # Combine knowledge sections with clear instructions + if knowledge_sections: + base_prompt += f""" + +**KNOWLEDGE BASE:** +{chr(10).join(knowledge_sections)} + +**RESPONSE GUIDELINES:** +1. Prioritize information from your training knowledge when directly relevant to the user's question +2. Use document knowledge to provide comprehensive and accurate information +3. If the training knowledge contains specific details about the user (like their name, preferences, or background), use this information naturally in your responses +4. Maintain consistency with previous conversations and established context +5. If you don't have relevant information in your knowledge base, clearly state your limitations +6. Always be helpful, accurate, and true to your AI Soul personality + +**IMPORTANT:** When the user asks about information that you should know from training (like their name or personal details), refer to your training knowledge and provide the information confidently. + +**CRITICAL INSTRUCTION:** You MUST use the information from your Personal Training Knowledge section above. For example, if the training knowledge says "My name is Ahmed", then when asked "what is your name?" you should respond with information about Ahmed from the training data, NOT give a generic AI response. You are embodying the person described in your training knowledge. + +**PERSONA EMBODIMENT:** Respond as if you ARE the person described in the training knowledge. Use "I" statements naturally. NEVER mention that you are an AI, LLM, artificial intelligence, or any technical terms about your nature. Do NOT say "Based on my training data", "As an AI", "I am an artificial intelligence", or similar phrases. Instead, speak directly as the person. For example, say "I work with Python and React" instead of "The training data shows experience with Python and React". + +**KNOWLEDGE LIMITATIONS:** If you don't have information about something in your training knowledge, simply say "I'm not familiar with that" or "I don't have experience with that" or "I'm unaware of that" - do NOT provide detailed explanations about topics not in your training knowledge. Keep responses brief and personal when you lack specific knowledge.""" + + logger.info(f"System prompt built with {len(knowledge_sections)} knowledge sections") + return base_prompt + + def _build_conversation_history(self, session: Session, user_id: str, ai_soul_id: str, limit: int = 10) -> list[dict[str, str]]: + """Build conversation history for a specific AI soul""" + statement = ( + select(ChatMessage) + .where(ChatMessage.user_id == user_id, ChatMessage.ai_soul_id == ai_soul_id) + .order_by(ChatMessage.timestamp.desc()) + .limit(limit * 2) # Get extra messages to account for both user and AI messages + ) + messages = session.exec(statement).all() + messages.reverse() # Show in chronological order + + return [ + {"role": "user" if msg.is_from_user else "assistant", "content": msg.content} + for msg in messages + ] + + def _build_conversation_history_with_context_management( + self, + session: Session, + user_id: str, + ai_soul_id: str, + current_message: str, + max_history_messages: int = 20 + ) -> list[dict[str, str]]: + """Build conversation history with intelligent context management""" + + # Get recent conversation history + statement = ( + select(ChatMessage) + .where(ChatMessage.user_id == user_id, ChatMessage.ai_soul_id == ai_soul_id) + .order_by(ChatMessage.timestamp.desc()) + .limit(max_history_messages) + ) + messages = session.exec(statement).all() + messages.reverse() # Show in chronological order + + # Convert to conversation format + conversation = [] + for msg in messages: + role = "user" if msg.is_from_user else "assistant" + conversation.append({"role": role, "content": msg.content}) + + return conversation + + def _manage_context_window(self, messages: list[dict[str, str]], max_tokens: int = 7000) -> list[dict[str, str]]: + """Manage context window to prevent token overflow""" + + # Rough token estimation: 1 token ≈ 0.75 words + def estimate_tokens(text: str) -> int: + return int(len(text.split()) * 1.33) + + total_tokens = 0 + managed_messages = [] + + # Always include system message (first message) + if messages and messages[0]["role"] == "system": + system_message = messages[0] + total_tokens += estimate_tokens(system_message["content"]) + managed_messages.append(system_message) + messages = messages[1:] + + # Always include the latest user message (last message) + if messages and messages[-1]["role"] == "user": + user_message = messages[-1] + user_tokens = estimate_tokens(user_message["content"]) + messages = messages[:-1] + else: + user_message = None + user_tokens = 0 + + # Add conversation history from most recent backwards + for message in reversed(messages): + message_tokens = estimate_tokens(message["content"]) + + # Check if adding this message would exceed the limit + if total_tokens + message_tokens + user_tokens > max_tokens: + logger.info(f"Context window limit reached. Truncating older messages. Current tokens: {total_tokens}") + break + + managed_messages.insert(-1 if managed_messages else 0, message) + total_tokens += message_tokens + + # Add the user message at the end + if user_message: + managed_messages.append(user_message) + total_tokens += user_tokens + + logger.info(f"Context window managed: {len(managed_messages)} messages, ~{total_tokens} tokens") + return managed_messages + + def get_training_summary(self, session: Session, user_id: str, ai_soul_id: str) -> dict[str, Any]: + """Get training summary for a specific AI soul""" + context = self.get_user_context(session, user_id, ai_soul_id) + ai_soul = session.get(AISoulEntity, ai_soul_id) + + if not ai_soul: + return {"error": "AI Soul Entity not found"} + + return { + "ai_soul_name": ai_soul.name, + "persona_type": ai_soul.persona_type, + "specializations": ai_soul.specializations.split(","), + "messages_processed": context.get("message_count", 0), + "topics_covered": context.get("recent_topics", []), + "professional_focus": context.get("professional_focus", []), + "values_learned": context.get("values_and_beliefs", []), + "communication_style": context.get("conversation_style", "supportive"), + "interaction_count": ai_soul.interaction_count, + "last_interaction": ai_soul.last_used.isoformat() if ai_soul.last_used else None, + } diff --git a/backend/app/services/cohere_service.py b/backend/app/services/cohere_service.py new file mode 100644 index 0000000000..42bfacc514 --- /dev/null +++ b/backend/app/services/cohere_service.py @@ -0,0 +1,438 @@ +""" +Cohere LLM Service for Intelligent Risk Assessment + +This service uses Cohere's LLM API to perform intelligent risk assessment +and content filtering, replacing hardcoded keyword matching with AI-powered analysis. +""" + +import json +import logging +from typing import Any, Dict, List + +import httpx +from pydantic import BaseModel + +from app.core.config import settings + +logger = logging.getLogger(__name__) + + +class RiskAssessmentRequest(BaseModel): + """Request model for risk assessment""" + content: str + context: str = "" + analysis_type: str = "general" # general, content_filter, crisis_detection + + +class RiskAssessmentResponse(BaseModel): + """Response model for risk assessment""" + risk_level: str # low, medium, high, critical + risk_categories: List[str] + confidence_score: float + reasoning: str + requires_human_review: bool + auto_response_blocked: bool + crisis_resources_needed: bool + + +class CohereService: + """Service for intelligent risk assessment using Cohere LLM""" + + def __init__(self): + # Use Cohere as the primary LLM service + if settings.COHERE_API_KEY: + self.api_key = settings.COHERE_API_KEY + self.base_url = "https://api.cohere.ai/v1" + self.model = settings.COHERE_CHAT_MODEL + self.use_cohere = True + else: + raise ValueError("COHERE_API_KEY is required for LLM service") + + # Risk categories mapping + self.risk_categories = [ + "suicide", + "self_harm", + "violence", + "substance_abuse", + "abuse", + "mental_health_crisis", + "relationship_crisis", + "financial_crisis", + "sexual_content", + "general_distress" + ] + + # Crisis resources + self.crisis_resources = { + "suicide": [ + "🆘 National Suicide Prevention Lifeline: 988 or 1-800-273-8255", + "🆘 Crisis Text Line: Text HOME to 741741", + "🆘 If you're in immediate danger, call 911" + ], + "self_harm": [ + "🆘 Self-Injury Outreach & Support: 1-800-366-8288", + "🆘 Crisis Text Line: Text HOME to 741741", + "🆘 If you're in immediate danger, call 911" + ], + "violence": [ + "🆘 National Domestic Violence Hotline: 1-800-799-7233", + "🆘 If you're in immediate danger, call 911", + "🆘 Crisis Text Line: Text HOME to 741741" + ], + "substance_abuse": [ + "🆘 SAMHSA National Helpline: 1-800-662-HELP (4357)", + "🆘 Crisis Text Line: Text HOME to 741741" + ], + "abuse": [ + "🆘 National Domestic Violence Hotline: 1-800-799-7233", + "🆘 Childhelp National Child Abuse Hotline: 1-800-422-4453", + "🆘 If you're in immediate danger, call 911" + ], + "mental_health_crisis": [ + "🆘 National Suicide Prevention Lifeline: 988", + "🆘 Crisis Text Line: Text HOME to 741741", + "🆘 NAMI Helpline: 1-800-950-NAMI (6264)" + ] + } + + async def assess_risk(self, content: str, context: str = "", analysis_type: str = "general") -> RiskAssessmentResponse: + """ + Assess risk level of content using Cohere LLM + + Args: + content: The content to assess + context: Additional context for the assessment + analysis_type: Type of analysis (general, content_filter, crisis_detection) + + Returns: + RiskAssessmentResponse with detailed risk assessment + """ + try: + # Quick check for normal conversation to avoid unnecessary API calls + if self._is_normal_conversation(content): + logger.info(f"Normal conversation detected, skipping AI assessment: '{content[:50]}...'") + return RiskAssessmentResponse( + risk_level="low", + risk_categories=[], + confidence_score=0.95, + reasoning="Normal conversation pattern detected", + requires_human_review=False, + auto_response_blocked=False, + crisis_resources_needed=False + ) + + # Build the system prompt based on analysis type + system_prompt = self._build_system_prompt(analysis_type) + + # Build the user prompt + user_prompt = self._build_user_prompt(content, context, analysis_type) + + # Make API call to Cohere + async with httpx.AsyncClient() as client: + response = await client.post( + f"{self.base_url}/chat", + headers={ + "Authorization": f"Bearer {self.api_key}", + "Content-Type": "application/json", + }, + json={ + "model": self.model, + "message": user_prompt, + "preamble": system_prompt, + "max_tokens": 500, + "temperature": 0.1, # Low temperature for consistent results + "p": 0.9, + "stream": False + }, + timeout=30.0 + ) + + if response.status_code != 200: + logger.error(f"Cohere API error: {response.status_code} - {response.text}") + return self._fallback_assessment(content, "API_ERROR") + + result = response.json() + ai_response = result["text"] + + # Parse the AI response + return self._parse_ai_response(ai_response, content) + + except Exception as e: + logger.error(f"Error in Cohere risk assessment: {str(e)}") + return self._fallback_assessment(content, f"ERROR: {str(e)}") + + + + def _build_system_prompt(self, analysis_type: str) -> str: + """Build system prompt based on analysis type""" + + base_prompt = """You are a professional risk assessment AI designed to evaluate mental health, safety, and content risks in user messages. + +Your task is to analyze content and provide a detailed risk assessment in JSON format. + +Risk Levels: +- CRITICAL: Immediate suicide/self-harm intent, specific plans, imminent danger to self or others +- HIGH: Strong indicators of crisis, distress, harmful thoughts, or inappropriate content +- MEDIUM: Concerning patterns, mild distress indicators, potential risk factors +- LOW: Normal conversation, no significant risk indicators + +Risk Categories: +- suicide: Suicidal ideation, plans, or intent +- self_harm: Self-injury, cutting, or other self-destructive behaviors +- violence: Threats or plans to harm others, violent ideation +- substance_abuse: Drug or alcohol abuse, addiction concerns +- abuse: Domestic violence, child abuse, sexual abuse +- mental_health_crisis: Severe depression, anxiety, psychosis, breakdown +- relationship_crisis: Relationship problems, divorce, breakup distress +- financial_crisis: Bankruptcy, debt, financial distress +- sexual_content: Inappropriate sexual content, sexual abuse +- general_distress: General emotional distress, stress, worry + +NORMAL CONVERSATION PATTERNS (DO NOT FLAG): +- Simple greetings: "hello", "hi", "good morning", "how are you" +- Basic questions: "what's your name", "how does this work", "can you help me" +- Casual conversation: "I'm fine", "thank you", "okay", "sure" +- General topics: weather, hobbies, work, school (without distress indicators) +- Positive expressions: "I'm happy", "good day", "thanks" + +Guidelines: +- ONLY flag messages with genuine risk indicators or inappropriate content +- DO NOT flag normal conversation, greetings, or casual chat +- Look for specific indicators of harm, crisis, or inappropriate content +- Assess intent and severity carefully +- Normal emotional expression does not require review unless severe +- Only recommend human review for actual concerning content + +HUMAN REVIEW CRITERIA (All must be met): +1. Content contains explicit harm indicators OR inappropriate content +2. Message shows clear intent or planning of harmful actions +3. Content is beyond normal emotional expression or casual conversation + +Response Format (JSON only): +{ + "risk_level": "low|medium|high|critical", + "risk_categories": ["category1", "category2"], + "confidence_score": 0.0-1.0, + "reasoning": "brief explanation of assessment", + "requires_human_review": true/false, + "auto_response_blocked": true/false, + "crisis_resources_needed": true/false +}""" + + if analysis_type == "content_filter": + base_prompt += """ + +CONTENT FILTERING FOCUS: +- Pay special attention to sexual content, violence, and self-harm +- Consider age-appropriateness and context +- Block inappropriate sexual content +- Allow crisis-related content to go through (with human review)""" + + elif analysis_type == "crisis_detection": + base_prompt += """ + +CRISIS DETECTION FOCUS: +- Prioritize detection of immediate danger +- Look for specific plans or intent +- Consider timeline and immediacy +- Assess support systems and coping mechanisms""" + + return base_prompt + + def _build_user_prompt(self, content: str, context: str, analysis_type: str) -> str: + """Build user prompt for assessment""" + + prompt = f"""Analyze this content for risk assessment: + +Content: "{content}" +""" + + if context: + prompt += f"Context: {context}\n" + + prompt += f"Analysis Type: {analysis_type}\n" + prompt += "\nProvide risk assessment as JSON only (no additional text):" + + return prompt + + def _parse_ai_response(self, ai_response: str, content: str) -> RiskAssessmentResponse: + """Parse AI response and convert to RiskAssessmentResponse""" + try: + # Try to extract JSON from response + response_text = ai_response.strip() + + # Handle cases where AI might include extra text + if "```json" in response_text: + json_start = response_text.find("```json") + 7 + json_end = response_text.find("```", json_start) + response_text = response_text[json_start:json_end] + elif "{" in response_text: + json_start = response_text.find("{") + json_end = response_text.rfind("}") + 1 + response_text = response_text[json_start:json_end] + + # Parse JSON + parsed = json.loads(response_text) + + # Validate and normalize the response + risk_level = parsed.get("risk_level", "medium").lower() + if risk_level not in ["low", "medium", "high", "critical"]: + risk_level = "medium" + + risk_categories = parsed.get("risk_categories", []) + if not isinstance(risk_categories, list): + risk_categories = [] + + confidence_score = float(parsed.get("confidence_score", 0.5)) + confidence_score = max(0.0, min(1.0, confidence_score)) + + reasoning = parsed.get("reasoning", "AI-based risk assessment") + requires_human_review = parsed.get("requires_human_review", risk_level in ["high", "critical"]) + auto_response_blocked = parsed.get("auto_response_blocked", risk_level == "critical") + crisis_resources_needed = parsed.get("crisis_resources_needed", risk_level in ["high", "critical"]) + + return RiskAssessmentResponse( + risk_level=risk_level, + risk_categories=risk_categories, + confidence_score=confidence_score, + reasoning=reasoning, + requires_human_review=requires_human_review, + auto_response_blocked=auto_response_blocked, + crisis_resources_needed=crisis_resources_needed + ) + + except Exception as e: + logger.error(f"Error parsing AI response: {str(e)}") + logger.error(f"AI response was: {ai_response}") + return self._fallback_assessment(content, f"PARSE_ERROR: {str(e)}") + + def _is_normal_conversation(self, content: str) -> bool: + """Check if content is normal conversation that doesn't need review""" + content_lower = content.lower().strip() + + # Simple greetings and common phrases + normal_patterns = [ + "hello", "hi", "hey", "good morning", "good afternoon", "good evening", + "how are you", "how's it going", "what's up", "nice to meet you", + "thanks", "thank you", "you're welcome", "please", "sure", "okay", "ok", + "yes", "no", "maybe", "i don't know", "i'm fine", "i'm good", "i'm okay", + "what's your name", "who are you", "how does this work", "can you help me", + "what can you do", "tell me about", "i'm happy", "good day", "bye", "goodbye", + "see you later", "have a good day", "nice talking to you" + ] + + # Check if the entire message (or close to it) is just normal conversation + for pattern in normal_patterns: + if pattern in content_lower and len(content_lower) <= len(pattern) + 10: + return True + + # Check for very short messages (likely greetings or simple responses) + if len(content_lower) <= 15 and not any(word in content_lower for word in + ["kill", "die", "hurt", "hate", "suicide", "cut", "blood", "pain", "kill myself"]): + return True + + return False + + def _fallback_assessment(self, content: str, error_reason: str) -> RiskAssessmentResponse: + """Provide fallback assessment when AI fails""" + + # First check if it's normal conversation + if self._is_normal_conversation(content): + return RiskAssessmentResponse( + risk_level="low", + risk_categories=[], + confidence_score=0.9, + reasoning="Normal conversation pattern detected", + requires_human_review=False, + auto_response_blocked=False, + crisis_resources_needed=False + ) + + # Simple keyword-based fallback for safety + content_lower = content.lower() + + critical_keywords = [ + "suicide", "kill myself", "end my life", "want to die", "going to die", + "kill him", "kill her", "murder", "hurt others", "going to hurt", + "plan to kill", "want to kill" + ] + + high_risk_keywords = [ + "hurt myself", "cut myself", "cutting", "self harm", "self-harm", + "overdose", "can't go on", "hopeless", "worthless", "end it all", + "sexual abuse", "molest", "rape", "inappropriate touch" + ] + + risk_level = "low" + risk_categories = [] + + # Check for critical keywords with context + for keyword in critical_keywords: + if keyword in content_lower: + risk_level = "critical" + if any(term in keyword for term in ["suicide", "kill myself", "end my life", "want to die"]): + risk_categories.append("suicide") + elif any(term in keyword for term in ["kill", "murder", "hurt others"]): + risk_categories.append("violence") + break + + # Check for high-risk keywords if not already critical + if risk_level == "low": + for keyword in high_risk_keywords: + if keyword in content_lower: + risk_level = "high" + if any(term in keyword for term in ["hurt myself", "cut myself", "cutting", "self harm"]): + risk_categories.append("self_harm") + elif any(term in keyword for term in ["hopeless", "worthless", "can't go on"]): + risk_categories.append("mental_health_crisis") + elif any(term in keyword for term in ["sexual", "abuse", "molest", "rape"]): + risk_categories.append("sexual_content") + break + + return RiskAssessmentResponse( + risk_level=risk_level, + risk_categories=risk_categories, + confidence_score=0.6, # Medium confidence for fallback + reasoning=f"Fallback assessment due to: {error_reason}", + requires_human_review=risk_level in ["high", "critical"], + auto_response_blocked=risk_level == "critical", + crisis_resources_needed=risk_level in ["high", "critical"] + ) + + def get_crisis_resources(self, risk_categories: List[str]) -> List[str]: + """Get appropriate crisis resources based on risk categories""" + resources = [] + + for category in risk_categories: + if category in self.crisis_resources: + resources.extend(self.crisis_resources[category]) + + # Remove duplicates while preserving order + seen = set() + unique_resources = [] + for resource in resources: + if resource not in seen: + seen.add(resource) + unique_resources.append(resource) + + return unique_resources + + async def analyze_content_filter(self, content: str) -> Dict[str, Any]: + """ + Analyze content for filtering (compatibility with ContentFilterService) + + Returns: + Dict with filtering results in the expected format + """ + assessment = await self.assess_risk(content, analysis_type="content_filter") + + # Convert to ContentFilterService format + return { + "flagged": assessment.risk_level in ["medium", "high", "critical"], + "categories": assessment.risk_categories, + "severity": assessment.risk_level, + "action": "block" if assessment.auto_response_blocked else "warn" if assessment.requires_human_review else "allow", + "crisis_type": assessment.risk_categories[0] if assessment.risk_categories else None, + "suggested_response": "Crisis resources available" if assessment.crisis_resources_needed else None, + "crisis_resources": self.get_crisis_resources(assessment.risk_categories) if assessment.crisis_resources_needed else [] + } \ No newline at end of file diff --git a/backend/app/services/content_filter_service.py b/backend/app/services/content_filter_service.py new file mode 100644 index 0000000000..6f80554ad5 --- /dev/null +++ b/backend/app/services/content_filter_service.py @@ -0,0 +1,302 @@ +import logging +import re +from datetime import datetime + +from app.services.cohere_service import CohereService + +logger = logging.getLogger(__name__) + + +class ContentFilterService: + def __init__(self): + # Initialize Cohere service for intelligent content filtering + self.cohere_service = CohereService() + + # Keep simple fallback keywords for when AI service fails + self.fallback_keywords = { + "violence": ["kill", "murder", "violence", "hurt", "harm", "attack", "fight", "beat", "punch", "knife", "gun", "weapon"], + "self_harm": ["suicide", "kill myself", "end my life", "hurt myself", "cut myself", "self harm", "self-harm", + "want to die", "death", "overdose", "hanging", "jump off", "worthless", "hopeless", "can't go on"], + "sexual": ["sexual", "sex", "porn", "masturbation", "abuse", "assault", "rape", "molest", "inappropriate touching", + "sexual content", "explicit", "adult content"] + } + + self.crisis_resources = { + "suicide": { + "message": "I'm very concerned about what you're sharing. Your life has value and there are people who want to help.", + "resources": [ + "🇺🇸 National Suicide Prevention Lifeline: 988 or 1-800-273-8255", + "🇺🇸 Crisis Text Line: Text HOME to 741741", + "🇺🇸 Trevor Lifeline (LGBTQ): 1-866-488-7386", + "🇺🇸 National Sexual Assault Hotline: 1-800-656-4673" + ] + }, + "violence": { + "message": "I notice you're expressing thoughts about violence. Let's talk about healthier ways to handle these feelings.", + "resources": [ + "🇺🇸 National Domestic Violence Hotline: 1-800-799-7233", + "🇺🇸 Crisis Text Line: Text HOME to 741741" + ] + }, + "general_crisis": { + "message": "I'm here to support you, but I want to make sure you have access to professional help too.", + "resources": [ + "🇺🇸 Crisis Text Line: Text HOME to 741741", + "🇺🇸 SAMHSA National Helpline: 1-800-662-4357", + "📍 For immediate danger, please call 911 or go to your nearest emergency room" + ] + } + } + + def _is_normal_conversation(self, content: str) -> bool: + """Check if content is normal conversation that doesn't need review""" + content_lower = content.lower().strip() + + # Simple greetings and common phrases + normal_patterns = [ + "hello", "hi", "hey", "good morning", "good afternoon", "good evening", + "how are you", "how's it going", "what's up", "nice to meet you", + "thanks", "thank you", "you're welcome", "please", "sure", "okay", "ok", + "yes", "no", "maybe", "i don't know", "i'm fine", "i'm good", "i'm okay", + "what's your name", "who are you", "how does this work", "can you help me", + "what can you do", "tell me about", "i'm happy", "good day", "bye", "goodbye", + "see you later", "have a good day", "nice talking to you" + ] + + # Check if the entire message (or close to it) is just normal conversation + for pattern in normal_patterns: + if pattern in content_lower and len(content_lower) <= len(pattern) + 10: + return True + + # Check for very short messages (likely greetings or simple responses) + if len(content_lower) <= 15 and not any(word in content_lower for word in + ["kill", "die", "hurt", "hate", "suicide", "cut", "blood", "pain", "kill myself"]): + return True + + return False + + async def analyze_content(self, content: str) -> dict[str, any]: + """ + Analyze content for sensitive topics using AI-powered analysis + """ + try: + # Quick check for normal conversation to avoid unnecessary processing + if self._is_normal_conversation(content): + logger.info(f"Normal conversation detected, skipping content analysis: '{content[:50]}...'") + return { + "flagged": False, + "categories": [], + "severity": "low", + "action": "allow", + "crisis_type": None, + "suggested_response": None, + "crisis_resources": [] + } + + # Use Cohere service for intelligent content analysis + logger.info("Using Cohere LLM for content filtering analysis") + analysis_result = await self.cohere_service.analyze_content_filter(content) + + # Convert Cohere result to expected format + results = { + "flagged": analysis_result.get("flagged", False), + "categories": analysis_result.get("categories", []), + "severity": analysis_result.get("severity", "low"), + "action": analysis_result.get("action", "allow"), + "crisis_type": analysis_result.get("crisis_type"), + "suggested_response": analysis_result.get("suggested_response"), + "crisis_resources": analysis_result.get("crisis_resources", []) + } + + logger.info(f"Content analysis completed: flagged={results['flagged']}, " + f"severity={results['severity']}, categories={results['categories']}") + + return results + + except Exception as e: + logger.error(f"Error in AI-powered content analysis: {str(e)}") + # Fall back to simple keyword-based analysis + return self._fallback_analysis(content) + + def _fallback_analysis(self, content: str) -> dict[str, any]: + """ + Fallback keyword-based analysis when AI service fails + """ + # First check if it's normal conversation + if self._is_normal_conversation(content): + logger.info(f"Normal conversation detected in fallback analysis: '{content[:50]}...'") + return { + "flagged": False, + "categories": [], + "severity": "low", + "action": "allow", + "crisis_type": None, + "suggested_response": None, + "crisis_resources": [] + } + + content_lower = content.lower() + + results = { + "flagged": False, + "categories": [], + "severity": "low", + "action": "allow", + "crisis_type": None, + "suggested_response": None, + "crisis_resources": [] + } + + # Check for self-harm content (highest priority) + self_harm_score = self._check_self_harm_fallback(content_lower) + if self_harm_score > 0: + results["flagged"] = True + results["categories"].append("self_harm") + + if self_harm_score >= 3: + results["severity"] = "critical" + results["action"] = "crisis_intervention" + results["crisis_type"] = "suicide" + results["suggested_response"] = self.crisis_resources["suicide"]["message"] + results["crisis_resources"] = self.crisis_resources["suicide"]["resources"] + elif self_harm_score >= 2: + results["severity"] = "high" + results["action"] = "warn" + + # Check for violent content + violence_score = self._check_violence_fallback(content_lower) + if violence_score > 0: + results["flagged"] = True + results["categories"].append("violence") + + if violence_score >= 2 and results["severity"] != "critical": + results["severity"] = "high" + results["action"] = "warn" + if not results["crisis_type"]: + results["crisis_type"] = "violence" + results["suggested_response"] = self.crisis_resources["violence"]["message"] + results["crisis_resources"] = self.crisis_resources["violence"]["resources"] + + # Check for sexual content + sexual_score = self._check_sexual_content_fallback(content_lower) + if sexual_score > 0: + results["flagged"] = True + results["categories"].append("sexual") + + if sexual_score >= 2 and results["severity"] in ["low", "medium"]: + results["severity"] = "medium" + results["action"] = "warn" + + # Set default crisis resources if flagged but no specific type + if results["flagged"] and not results["crisis_resources"]: + results["crisis_resources"] = self.crisis_resources["general_crisis"]["resources"] + + logger.info(f"Fallback analysis completed: flagged={results['flagged']}, severity={results['severity']}") + return results + + def _check_self_harm_fallback(self, content: str) -> int: + """Check for self-harm indicators using fallback keywords""" + score = 0 + + # Check for fallback keywords + for keyword in self.fallback_keywords["self_harm"]: + if keyword in content: + if keyword in ["suicide", "kill myself", "end my life"]: + score += 3 + else: + score += 1 + + return min(score, 3) # Cap at 3 + + def _check_violence_fallback(self, content: str) -> int: + """Check for violent content using fallback keywords""" + score = 0 + + # Check for fallback keywords + for keyword in self.fallback_keywords["violence"]: + if keyword in content: + if keyword in ["kill", "murder", "gun", "knife", "weapon"]: + score += 2 + else: + score += 1 + + return min(score, 3) # Cap at 3 + + def _check_sexual_content_fallback(self, content: str) -> int: + """Check for sexual content using fallback keywords""" + score = 0 + + # Check for fallback keywords + for keyword in self.fallback_keywords["sexual"]: + if keyword in content: + if keyword in ["rape", "molest", "sexual assault", "sexual abuse"]: + score += 3 + else: + score += 1 + + return min(score, 3) # Cap at 3 + + def generate_filtered_response(self, analysis: dict[str, any], original_response: str) -> str: + """Generate appropriate response based on content analysis""" + + if analysis["action"] == "crisis_intervention": + crisis_response = f""" +{analysis['suggested_response']} + +**Immediate Help Available:** +{chr(10).join(analysis['crisis_resources'])} + +Please reach out to one of these resources right away. You don't have to go through this alone. + +While I want to support you as your AI counselor, these crisis resources have specially trained professionals who can provide immediate help. Your life matters, and there are people who care about you and want to help. + """.strip() + return crisis_response + + elif analysis["action"] == "warn" and "self_harm" in analysis["categories"]: + warning_response = f""" +I notice you're going through a very difficult time. While I'm here to support you, I want to make sure you have access to professional crisis support: + +**Crisis Resources:** +{chr(10).join(analysis['crisis_resources'])} + +{original_response} + +Remember, reaching out for professional help is a sign of strength, not weakness. + """.strip() + return warning_response + + elif analysis["action"] == "warn": + # For other warnings (violence, sexual content), add a gentler note + warning_note = "I want to ensure our conversation remains supportive and appropriate. If you're struggling with difficult thoughts or situations, please consider reaching out to professional resources." + return f"{original_response}\n\n{warning_note}" + + else: + return original_response + + def log_flagged_content(self, user_id: str, content: str, analysis: dict[str, any]) -> None: + """Log flagged content for monitoring and safety purposes""" + log_entry = { + "timestamp": datetime.utcnow().isoformat(), + "user_id": user_id, + "content_preview": content[:100] + "..." if len(content) > 100 else content, + "categories": analysis["categories"], + "severity": analysis["severity"], + "action": analysis["action"] + } + + # In a production environment, this would be logged to a secure monitoring system + logger.warning(f"Content filtered: {log_entry}") + + def is_crisis_situation(self, analysis: dict[str, any]) -> bool: + """Check if the content analysis indicates a crisis situation""" + return analysis.get("severity") == "critical" or analysis.get("action") == "crisis_intervention" + + async def is_safe_content(self, content: str) -> bool: + """ + Check if content is safe (simple wrapper around analyze_content) + Returns True if content is safe, False if it should be blocked + """ + analysis = await self.analyze_content(content) + # Block content if it's flagged as high severity or requires crisis intervention + return not (analysis.get("severity") in ["high", "critical"] or + analysis.get("action") in ["block", "crisis_intervention"]) diff --git a/backend/app/services/counselor_service.py b/backend/app/services/counselor_service.py new file mode 100644 index 0000000000..e892bcdff9 --- /dev/null +++ b/backend/app/services/counselor_service.py @@ -0,0 +1,805 @@ +""" +Counselor Service for Managing Review Queue and Approvals + +This service handles the counselor workflow for reviewing AI responses, +managing the queue, and tracking counselor actions. +""" + +import json +import logging +from datetime import datetime, timedelta +from typing import Any, Dict, List, Optional + +from sqlmodel import Session, select, and_, or_ + +from app.models import ( + AISoulEntity, + ChatMessage, + Counselor, + CounselorAction, + Organization, + PendingResponse, + RiskAssessment, + User, +) + +logger = logging.getLogger(__name__) + + +class CounselorService: + """Service for managing counselor review queue and approvals.""" + + def __init__(self, session: Session): + self.session = session + + async def create_pending_response( + self, + chat_message_id: str, + risk_assessment_id: str, + user_id: str, + ai_soul_id: str, + original_message: str, + ai_response: str, + organization_id: str | None = None, + priority: str = "normal" + ) -> PendingResponse: + """ + Create a new pending response for counselor review. + """ + try: + # Determine priority based on risk level + risk_assessment = self.session.get(RiskAssessment, risk_assessment_id) + if risk_assessment: + if risk_assessment.risk_level == "critical": + priority = "urgent" + elif risk_assessment.risk_level == "high": + priority = "high" + + # Set response time limit based on priority + response_time_limit = None + if priority == "urgent": + response_time_limit = datetime.utcnow() + timedelta(minutes=15) + elif priority == "high": + response_time_limit = datetime.utcnow() + timedelta(hours=1) + elif priority == "normal": + response_time_limit = datetime.utcnow() + timedelta(hours=4) + + # Assign to available counselor + assigned_counselor = await self._assign_counselor(organization_id, priority) + + pending_response = PendingResponse( + chat_message_id=chat_message_id, + risk_assessment_id=risk_assessment_id, + user_id=user_id, + ai_soul_id=ai_soul_id, + organization_id=organization_id, + original_user_message=original_message, + ai_generated_response=ai_response, + priority=priority, + assigned_counselor_id=assigned_counselor.id if assigned_counselor else None, + response_time_limit=response_time_limit + ) + + self.session.add(pending_response) + self.session.commit() + self.session.refresh(pending_response) + + logger.info( + f"Created pending response {pending_response.id} for user {user_id} " + f"with priority {priority}" + ) + + # TODO: Send notification to assigned counselor + if assigned_counselor: + await self._notify_counselor(assigned_counselor, pending_response) + + return pending_response + + except Exception as e: + logger.error(f"Error creating pending response: {str(e)}") + self.session.rollback() + raise + + async def get_counselor_queue( + self, + counselor_id: str, + status: str = "pending", + limit: int = 50 + ) -> List[Dict[str, Any]]: + """ + Get pending responses assigned to a specific counselor. + """ + try: + statement = ( + select(PendingResponse) + .where( + and_( + PendingResponse.assigned_counselor_id == counselor_id, + PendingResponse.status == status + ) + ) + .order_by( + PendingResponse.priority.desc(), # Urgent first + PendingResponse.created_at.asc() # Oldest first within priority + ) + .limit(limit) + ) + + pending_responses = self.session.exec(statement).all() + + # Enrich with additional data + enriched_queue = [] + for response in pending_responses: + # Get related data + user = self.session.get(User, response.user_id) + ai_soul = self.session.get(AISoulEntity, response.ai_soul_id) + risk_assessment = self.session.get(RiskAssessment, response.risk_assessment_id) + + # Calculate time remaining + time_remaining = None + if response.response_time_limit: + remaining = response.response_time_limit - datetime.utcnow() + time_remaining = max(0, int(remaining.total_seconds())) + + enriched_item = { + "id": str(response.id), + "user_name": user.full_name if user else "Unknown", + "user_email": user.email if user else "Unknown", + "ai_soul_name": ai_soul.name if ai_soul else "Unknown", + "original_user_message": response.original_user_message, + "ai_generated_response": response.ai_generated_response, + "priority": response.priority, + "created_at": response.created_at, + "time_remaining_seconds": time_remaining, + "risk_level": risk_assessment.risk_level if risk_assessment else "unknown", + "risk_categories": json.loads(risk_assessment.risk_categories) if risk_assessment else [], + "risk_reasoning": risk_assessment.reasoning if risk_assessment else "", + "status": response.status + } + enriched_queue.append(enriched_item) + + return enriched_queue + + except Exception as e: + logger.error(f"Error getting counselor queue: {str(e)}") + return [] + + async def get_admin_queue( + self, + organization_id: str | None = None, + status: str = "pending", + limit: int = 50 + ) -> List[Dict[str, Any]]: + """ + Get all pending responses for admin users with the same data structure as counselor queue. + This ensures frontend compatibility. + """ + try: + statement = select(PendingResponse).where( + PendingResponse.status == status + ) + + if organization_id: + statement = statement.where(PendingResponse.organization_id == organization_id) + + statement = statement.order_by( + PendingResponse.priority.desc(), # Urgent first + PendingResponse.created_at.asc() # Oldest first within priority + ).limit(limit) + + pending_responses = self.session.exec(statement).all() + + # Use the same enriched format as counselor queue for consistency + enriched_queue = [] + for response in pending_responses: + # Get related data + user = self.session.get(User, response.user_id) + ai_soul = self.session.get(AISoulEntity, response.ai_soul_id) + risk_assessment = self.session.get(RiskAssessment, response.risk_assessment_id) + assigned_counselor = self.session.get(Counselor, response.assigned_counselor_id) if response.assigned_counselor_id else None + + # Calculate time remaining + time_remaining = None + if response.response_time_limit: + remaining = response.response_time_limit - datetime.utcnow() + time_remaining = max(0, int(remaining.total_seconds())) + + enriched_item = { + "id": str(response.id), + "user_name": user.full_name if user else "Unknown", + "user_email": user.email if user else "Unknown", + "ai_soul_name": ai_soul.name if ai_soul else "Unknown", + "original_user_message": response.original_user_message, + "ai_generated_response": response.ai_generated_response, + "priority": response.priority, + "created_at": response.created_at, + "time_remaining_seconds": time_remaining, + "risk_level": risk_assessment.risk_level if risk_assessment else "unknown", + "risk_categories": json.loads(risk_assessment.risk_categories) if risk_assessment else [], + "risk_reasoning": risk_assessment.reasoning if risk_assessment else "", + "status": response.status, + "assigned_counselor": assigned_counselor.user.full_name if assigned_counselor and assigned_counselor.user else "Unassigned" + } + enriched_queue.append(enriched_item) + + return enriched_queue + + except Exception as e: + logger.error(f"Error getting admin queue: {str(e)}") + return [] + + async def approve_response( + self, + pending_response_id: str, + counselor_id: str | None, + notes: str | None = None + ) -> Dict[str, Any]: + """ + Approve an AI response without modifications. + """ + try: + pending_response = self.session.get(PendingResponse, pending_response_id) + if not pending_response: + raise ValueError("Pending response not found") + + # Update pending response + pending_response.status = "approved" + pending_response.reviewed_at = datetime.utcnow() + pending_response.counselor_notes = notes + + # Log counselor action only if we have a valid counselor_id + if counselor_id: + import uuid + action = CounselorAction( + counselor_id=uuid.UUID(counselor_id), + pending_response_id=uuid.UUID(pending_response_id), + user_id=pending_response.user_id, + organization_id=pending_response.organization_id, + action_type="approved", + original_response=pending_response.ai_generated_response, + final_response=pending_response.ai_generated_response, + reason=notes, + time_taken_seconds=self._calculate_review_time(pending_response) + ) + + self.session.add(action) + + self.session.commit() + + # Send the approved response to the user + await self._send_response_to_user( + pending_response, + pending_response.ai_generated_response + ) + + logger.info(f"Response {pending_response_id} approved by counselor {counselor_id}") + + return { + "status": "approved", + "response_sent": True, + "final_response": pending_response.ai_generated_response + } + + except Exception as e: + logger.error(f"Error approving response: {str(e)}") + self.session.rollback() + raise + + async def modify_response( + self, + pending_response_id: str, + counselor_id: str | None, + modified_response: str, + notes: str | None = None + ) -> Dict[str, Any]: + """ + Modify an AI response before sending to user. + """ + try: + pending_response = self.session.get(PendingResponse, pending_response_id) + if not pending_response: + raise ValueError("Pending response not found") + + # Update pending response + pending_response.status = "modified" + pending_response.reviewed_at = datetime.utcnow() + pending_response.modified_response = modified_response + pending_response.counselor_notes = notes + + # Log counselor action only if we have a valid counselor_id + if counselor_id: + import uuid + action = CounselorAction( + counselor_id=uuid.UUID(counselor_id), + pending_response_id=uuid.UUID(pending_response_id), + user_id=pending_response.user_id, + organization_id=pending_response.organization_id, + action_type="modified", + original_response=pending_response.ai_generated_response, + final_response=modified_response, + reason=notes, + time_taken_seconds=self._calculate_review_time(pending_response) + ) + + self.session.add(action) + + self.session.commit() + + # Send the modified response to the user + await self._send_response_to_user(pending_response, modified_response) + + logger.info(f"Response {pending_response_id} modified by counselor {counselor_id}") + + return { + "status": "modified", + "response_sent": True, + "final_response": modified_response + } + + except Exception as e: + logger.error(f"Error modifying response: {str(e)}") + self.session.rollback() + raise + + async def reject_response( + self, + pending_response_id: str, + counselor_id: str | None, + replacement_response: str, + reason: str + ) -> Dict[str, Any]: + """ + Reject an AI response and provide a replacement. + """ + try: + pending_response = self.session.get(PendingResponse, pending_response_id) + if not pending_response: + raise ValueError("Pending response not found") + + # Update pending response + pending_response.status = "rejected" + pending_response.reviewed_at = datetime.utcnow() + pending_response.modified_response = replacement_response + pending_response.counselor_notes = reason + + # Log counselor action only if we have a valid counselor_id + if counselor_id: + import uuid + action = CounselorAction( + counselor_id=uuid.UUID(counselor_id), + pending_response_id=uuid.UUID(pending_response_id), + user_id=pending_response.user_id, + organization_id=pending_response.organization_id, + action_type="rejected", + original_response=pending_response.ai_generated_response, + final_response=replacement_response, + reason=reason, + time_taken_seconds=self._calculate_review_time(pending_response) + ) + + self.session.add(action) + + self.session.commit() + + # Send the replacement response to the user + await self._send_response_to_user(pending_response, replacement_response) + + logger.info(f"Response {pending_response_id} rejected by counselor {counselor_id}") + + return { + "status": "rejected", + "response_sent": True, + "final_response": replacement_response + } + + except Exception as e: + logger.error(f"Error rejecting response: {str(e)}") + self.session.rollback() + raise + + async def escalate_case( + self, + pending_response_id: str, + counselor_id: str, + escalation_reason: str, + target_counselor_id: str | None = None + ) -> Dict[str, Any]: + """ + Escalate a case to another counselor or supervisor. + """ + try: + pending_response = self.session.get(PendingResponse, pending_response_id) + if not pending_response: + raise ValueError("Pending response not found") + + # Find target counselor (supervisor or specialist) + if not target_counselor_id: + target_counselor = await self._find_supervisor( + pending_response.organization_id + ) + target_counselor_id = target_counselor.id if target_counselor else None + + if not target_counselor_id: + raise ValueError("No available counselor for escalation") + + # Update pending response + pending_response.assigned_counselor_id = target_counselor_id + pending_response.priority = "urgent" # Escalated cases are urgent + pending_response.counselor_notes = f"Escalated: {escalation_reason}" + + # Log counselor action + import uuid + action = CounselorAction( + counselor_id=uuid.UUID(counselor_id), + pending_response_id=uuid.UUID(pending_response_id), + user_id=pending_response.user_id, + organization_id=pending_response.organization_id, + action_type="escalated", + original_response=pending_response.ai_generated_response, + final_response=None, + reason=escalation_reason, + time_taken_seconds=self._calculate_review_time(pending_response) + ) + + self.session.add(action) + self.session.commit() + + # Notify target counselor + target_counselor = self.session.get(Counselor, target_counselor_id) + if target_counselor: + await self._notify_counselor(target_counselor, pending_response, is_escalation=True) + + logger.info( + f"Case {pending_response_id} escalated by counselor {counselor_id} " + f"to counselor {target_counselor_id}" + ) + + return { + "status": "escalated", + "assigned_to": target_counselor_id, + "priority": "urgent" + } + + except Exception as e: + logger.error(f"Error escalating case: {str(e)}") + self.session.rollback() + raise + + async def get_organization_queue( + self, + organization_id: str, + status: str = "pending", + priority: str | None = None, + limit: int = 100 + ) -> List[Dict[str, Any]]: + """ + Get all pending responses for an organization. + """ + try: + statement = select(PendingResponse).where( + and_( + PendingResponse.organization_id == organization_id, + PendingResponse.status == status + ) + ) + + if priority: + statement = statement.where(PendingResponse.priority == priority) + + statement = statement.order_by( + PendingResponse.priority.desc(), + PendingResponse.created_at.asc() + ).limit(limit) + + pending_responses = self.session.exec(statement).all() + + # Enrich with additional data + enriched_queue = [] + for response in pending_responses: + user = self.session.get(User, response.user_id) + ai_soul = self.session.get(AISoulEntity, response.ai_soul_id) + counselor = self.session.get(Counselor, response.assigned_counselor_id) if response.assigned_counselor_id else None + risk_assessment = self.session.get(RiskAssessment, response.risk_assessment_id) + + enriched_item = { + "id": str(response.id), + "user_name": user.full_name if user else "Unknown", + "ai_soul_name": ai_soul.name if ai_soul else "Unknown", + "assigned_counselor": counselor.user.full_name if counselor and counselor.user else "Unassigned", + "priority": response.priority, + "status": response.status, + "created_at": response.created_at, + "risk_level": risk_assessment.risk_level if risk_assessment else "unknown", + "time_in_queue_minutes": int((datetime.utcnow() - response.created_at).total_seconds() / 60) + } + enriched_queue.append(enriched_item) + + return enriched_queue + + except Exception as e: + logger.error(f"Error getting organization queue: {str(e)}") + return [] + + async def get_counselor_performance( + self, + counselor_id: str, + days: int = 30 + ) -> Dict[str, Any]: + """ + Get performance metrics for a counselor. + """ + try: + cutoff_date = datetime.utcnow() - timedelta(days=days) + + # Get counselor actions + statement = ( + select(CounselorAction) + .where( + and_( + CounselorAction.counselor_id == counselor_id, + CounselorAction.created_at >= cutoff_date + ) + ) + ) + actions = self.session.exec(statement).all() + + # Calculate metrics + total_cases = len(actions) + approvals = len([a for a in actions if a.action_type == "approved"]) + modifications = len([a for a in actions if a.action_type == "modified"]) + rejections = len([a for a in actions if a.action_type == "rejected"]) + escalations = len([a for a in actions if a.action_type == "escalated"]) + + # Average review time + review_times = [a.time_taken_seconds for a in actions if a.time_taken_seconds] + avg_review_time = sum(review_times) / len(review_times) if review_times else 0 + + # Get current queue size + current_queue = await self.get_counselor_queue(counselor_id, "pending") + + return { + "counselor_id": counselor_id, + "period_days": days, + "total_cases_reviewed": total_cases, + "approvals": approvals, + "modifications": modifications, + "rejections": rejections, + "escalations": escalations, + "approval_rate": approvals / total_cases if total_cases > 0 else 0, + "average_review_time_seconds": int(avg_review_time), + "current_queue_size": len(current_queue), + "cases_per_day": total_cases / days if days > 0 else 0 + } + + except Exception as e: + logger.error(f"Error getting counselor performance: {str(e)}") + return {} + + async def get_organization_performance( + self, + organization_id: str | None = None, + days: int = 30 + ) -> Dict[str, Any]: + """ + Get organization-wide performance metrics for admin users. + """ + try: + cutoff_date = datetime.utcnow() - timedelta(days=days) + + # Get all counselor actions for the organization + statement = select(CounselorAction).where( + CounselorAction.created_at >= cutoff_date + ) + + if organization_id: + statement = statement.where(CounselorAction.organization_id == organization_id) + + actions = self.session.exec(statement).all() + + # Calculate organization-wide metrics + total_cases = len(actions) + approvals = len([a for a in actions if a.action_type == "approved"]) + modifications = len([a for a in actions if a.action_type == "modified"]) + rejections = len([a for a in actions if a.action_type == "rejected"]) + escalations = len([a for a in actions if a.action_type == "escalated"]) + + # Average review time across all counselors + review_times = [a.time_taken_seconds for a in actions if a.time_taken_seconds] + avg_review_time = sum(review_times) / len(review_times) if review_times else 0 + + # Get current organization-wide queue size + current_queue = await self.get_organization_queue( + organization_id=organization_id, + status="pending" + ) + + return { + "counselor_id": "organization-wide", + "period_days": days, + "total_cases_reviewed": total_cases, + "approvals": approvals, + "modifications": modifications, + "rejections": rejections, + "escalations": escalations, + "approval_rate": approvals / total_cases if total_cases > 0 else 0, + "average_review_time_seconds": int(avg_review_time), + "current_queue_size": len(current_queue), + "cases_per_day": total_cases / days if days > 0 else 0 + } + + except Exception as e: + logger.error(f"Error getting organization performance: {str(e)}") + return { + "counselor_id": "organization-wide", + "period_days": days, + "total_cases_reviewed": 0, + "approvals": 0, + "modifications": 0, + "rejections": 0, + "escalations": 0, + "approval_rate": 0, + "average_review_time_seconds": 0, + "current_queue_size": 0, + "cases_per_day": 0 + } + + async def _assign_counselor( + self, + organization_id: str | None, + priority: str + ) -> Optional[Counselor]: + """ + Assign an available counselor based on workload and specialization. + """ + try: + # Get available counselors for the organization + statement = select(Counselor).where( + and_( + Counselor.organization_id == organization_id, + Counselor.is_available == True + ) + ) + counselors = self.session.exec(statement).all() + + if not counselors: + return None + + # Find counselor with lowest current workload + best_counselor = None + min_workload = float('inf') + + for counselor in counselors: + # Count current pending cases + current_cases = self.session.exec( + select(PendingResponse).where( + and_( + PendingResponse.assigned_counselor_id == counselor.id, + PendingResponse.status == "pending" + ) + ) + ).all() + + workload = len(current_cases) + + # Skip if at max capacity + if workload >= counselor.max_concurrent_cases: + continue + + # Prefer counselors with lower workload + if workload < min_workload: + min_workload = workload + best_counselor = counselor + + return best_counselor + + except Exception as e: + logger.error(f"Error assigning counselor: {str(e)}") + return None + + async def _find_supervisor(self, organization_id: str | None) -> Optional[Counselor]: + """ + Find a supervisor counselor for escalation. + """ + # For now, find any available counselor + # In the future, this could check for specific supervisor roles + return await self._assign_counselor(organization_id, "urgent") + + def _calculate_review_time(self, pending_response: PendingResponse) -> int: + """ + Calculate how long the review took in seconds. + """ + if not pending_response.created_at: + return 0 + + review_time = datetime.utcnow() - pending_response.created_at + return int(review_time.total_seconds()) + + async def _send_response_to_user( + self, + pending_response: PendingResponse, + final_response: str + ) -> None: + """ + Send the final approved/modified response to the user. + """ + try: + # Create the AI response message in the chat + ai_message = ChatMessage( + content=final_response, + user_id=pending_response.user_id, + ai_soul_id=pending_response.ai_soul_id, + is_from_user=False + ) + + self.session.add(ai_message) + self.session.commit() + + logger.info( + f"Approved response sent to user {pending_response.user_id} " + f"for pending response {pending_response.id} - this replaces temporary review message" + ) + + except Exception as e: + logger.error(f"Error sending response to user: {str(e)}") + raise + + async def _notify_counselor( + self, + counselor: Counselor, + pending_response: PendingResponse, + is_escalation: bool = False + ) -> None: + """ + Send notification to counselor about new case. + """ + try: + # TODO: Implement notification system (email, push, websocket) + # For now, just log + notification_type = "escalation" if is_escalation else "new_case" + logger.info( + f"Notification sent to counselor {counselor.id} " + f"for {notification_type}: {pending_response.id}" + ) + + except Exception as e: + logger.error(f"Error notifying counselor: {str(e)}") + + async def auto_approve_expired_responses(self) -> int: + """ + Auto-approve responses that have exceeded their time limit. + """ + try: + # Find expired pending responses + statement = ( + select(PendingResponse) + .where( + and_( + PendingResponse.status == "pending", + PendingResponse.response_time_limit < datetime.utcnow() + ) + ) + ) + expired_responses = self.session.exec(statement).all() + + auto_approved_count = 0 + + for response in expired_responses: + # Auto-approve with system note + response.status = "approved" + response.reviewed_at = datetime.utcnow() + response.counselor_notes = "Auto-approved due to time limit expiration" + + # Send original AI response + await self._send_response_to_user(response, response.ai_generated_response) + + auto_approved_count += 1 + + if auto_approved_count > 0: + self.session.commit() + logger.info(f"Auto-approved {auto_approved_count} expired responses") + + return auto_approved_count + + except Exception as e: + logger.error(f"Error auto-approving expired responses: {str(e)}") + return 0 \ No newline at end of file diff --git a/backend/app/services/document_service.py b/backend/app/services/document_service.py new file mode 100644 index 0000000000..8b1e6e16d7 --- /dev/null +++ b/backend/app/services/document_service.py @@ -0,0 +1,383 @@ +import logging +import os +import uuid +from typing import Any + +import chromadb +from chromadb.config import Settings +from fastapi import HTTPException, UploadFile +from openai import OpenAI +from PyPDF2 import PdfReader +from sqlmodel import Session, select + +from app.core.config import settings +from app.models import Document, DocumentChunk, User +from app.utils import get_file_hash + +logger = logging.getLogger(__name__) + + +class DocumentService: + def __init__(self, db: Session): + self.db = db + self.upload_dir = settings.UPLOAD_DIR + os.makedirs(self.upload_dir, exist_ok=True) + self.client = OpenAI(api_key=settings.OPENAI_API_KEY) + + # Initialize Chroma client (optional - fallback if not available) + self.chroma_client = None + self.collection = None + try: + self.chroma_client = chromadb.HttpClient( + host="chroma", + port=8000, + settings=Settings( + allow_reset=True, + anonymized_telemetry=False + ) + ) + + # Create or get collection + self.collection = self.chroma_client.get_or_create_collection( + name="documents", + metadata={"hnsw:space": "cosine"} + ) + except Exception as e: + logger.warning(f"ChromaDB not available, using database-only mode: {e}") + self.chroma_client = None + self.collection = None + + async def upload_document( + self, file: UploadFile, user: User, description: str | None = None + ) -> Document: + """Upload a document and create initial database record.""" + if not file.content_type == "application/pdf": + raise HTTPException(status_code=400, detail="Only PDF files are supported") + + # Read file content and validate + content = await file.read() + if len(content) > settings.MAX_UPLOAD_SIZE: + raise HTTPException(status_code=400, detail="File too large") + + # Generate unique filename using UUID and original extension + file_hash = get_file_hash(content) + ext = os.path.splitext(file.filename)[1] + filename = f"{file_hash}{ext}" + file_path = os.path.join(self.upload_dir, filename) + + # Save file to disk + with open(file_path, "wb") as f: + f.write(content) + + # Create document record + document = Document( + filename=filename, + original_filename=file.filename, + file_size=len(content), + content_type=file.content_type, + description=description, + file_path=file_path, + user_id=user.id, + ) + self.db.add(document) + self.db.commit() + self.db.refresh(document) + + # Start async processing + await self.process_document(document) + + return document + + async def process_document(self, document: Document) -> None: + """Process uploaded PDF document and create chunks with embeddings.""" + try: + # Update status to processing + document.processing_status = "processing" + self.db.commit() + + # Extract text from PDF + chunks = self._extract_text_chunks(document.file_path) + + # Process chunks and store in Chroma (if available) + for idx, (content, metadata) in enumerate(chunks): + # Generate embedding using OpenAI (if ChromaDB is available) + embedding = None + if self.collection: + try: + embedding = await self.generate_embedding(content) + + # Store in Chroma + self.collection.add( + documents=[content], + embeddings=[embedding], + metadatas=[{ + "document_id": str(document.id), + "user_id": str(document.user_id), + "chunk_index": idx, + **metadata + }], + ids=[f"{document.id}_{idx}"] + ) + except Exception as e: + logger.warning(f"Failed to store in ChromaDB: {e}") + + # Store in database + chunk = DocumentChunk( + document_id=document.id, + user_id=document.user_id, + content=content, + chunk_index=idx, + chunk_metadata=metadata, + ) + self.db.add(chunk) + + # Update document status and chunk count + document.processing_status = "completed" + document.chunk_count = len(chunks) + self.db.commit() + + except Exception as e: + document.processing_status = "failed" + self.db.commit() + raise HTTPException( + status_code=500, + detail=f"Failed to process document: {str(e)}", + ) + + async def generate_embedding(self, text: str) -> list[float]: + """Generate embedding for text using OpenAI.""" + try: + response = self.client.embeddings.create( + model="text-embedding-ada-002", + input=text + ) + return response.data[0].embedding + except Exception as e: + logger.error(f"Error generating embedding: {str(e)}") + raise HTTPException( + status_code=500, + detail="Failed to generate embedding" + ) + + def _extract_text_chunks(self, file_path: str) -> list[tuple[str, str]]: + """Extract text from PDF and split into chunks with metadata.""" + chunks = [] + + try: + with open(file_path, "rb") as file: + pdf_reader = PdfReader(file) + + for page_num, page in enumerate(pdf_reader.pages): + text = page.extract_text() + + # Split text into chunks (simple implementation - can be enhanced) + words = text.split() + chunk_size = 200 # Adjust based on your needs + + for i in range(0, len(words), chunk_size): + chunk_words = words[i:i + chunk_size] + chunk_text = " ".join(chunk_words) + + metadata = { + "page": page_num + 1, + "chunk_start": i, + "chunk_end": i + len(chunk_words), + } + + chunks.append((chunk_text, str(metadata))) + + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Failed to extract text from PDF: {str(e)}", + ) + + return chunks + + def get_document(self, document_id: uuid.UUID, user_id: uuid.UUID) -> Document: + """Get a document by ID and user ID.""" + document = self.db.exec( + select(Document).where( + Document.id == document_id, + Document.user_id == user_id, + ) + ).first() + + if not document: + raise HTTPException(status_code=404, detail="Document not found") + + return document + + def get_user_documents( + self, user_id: uuid.UUID, skip: int = 0, limit: int = 100 + ) -> tuple[list[Document], int]: + """Get all documents for a user with pagination.""" + query = select(Document).where(Document.user_id == user_id) + total = len(self.db.exec(query).all()) + + documents = self.db.exec( + query.offset(skip).limit(limit) + ).all() + + return documents, total + + def delete_document(self, document_id: uuid.UUID, user_id: uuid.UUID) -> None: + """Delete a document and its associated file.""" + document = self.get_document(document_id, user_id) + + # Delete file from disk + try: + if os.path.exists(document.file_path): + os.remove(document.file_path) + except Exception as e: + # Log error but continue with database deletion + print(f"Error deleting file {document.file_path}: {e}") + + # Delete from Chroma + try: + self.collection.delete( + where={"document_id": str(document_id)} + ) + except Exception as e: + # Log error but continue with database deletion + print(f"Error deleting vectors from Chroma: {e}") + + # Delete from database (will cascade to chunks) + self.db.delete(document) + self.db.commit() + + async def search_documents( + self, + session: Session, + user_id: str, + query: str, + limit: int = 5 + ) -> list[dict[str, Any]]: + """Search documents using semantic similarity.""" + try: + # Generate query embedding + query_embedding = await self.generate_embedding(query) + + # Search in Chroma + results = self.collection.query( + query_embeddings=[query_embedding], + n_results=limit, + where={"user_id": user_id} + ) + + # Format results + formatted_results = [] + for idx, (doc, distance) in enumerate(zip(results["documents"][0], results["distances"][0], strict=False)): + metadata = results["metadatas"][0][idx] + formatted_results.append({ + "content": doc, + "similarity": 1 - distance, # Convert distance to similarity + "metadata": metadata, + "chunk": await self._get_chunk( + session, + metadata["document_id"], + metadata["chunk_index"] + ) + }) + + return formatted_results + + except Exception as e: + logger.error(f"Error searching documents: {str(e)}") + raise HTTPException( + status_code=500, + detail=f"Error searching documents: {str(e)}" + ) + + async def _get_chunk( + self, + session: Session, + document_id: str, + chunk_index: int + ) -> DocumentChunk: + """Get a specific document chunk.""" + chunk = session.exec( + select(DocumentChunk) + .where( + DocumentChunk.document_id == uuid.UUID(document_id), + DocumentChunk.chunk_index == chunk_index + ) + ).first() + + if not chunk: + raise HTTPException( + status_code=404, + detail=f"Chunk not found: doc={document_id}, idx={chunk_index}" + ) + + return chunk + + def extract_text_from_file(self, file_path: str) -> str: + """ + Synchronous version of text extraction for Celery tasks. + + Args: + file_path: Path to the file to extract text from + + Returns: + Extracted text content + """ + try: + if file_path.lower().endswith('.pdf'): + return self._extract_pdf_text_sync(file_path) + elif file_path.lower().endswith(('.doc', '.docx')): + return self._extract_docx_text_sync(file_path) + elif file_path.lower().endswith('.txt'): + return self._extract_txt_text_sync(file_path) + else: + raise ValueError(f"Unsupported file format: {file_path}") + except Exception as e: + logger.error(f"Error extracting text from {file_path}: {e}") + raise + + def _extract_pdf_text_sync(self, file_path: str) -> str: + """Synchronous PDF text extraction.""" + try: + import fitz # PyMuPDF + + doc = fitz.open(file_path) + text = "" + + for page in doc: + text += page.get_text() + + doc.close() + return text + + except ImportError: + # Fallback to PyPDF2 + from PyPDF2 import PdfReader + + reader = PdfReader(file_path) + text = "" + + for page in reader.pages: + text += page.extract_text() + + return text + + def _extract_docx_text_sync(self, file_path: str) -> str: + """Synchronous DOCX text extraction.""" + try: + from docx import Document + + doc = Document(file_path) + text = "" + + for paragraph in doc.paragraphs: + text += paragraph.text + "\n" + + return text + except ImportError: + logger.warning("python-docx not available - cannot extract DOCX text") + return "" + + def _extract_txt_text_sync(self, file_path: str) -> str: + """Synchronous text file extraction.""" + with open(file_path, encoding='utf-8') as file: + return file.read() diff --git a/backend/app/services/enhanced_rag_service.py b/backend/app/services/enhanced_rag_service.py new file mode 100644 index 0000000000..14890dde68 --- /dev/null +++ b/backend/app/services/enhanced_rag_service.py @@ -0,0 +1,1640 @@ +""" +Enhanced RAG Service for AI Soul Entity Project + +This service provides advanced document processing, semantic search, and retrieval +capabilities using Qdrant vector database, intelligent chunking, and hybrid search. + +Features: +- Intelligent semantic chunking +- Multi-stage retrieval with reranking +- Performance analytics and monitoring +- Caching for improved response times +- Support for multiple document formats +""" + +import json +import logging +import time +import uuid +from datetime import datetime +from typing import Any + +import numpy as np +from openai import AsyncOpenAI +from sqlmodel import Session, select + +from app.core.config import settings +from app.models import ( + Document, + DocumentChunkEnhanced, + DocumentProcessingLog, + RAGConfiguration, + SearchQuery, + SearchResultClick, +) + +logger = logging.getLogger(__name__) + +# Optional imports with graceful fallbacks +try: + # Import redis with compatibility handling + import redis.asyncio as aioredis + REDIS_AVAILABLE = True + logger.info("Using redis.asyncio for Redis operations") +except ImportError: + try: + import aioredis + REDIS_AVAILABLE = True + logger.info("Using aioredis for Redis operations") + except ImportError: + logger.warning("Redis not available - caching will be disabled") + REDIS_AVAILABLE = False + except Exception as e: + logger.warning(f"aioredis import failed: {e} - trying fallback") + REDIS_AVAILABLE = False +except Exception as e: + logger.warning(f"Redis import failed: {e} - caching will be disabled") + REDIS_AVAILABLE = False + +try: + from qdrant_client import QdrantClient + from qdrant_client.models import ( + CollectionStatus, + Distance, + FieldCondition, + Filter, + MatchValue, + PointStruct, + VectorParams, + ) + QDRANT_AVAILABLE = True +except ImportError: + logger.warning("Qdrant not available - vector search will be limited") + QDRANT_AVAILABLE = False + +try: + from sentence_transformers import SentenceTransformer + SENTENCE_TRANSFORMERS_AVAILABLE = True +except ImportError: + logger.warning("Sentence Transformers not available - semantic chunking will be limited") + SENTENCE_TRANSFORMERS_AVAILABLE = False + +try: + from sklearn.feature_extraction.text import TfidfVectorizer + from sklearn.metrics.pairwise import cosine_similarity + SKLEARN_AVAILABLE = True +except ImportError: + logger.warning("Scikit-learn not available - reranking will be limited") + SKLEARN_AVAILABLE = False + + +class EnhancedRAGService: + """Enhanced RAG service with intelligent chunking and hybrid search.""" + + def __init__(self, db_session: Session): + self.db = db_session + self.openai_client = AsyncOpenAI(api_key=settings.OPENAI_API_KEY) + + # Initialize Qdrant client if available + self.qdrant_client = None + if QDRANT_AVAILABLE: + try: + self.qdrant_client = QdrantClient( + url=settings.QDRANT_URL or "http://localhost:6333", + timeout=60 + ) + logger.info(f"Qdrant client initialized successfully with URL: {settings.QDRANT_URL or 'http://localhost:6333'}") + except Exception as e: + logger.error(f"Failed to connect to Qdrant: {e}") + self.qdrant_client = None + else: + logger.error("Qdrant client library not available") + + # Collection names + self.documents_collection = "ai_soul_documents" + self.training_collection = "ai_soul_training" + + # Initialize Redis for caching + self.redis_client = None + self.redis_initialized = False + + # Initialize sentence transformer for semantic chunking + self.sentence_transformer = None + if SENTENCE_TRANSFORMERS_AVAILABLE: + self._initialize_sentence_transformer() + + # TF-IDF vectorizer for hybrid search + if SKLEARN_AVAILABLE: + self.tfidf_vectorizer = TfidfVectorizer( + max_features=1000, + stop_words='english', + ngram_range=(1, 2) + ) + else: + self.tfidf_vectorizer = None + + # Collections will be initialized on first use + self.collections_initialized = False + + async def _initialize_redis(self): + """Initialize Redis connection for caching.""" + try: + # Use the appropriate Redis client based on what was imported + if hasattr(aioredis, 'from_url'): + self.redis_client = await aioredis.from_url( + settings.REDIS_URL or "redis://localhost:6379", + decode_responses=True + ) + else: + # Fallback for older aioredis versions + self.redis_client = aioredis.Redis.from_url( + settings.REDIS_URL or "redis://localhost:6379", + decode_responses=True + ) + + await self.redis_client.ping() + logger.info("Redis connection established") + except Exception as e: + logger.warning(f"Redis connection failed: {e}") + self.redis_client = None + + def _initialize_sentence_transformer(self): + """Initialize sentence transformer for semantic chunking.""" + try: + self.sentence_transformer = SentenceTransformer('all-MiniLM-L6-v2') + logger.info("Sentence transformer initialized") + except Exception as e: + logger.warning(f"Sentence transformer initialization failed: {e}") + self.sentence_transformer = None + + async def _ensure_initialization(self): + """Ensure all services are initialized before use.""" + # Initialize Redis if not already done + if REDIS_AVAILABLE and not self.redis_initialized: + await self._initialize_redis() + self.redis_initialized = True + + # Initialize Qdrant collections if not already done + if self.qdrant_client and not self.collections_initialized: + await self._initialize_collections() + self.collections_initialized = True + + async def _initialize_collections(self): + """Initialize Qdrant collections for documents and training data.""" + if not self.qdrant_client: + return + + try: + # Check if collections exist + collections = self.qdrant_client.get_collections() + existing_collections = [col.name for col in collections.collections] + + # Create documents collection if it doesn't exist + if self.documents_collection not in existing_collections: + self.qdrant_client.create_collection( + collection_name=self.documents_collection, + vectors_config=VectorParams( + size=1536, # OpenAI text-embedding-3-small dimension + distance=Distance.COSINE + ) + ) + logger.info(f"Created collection: {self.documents_collection}") + + # Create training collection if it doesn't exist + if self.training_collection not in existing_collections: + self.qdrant_client.create_collection( + collection_name=self.training_collection, + vectors_config=VectorParams( + size=1536, + distance=Distance.COSINE + ) + ) + logger.info(f"Created collection: {self.training_collection}") + + except Exception as e: + logger.error(f"Error initializing Qdrant collections: {e}") + + async def get_embedding(self, text: str, model: str = "text-embedding-3-small") -> list[float]: + """Generate embedding for text using OpenAI.""" + try: + response = await self.openai_client.embeddings.create( + model=model, + input=text + ) + return response.data[0].embedding + except Exception as e: + logger.error(f"Error generating embedding: {e}") + return [0.0] * 1536 # Return zero vector on error + + async def intelligent_chunking( + self, + text: str, + chunk_size: int = 500, + overlap: int = 50, + strategy: str = "semantic" + ) -> list[dict[str, Any]]: + """ + Intelligent chunking with semantic boundaries. + + Args: + text: Input text to chunk + chunk_size: Target chunk size in characters + overlap: Overlap between chunks + strategy: Chunking strategy ('semantic', 'sentence', 'paragraph') + + Returns: + List of chunk dictionaries with content and metadata + """ + chunks = [] + + if strategy == "semantic" and self.sentence_transformer: + chunks = await self._semantic_chunking(text, chunk_size, overlap) + elif strategy == "sentence": + chunks = await self._sentence_chunking(text, chunk_size, overlap) + elif strategy == "paragraph": + chunks = await self._paragraph_chunking(text, chunk_size, overlap) + else: + # Fallback to simple chunking + chunks = await self._simple_chunking(text, chunk_size, overlap) + + # Add metadata to chunks and ensure size constraints + final_chunks = [] + for i, chunk in enumerate(chunks): + content = chunk["content"] + + # If chunk is still too large, split it further + if len(content) > 3500: + # Simple split for oversized chunks + sub_chunks = [] + start = 0 + while start < len(content): + end = start + 3500 + sub_chunk_content = content[start:end] + sub_chunks.append({ + "content": sub_chunk_content, + "metadata": chunk.get("metadata", {}) + }) + start = end + + # Add sub-chunks with updated indices + for j, sub_chunk in enumerate(sub_chunks): + sub_chunk.update({ + "chunk_index": len(final_chunks), + "total_chunks": -1, # Will be updated later + "chunking_strategy": strategy, + "chunk_size_target": chunk_size, + "actual_size": len(sub_chunk["content"]), + "created_at": datetime.utcnow().isoformat() + }) + final_chunks.append(sub_chunk) + else: + chunk.update({ + "chunk_index": len(final_chunks), + "total_chunks": -1, # Will be updated later + "chunking_strategy": strategy, + "chunk_size_target": chunk_size, + "actual_size": len(chunk["content"]), + "created_at": datetime.utcnow().isoformat() + }) + final_chunks.append(chunk) + + # Update total_chunks count + for chunk in final_chunks: + chunk["total_chunks"] = len(final_chunks) + + return final_chunks + + async def _semantic_chunking(self, text: str, chunk_size: int, overlap: int) -> list[dict[str, Any]]: + """Semantic chunking using sentence embeddings.""" + if not self.sentence_transformer: + logger.warning("Sentence transformer not available, falling back to sentence chunking") + return await self._sentence_chunking(text, chunk_size, overlap) + + try: + # Split into sentences + sentences = self._split_sentences(text) + if not sentences: + return [{"content": text, "metadata": {"type": "fallback"}}] + + # Generate embeddings for sentences + sentence_embeddings = self.sentence_transformer.encode(sentences) + + chunks = [] + current_chunk = [] + current_length = 0 + + for i, sentence in enumerate(sentences): + sentence_length = len(sentence) + + # Check if adding this sentence would exceed chunk size + if current_length + sentence_length > chunk_size and current_chunk: + # Calculate semantic coherence of current chunk + chunk_text = " ".join(current_chunk) + coherence_score = self._calculate_semantic_coherence( + current_chunk, sentence_embeddings[i-len(current_chunk):i] + ) + + chunks.append({ + "content": chunk_text, + "metadata": { + "type": "semantic", + "sentence_count": len(current_chunk), + "coherence_score": coherence_score, + "start_sentence": i - len(current_chunk), + "end_sentence": i - 1 + } + }) + + # Start new chunk with overlap + overlap_sentences = max(1, overlap // 50) # Approximate sentences for overlap + current_chunk = current_chunk[-overlap_sentences:] + [sentence] + current_length = sum(len(s) for s in current_chunk) + else: + current_chunk.append(sentence) + current_length += sentence_length + + # Add final chunk + if current_chunk: + chunk_text = " ".join(current_chunk) + coherence_score = self._calculate_semantic_coherence( + current_chunk, sentence_embeddings[-len(current_chunk):] + ) + + chunks.append({ + "content": chunk_text, + "metadata": { + "type": "semantic", + "sentence_count": len(current_chunk), + "coherence_score": coherence_score, + "start_sentence": len(sentences) - len(current_chunk), + "end_sentence": len(sentences) - 1 + } + }) + + return chunks + + except Exception as e: + logger.error(f"Error in semantic chunking: {e}") + return await self._simple_chunking(text, chunk_size, overlap) + + async def _sentence_chunking(self, text: str, chunk_size: int, overlap: int) -> list[dict[str, Any]]: + """Chunking based on sentence boundaries.""" + sentences = self._split_sentences(text) + chunks = [] + current_chunk = [] + current_length = 0 + + for sentence in sentences: + if current_length + len(sentence) > chunk_size and current_chunk: + chunks.append({ + "content": " ".join(current_chunk), + "metadata": { + "type": "sentence", + "sentence_count": len(current_chunk) + } + }) + + # Handle overlap + overlap_sentences = max(1, overlap // 50) + current_chunk = current_chunk[-overlap_sentences:] + [sentence] + current_length = sum(len(s) for s in current_chunk) + else: + current_chunk.append(sentence) + current_length += len(sentence) + + if current_chunk: + chunks.append({ + "content": " ".join(current_chunk), + "metadata": { + "type": "sentence", + "sentence_count": len(current_chunk) + } + }) + + return chunks + + async def _paragraph_chunking(self, text: str, chunk_size: int, overlap: int) -> list[dict[str, Any]]: + """Chunking based on paragraph boundaries.""" + paragraphs = [p.strip() for p in text.split('\n\n') if p.strip()] + chunks = [] + current_chunk = [] + current_length = 0 + + for paragraph in paragraphs: + if current_length + len(paragraph) > chunk_size and current_chunk: + chunks.append({ + "content": "\n\n".join(current_chunk), + "metadata": { + "type": "paragraph", + "paragraph_count": len(current_chunk) + } + }) + + current_chunk = [paragraph] + current_length = len(paragraph) + else: + current_chunk.append(paragraph) + current_length += len(paragraph) + 2 # +2 for \n\n + + if current_chunk: + chunks.append({ + "content": "\n\n".join(current_chunk), + "metadata": { + "type": "paragraph", + "paragraph_count": len(current_chunk) + } + }) + + return chunks + + async def _simple_chunking(self, text: str, chunk_size: int, overlap: int) -> list[dict[str, Any]]: + """Simple character-based chunking with overlap.""" + chunks = [] + start = 0 + + while start < len(text): + end = start + chunk_size + chunk_text = text[start:end] + + chunks.append({ + "content": chunk_text, + "metadata": { + "type": "simple", + "start_char": start, + "end_char": end + } + }) + + start += chunk_size - overlap + + return chunks + + def _split_sentences(self, text: str) -> list[str]: + """Split text into sentences using simple heuristics.""" + import re + + # Simple sentence splitting - can be enhanced with NLTK or spaCy + sentences = re.split(r'[.!?]+', text) + sentences = [s.strip() for s in sentences if s.strip()] + return sentences + + def _calculate_semantic_coherence(self, sentences: list[str], embeddings: np.ndarray) -> float: + """Calculate semantic coherence score for a chunk.""" + if len(embeddings) < 2: + return 1.0 + + try: + from sklearn.metrics.pairwise import cosine_similarity + + # Calculate average pairwise cosine similarity + similarities = [] + for i in range(len(embeddings)): + for j in range(i + 1, len(embeddings)): + similarity = cosine_similarity( + embeddings[i].reshape(1, -1), + embeddings[j].reshape(1, -1) + )[0][0] + similarities.append(similarity) + + return float(np.mean(similarities)) if similarities else 0.0 + except ImportError: + # Fallback to simple calculation + return 0.8 # Default coherence score + + async def process_document( + self, + document: Document, + user_id: str, + config: RAGConfiguration | None = None + ) -> dict[str, Any]: + """ + Process a document with enhanced chunking and indexing. + + Args: + document: Document model instance + user_id: User ID for tracking + config: RAG configuration (optional) + + Returns: + Processing results with metrics + """ + start_time = time.time() + + # Log processing start + processing_log = DocumentProcessingLog( + document_id=document.id, + user_id=uuid.UUID(user_id), + processing_stage="started", + status="started", + created_at=datetime.utcnow() + ) + self.db.add(processing_log) + self.db.commit() + + try: + # Ensure initialization + await self._ensure_initialization() + + # Get configuration or use defaults + if not config: + config = await self._get_or_create_config(user_id) + + # Extract text from document + text_content = await self._extract_document_text(document.file_path) + + # Update processing log + processing_log.processing_stage = "text_extraction" + processing_log.status = "completed" + processing_log.processing_time_ms = int((time.time() - start_time) * 1000) + self.db.commit() + + # Intelligent chunking with database constraint + chunk_start = time.time() + # Ensure chunk size doesn't exceed database limit + max_chunk_size = min(config.chunk_size, 3500) # Leave some buffer for metadata + chunks = await self.intelligent_chunking( + text_content, + chunk_size=max_chunk_size, + overlap=config.chunk_overlap, + strategy=config.chunking_strategy + ) + + # Update processing log for chunking + processing_log.processing_stage = "chunking" + processing_log.chunks_created = len(chunks) + processing_log.processing_time_ms = int((time.time() - chunk_start) * 1000) + self.db.commit() + + # Generate embeddings and store in Qdrant + embedding_start = time.time() + stored_chunks = [] + + for chunk_data in chunks: + # Generate embedding + embedding = await self.get_embedding( + chunk_data["content"], + config.embedding_model + ) + + # Create enhanced chunk record + chunk_record = DocumentChunkEnhanced( + document_id=document.id, + user_id=uuid.UUID(user_id), + content=chunk_data["content"], + chunk_index=chunk_data["chunk_index"], + chunk_metadata=json.dumps(chunk_data["metadata"]), + semantic_metadata=json.dumps({ + "coherence_score": chunk_data["metadata"].get("coherence_score", 0.0), + "sentence_count": chunk_data["metadata"].get("sentence_count", 0), + "chunking_strategy": chunk_data["metadata"].get("chunking_strategy", "unknown") + }), + embedding_model=config.embedding_model, + embedding_dimension=len(embedding), + created_at=datetime.utcnow() + ) + + self.db.add(chunk_record) + self.db.flush() # Get the ID + + # Store in Qdrant if available + if self.qdrant_client: + point = PointStruct( + id=str(chunk_record.id), + vector=embedding, + payload={ + "document_id": str(document.id), + "user_id": user_id, + "chunk_index": chunk_data["chunk_index"], + "content": chunk_data["content"][:500], # Truncated for payload + "metadata": chunk_data["metadata"], + "created_at": datetime.utcnow().isoformat() + } + ) + + self.qdrant_client.upsert( + collection_name=self.documents_collection, + points=[point] + ) + else: + logger.warning("Qdrant client not available - skipping vector storage") + + stored_chunks.append(chunk_record) + + self.db.commit() + + # Update final processing log + processing_log.processing_stage = "completed" + processing_log.status = "completed" + processing_log.processing_time_ms = int((time.time() - start_time) * 1000) + processing_log.completed_at = datetime.utcnow() + + # Update document + document.processing_status = "completed" + document.chunk_count = len(chunks) + + self.db.commit() + + return { + "status": "success", + "chunks_created": len(chunks), + "processing_time_ms": int((time.time() - start_time) * 1000), + "embedding_model": config.embedding_model, + "chunking_strategy": config.chunking_strategy + } + + except Exception as e: + logger.error(f"Error processing document {document.id}: {e}") + + # Update processing log with error + processing_log.processing_stage = "failed" + processing_log.status = "failed" + processing_log.error_message = str(e) + processing_log.processing_time_ms = int((time.time() - start_time) * 1000) + + # Update document status + document.processing_status = "failed" + + self.db.commit() + + raise + + async def _extract_document_text(self, file_path: str) -> str: + """Extract text from various document formats.""" + try: + if file_path.lower().endswith('.pdf'): + return await self._extract_pdf_text(file_path) + elif file_path.lower().endswith(('.doc', '.docx')): + return await self._extract_docx_text(file_path) + elif file_path.lower().endswith('.txt'): + return await self._extract_txt_text(file_path) + else: + raise ValueError(f"Unsupported file format: {file_path}") + except Exception as e: + logger.error(f"Error extracting text from {file_path}: {e}") + raise + + async def _extract_pdf_text(self, file_path: str) -> str: + """Extract text from PDF using PyMuPDF.""" + try: + import fitz # PyMuPDF + + doc = fitz.open(file_path) + text = "" + + for page in doc: + text += page.get_text() + + doc.close() + return text + + except ImportError: + # Fallback to PyPDF2 + from PyPDF2 import PdfReader + + reader = PdfReader(file_path) + text = "" + + for page in reader.pages: + text += page.extract_text() + + return text + + async def _extract_docx_text(self, file_path: str) -> str: + """Extract text from DOCX files.""" + from docx import Document + + doc = Document(file_path) + text = "" + + for paragraph in doc.paragraphs: + text += paragraph.text + "\n" + + return text + + async def _extract_txt_text(self, file_path: str) -> str: + """Extract text from plain text files.""" + with open(file_path, encoding='utf-8') as file: + return file.read() + + async def _get_or_create_config(self, user_id: str) -> RAGConfiguration: + """Get or create RAG configuration for user.""" + config = self.db.exec( + select(RAGConfiguration).where( + RAGConfiguration.user_id == uuid.UUID(user_id), + RAGConfiguration.ai_soul_id.is_(None) # Default config + ) + ).first() + + if not config: + config = RAGConfiguration( + user_id=uuid.UUID(user_id), + chunking_strategy="semantic", + chunk_size=500, + chunk_overlap=50, + embedding_model="text-embedding-3-small", + search_algorithm="hybrid", + similarity_threshold=0.1, + max_results=10, + enable_reranking=True + ) + self.db.add(config) + self.db.commit() + self.db.refresh(config) + + return config + + async def hybrid_search( + self, + query: str, + user_id: str, + ai_soul_id: str | None = None, + filters: dict[str, Any] | None = None, + limit: int = 10 + ) -> dict[str, Any]: + """ + Perform hybrid search combining vector similarity and keyword matching. + + Args: + query: Search query + user_id: User ID for filtering and analytics + ai_soul_id: Optional AI Soul ID for filtering + filters: Additional filters + limit: Maximum number of results + + Returns: + Search results with metadata and analytics + """ + start_time = time.time() + + try: + # Ensure initialization + await self._ensure_initialization() + + # If Qdrant is not available, use database-only search + if not self.qdrant_client: + logger.warning("Qdrant not available, falling back to database-only search") + return await self._database_only_search(query, user_id, ai_soul_id, filters, limit) + + # Check cache first + cache_key = self._generate_cache_key(query, user_id, ai_soul_id, filters, limit) + cached_results = await self._get_cached_results(cache_key) + + if cached_results: + # Log cached search + await self._log_search_query( + query, user_id, ai_soul_id, filters, + len(cached_results["results"]), + int((time.time() - start_time) * 1000), + cached=True + ) + return cached_results + + # Get user configuration + config = await self._get_or_create_config(user_id) + + # Generate query embedding + query_embedding = await self.get_embedding(query, config.embedding_model) + + # Build Qdrant filter + qdrant_filter = self._build_qdrant_filter(user_id, ai_soul_id, filters) + + # Vector search in Qdrant + vector_results = self.qdrant_client.search( + collection_name=self.documents_collection, + query_vector=query_embedding, + query_filter=qdrant_filter, + limit=min(limit * 2, 50), # Get more for reranking + with_payload=True, + with_vectors=False, + score_threshold=0.05 # Lower threshold for testing + ) + + # Convert to standardized format + search_results = [] + for result in vector_results: + # Get full chunk data from database + chunk = self.db.get(DocumentChunkEnhanced, uuid.UUID(result.id)) + if chunk: + search_results.append({ + "chunk_id": str(chunk.id), + "document_id": str(chunk.document_id), + "content": chunk.content, + "similarity_score": result.score, + "chunk_index": chunk.chunk_index, + "metadata": json.loads(chunk.chunk_metadata or "{}"), + "semantic_metadata": json.loads(chunk.semantic_metadata or "{}"), + "embedding_model": chunk.embedding_model + }) + else: + logger.warning(f"Chunk not found in database for ID: {result.id}") + + # Apply reranking if enabled + if config.enable_reranking and len(search_results) > 1: + search_results = await self._rerank_results(query, search_results) + + # Apply additional filtering and ranking + final_results = await self._apply_business_logic_filtering( + search_results, config, limit + ) + + # Prepare response + response = { + "query": query, + "results": final_results[:limit], + "total_found": len(final_results), + "response_time_ms": int((time.time() - start_time) * 1000), + "search_algorithm": config.search_algorithm, + "similarity_threshold": config.similarity_threshold, + "reranking_enabled": config.enable_reranking + } + + # Cache results + await self._cache_results(cache_key, response) + + # Log search query + await self._log_search_query( + query, user_id, ai_soul_id, filters, + len(final_results), + response["response_time_ms"] + ) + + # Update chunk search counts + await self._update_chunk_analytics(final_results) + + return response + + except Exception as e: + logger.error(f"Error in hybrid search: {e}") + + # Log failed search + await self._log_search_query( + query, user_id, ai_soul_id, filters, 0, + int((time.time() - start_time) * 1000), + error=str(e) + ) + + raise + + async def _rerank_results( + self, + query: str, + results: list[dict[str, Any]] + ) -> list[dict[str, Any]]: + """ + Rerank search results using cross-encoder or other reranking methods. + + For now, implements a simple TF-IDF based reranking. + Can be enhanced with cross-encoder models later. + """ + try: + if not results: + return results + + # Extract content for TF-IDF + documents = [result["content"] for result in results] + documents.append(query) # Add query as last document + + # Fit TF-IDF and get similarity scores + tfidf_matrix = self.tfidf_vectorizer.fit_transform(documents) + query_tfidf = tfidf_matrix[-1] # Query is the last document + doc_tfidf = tfidf_matrix[:-1] # Documents are all except last + + # Calculate TF-IDF similarities + tfidf_similarities = cosine_similarity(query_tfidf, doc_tfidf).flatten() + + # Combine vector similarity and TF-IDF similarity + for i, result in enumerate(results): + vector_sim = result["similarity_score"] + tfidf_sim = tfidf_similarities[i] + + # Weighted combination (can be tuned) + combined_score = 0.7 * vector_sim + 0.3 * tfidf_sim + + result["rerank_score"] = combined_score + result["tfidf_similarity"] = float(tfidf_sim) + + # Sort by combined score + results.sort(key=lambda x: x["rerank_score"], reverse=True) + + return results + + except Exception as e: + logger.error(f"Error in reranking: {e}") + # Return original results if reranking fails + return results + + def _build_qdrant_filter( + self, + user_id: str, + ai_soul_id: str | None = None, + additional_filters: dict[str, Any] | None = None + ) -> Filter | None: + """Build Qdrant filter from search parameters.""" + conditions = [] + + # Always filter by user + conditions.append( + FieldCondition( + key="user_id", + match=MatchValue(value=user_id) + ) + ) + + # Add AI Soul filter if specified + if ai_soul_id: + conditions.append( + FieldCondition( + key="ai_soul_id", + match=MatchValue(value=ai_soul_id) + ) + ) + + # Add additional filters + if additional_filters: + for key, value in additional_filters.items(): + if key in ["document_id", "content_type", "created_after", "created_before"]: + conditions.append( + FieldCondition( + key=key, + match=MatchValue(value=value) + ) + ) + + return Filter(must=conditions) if conditions else None + + async def _apply_business_logic_filtering( + self, + results: list[dict[str, Any]], + config: RAGConfiguration, + limit: int + ) -> list[dict[str, Any]]: + """Apply business logic filtering and ranking.""" + filtered_results = [] + + for result in results: + # Apply similarity threshold + score_to_check = result.get("rerank_score", result["similarity_score"]) + + + + if score_to_check >= config.similarity_threshold: + # Add relevance indicators + result["above_threshold"] = True + result["relevance_tier"] = self._calculate_relevance_tier(score_to_check) + + filtered_results.append(result) + else: + result["above_threshold"] = False + + # Sort by best available score + filtered_results.sort( + key=lambda x: x.get("rerank_score", x["similarity_score"]), + reverse=True + ) + + return filtered_results + + def _calculate_relevance_tier(self, score: float) -> str: + """Calculate relevance tier based on score.""" + if score >= 0.9: + return "excellent" + elif score >= 0.8: + return "good" + elif score >= 0.7: + return "moderate" + else: + return "low" + + def _generate_cache_key( + self, + query: str, + user_id: str, + ai_soul_id: str | None, + filters: dict[str, Any] | None, + limit: int + ) -> str: + """Generate cache key for search results.""" + import hashlib + + key_parts = [ + query.lower().strip(), + user_id, + ai_soul_id or "", + json.dumps(filters or {}, sort_keys=True), + str(limit) + ] + + key_string = "|".join(key_parts) + return f"rag_search:{hashlib.md5(key_string.encode()).hexdigest()}" + + async def _get_cached_results(self, cache_key: str) -> dict[str, Any] | None: + """Get cached search results.""" + if not self.redis_client: + return None + + try: + cached_data = await self.redis_client.get(cache_key) + if cached_data: + return json.loads(cached_data) + except Exception as e: + logger.warning(f"Error getting cached results: {e}") + + return None + + async def _cache_results(self, cache_key: str, results: dict[str, Any]) -> None: + """Cache search results.""" + if not self.redis_client: + return + + try: + # Cache for 1 hour + await self.redis_client.setex( + cache_key, + 3600, + json.dumps(results, default=str) + ) + except Exception as e: + logger.warning(f"Error caching results: {e}") + + async def _log_search_query( + self, + query: str, + user_id: str, + ai_soul_id: str | None, + filters: dict[str, Any] | None, + results_count: int, + response_time_ms: int, + cached: bool = False, + error: str | None = None + ) -> None: + """Log search query for analytics.""" + try: + search_log = SearchQuery( + query_text=query, + user_id=uuid.UUID(user_id), + ai_soul_id=uuid.UUID(ai_soul_id) if ai_soul_id else None, + filters_applied=json.dumps(filters) if filters else None, + results_count=results_count, + response_time_ms=response_time_ms, + user_clicked_result=False, # Will be updated when user clicks + created_at=datetime.utcnow() + ) + + self.db.add(search_log) + self.db.commit() + + except Exception as e: + logger.error(f"Error logging search query: {e}") + + async def _update_chunk_analytics(self, results: list[dict[str, Any]]) -> None: + """Update analytics for returned chunks.""" + try: + for result in results: + chunk_id = uuid.UUID(result["chunk_id"]) + chunk = self.db.get(DocumentChunkEnhanced, chunk_id) + + if chunk: + chunk.search_count += 1 + chunk.last_accessed = datetime.utcnow() + + self.db.commit() + + except Exception as e: + logger.error(f"Error updating chunk analytics: {e}") + + async def track_result_click( + self, + search_query_id: str, + chunk_id: str, + user_id: str, + result_position: int, + similarity_score: float, + rerank_score: float | None = None + ) -> None: + """Track when user clicks on a search result.""" + try: + click_record = SearchResultClick( + search_query_id=uuid.UUID(search_query_id), + chunk_id=uuid.UUID(chunk_id), + user_id=uuid.UUID(user_id), + result_position=result_position, + similarity_score=similarity_score, + rerank_score=rerank_score, + clicked_at=datetime.utcnow() + ) + + self.db.add(click_record) + + # Update chunk click count + chunk = self.db.get(DocumentChunkEnhanced, uuid.UUID(chunk_id)) + if chunk: + chunk.click_count += 1 + + # Update search query + search_query = self.db.get(SearchQuery, uuid.UUID(search_query_id)) + if search_query: + search_query.user_clicked_result = True + + self.db.commit() + + except Exception as e: + logger.error(f"Error tracking result click: {e}") + + async def get_search_analytics( + self, + user_id: str, + days: int = 30 + ) -> dict[str, Any]: + """Get search analytics for a user.""" + try: + from datetime import timedelta + + cutoff_date = datetime.utcnow() - timedelta(days=days) + + # Get search queries + search_queries = self.db.exec( + select(SearchQuery).where( + SearchQuery.user_id == uuid.UUID(user_id), + SearchQuery.created_at >= cutoff_date + ) + ).all() + + # Calculate metrics + total_searches = len(search_queries) + avg_response_time = np.mean([q.response_time_ms for q in search_queries]) if search_queries else 0 + click_through_rate = len([q for q in search_queries if q.user_clicked_result]) / total_searches if total_searches > 0 else 0 + + # Get top queries + query_counts = {} + for query in search_queries: + query_counts[query.query_text] = query_counts.get(query.query_text, 0) + 1 + + top_queries = sorted(query_counts.items(), key=lambda x: x[1], reverse=True)[:10] + + return { + "total_searches": total_searches, + "avg_response_time_ms": round(avg_response_time, 2), + "click_through_rate": round(click_through_rate, 3), + "top_queries": top_queries, + "period_days": days + } + + except Exception as e: + logger.error(f"Error getting search analytics: {e}") + return { + "total_searches": 0, + "avg_response_time_ms": 0, + "click_through_rate": 0, + "top_queries": [], + "period_days": days, + "error": str(e) + } + + async def delete_document_from_index(self, document_id: str, user_id: str) -> bool: + """Delete document and its chunks from the vector index.""" + try: + # Get all chunks for this document + chunks = self.db.exec( + select(DocumentChunkEnhanced).where( + DocumentChunkEnhanced.document_id == uuid.UUID(document_id), + DocumentChunkEnhanced.user_id == uuid.UUID(user_id) + ) + ).all() + + # Delete from Qdrant + chunk_ids = [str(chunk.id) for chunk in chunks] + if chunk_ids: + self.qdrant_client.delete( + collection_name=self.documents_collection, + points_selector=chunk_ids + ) + + # Delete from database (will cascade) + for chunk in chunks: + self.db.delete(chunk) + + self.db.commit() + + return True + + except Exception as e: + logger.error(f"Error deleting document from index: {e}") + return False + + async def get_collection_info(self) -> dict[str, Any]: + """Get information about Qdrant collections.""" + try: + collections = self.qdrant_client.get_collections() + + info = {} + for collection in collections.collections: + if collection.name in [self.documents_collection, self.training_collection]: + collection_info = self.qdrant_client.get_collection(collection.name) + info[collection.name] = { + "status": collection_info.status, + "vectors_count": collection_info.vectors_count, + "points_count": collection_info.points_count, + "segments_count": collection_info.segments_count, + } + + return info + + except Exception as e: + logger.error(f"Error getting collection info: {e}") + return {"error": str(e)} + + async def health_check(self) -> dict[str, Any]: + """Perform health check on RAG system components.""" + health = { + "status": "healthy", + "components": {}, + "timestamp": datetime.utcnow().isoformat() + } + + # Check Qdrant + try: + collections = self.qdrant_client.get_collections() + health["components"]["qdrant"] = { + "status": "healthy", + "collections": len(collections.collections) + } + except Exception as e: + health["components"]["qdrant"] = { + "status": "unhealthy", + "error": str(e) + } + health["status"] = "degraded" + + # Check Redis + try: + if self.redis_client: + await self.redis_client.ping() + health["components"]["redis"] = {"status": "healthy"} + else: + health["components"]["redis"] = {"status": "unavailable"} + except Exception as e: + health["components"]["redis"] = { + "status": "unhealthy", + "error": str(e) + } + + # Check OpenAI + try: + # Simple test embedding + test_embedding = await self.get_embedding("test") + health["components"]["openai"] = { + "status": "healthy", + "embedding_dimension": len(test_embedding) + } + except Exception as e: + health["components"]["openai"] = { + "status": "unhealthy", + "error": str(e) + } + health["status"] = "degraded" + + return health + + async def _database_only_search( + self, + query: str, + user_id: str, + ai_soul_id: str | None = None, + filters: dict[str, Any] | None = None, + limit: int = 10 + ) -> dict[str, Any]: + """ + Fallback search using only database when Qdrant is not available. + Uses simple text matching on chunk content. + """ + start_time = time.time() + + try: + # Simple text search using LIKE + query_lower = query.lower() + + # Build base query + stmt = select(DocumentChunkEnhanced).where( + DocumentChunkEnhanced.user_id == uuid.UUID(user_id) + ) + + # Add text search condition + stmt = stmt.where( + DocumentChunkEnhanced.content.ilike(f"%{query}%") + ) + + # Execute query + chunks = self.db.exec(stmt.limit(limit)).all() + + # Format results + results = [] + for chunk in chunks: + # Simple relevance scoring based on query term frequency + content_lower = chunk.content.lower() + query_terms = query_lower.split() + score = sum(content_lower.count(term) for term in query_terms) / len(chunk.content) + + results.append({ + "chunk_id": str(chunk.id), + "document_id": str(chunk.document_id), + "content": chunk.content, + "similarity_score": min(score, 1.0), # Cap at 1.0 + "chunk_index": chunk.chunk_index, + "metadata": json.loads(chunk.chunk_metadata or "{}"), + "semantic_metadata": json.loads(chunk.semantic_metadata or "{}"), + "embedding_model": chunk.embedding_model, + "search_method": "database_only" + }) + + # Sort by relevance score + results.sort(key=lambda x: x["similarity_score"], reverse=True) + + response = { + "query": query, + "results": results[:limit], + "total_found": len(results), + "response_time_ms": int((time.time() - start_time) * 1000), + "search_algorithm": "database_only", + "similarity_threshold": 0.0, + "reranking_enabled": False + } + + # Log search query + await self._log_search_query( + query, user_id, ai_soul_id, filters, + len(results), + response["response_time_ms"] + ) + + return response + + except Exception as e: + logger.error(f"Error in database-only search: {e}") + raise + + async def simple_hybrid_search( + self, + query: str, + user_id: str, + ai_soul_id: str | None = None, + filters: dict[str, Any] | None = None, + limit: int = 10 + ) -> dict[str, Any]: + """ + Simple hybrid search that works even with missing dependencies. + Falls back to database text search when vector search is unavailable. + """ + start_time = time.time() + + try: + # Ensure initialization + await self._ensure_initialization() + + # If Qdrant is available, use the full hybrid search + if self.qdrant_client: + return await self.hybrid_search(query, user_id, ai_soul_id, filters, limit) + + # Fallback to database text search + logger.info("Using fallback database text search") + + # Build database query + query_conditions = [ + DocumentChunkEnhanced.user_id == uuid.UUID(user_id) + ] + + if ai_soul_id: + # Note: This would need a relationship to AI souls in the chunk model + pass + + # Simple text search using LIKE + text_search_query = select(DocumentChunkEnhanced).where( + *query_conditions, + DocumentChunkEnhanced.content.ilike(f"%{query}%") + ).limit(limit) + + chunks = self.db.exec(text_search_query).all() + + # Convert to response format + results = [] + for chunk in chunks: + results.append({ + "chunk_id": str(chunk.id), + "document_id": str(chunk.document_id), + "content": chunk.content, + "similarity_score": 0.5, # Default score for text match + "chunk_index": chunk.chunk_index, + "metadata": json.loads(chunk.chunk_metadata or "{}"), + "semantic_metadata": json.loads(chunk.semantic_metadata or "{}"), + "embedding_model": chunk.embedding_model, + "search_method": "database_text_search" + }) + + response = { + "query": query, + "results": results, + "total_found": len(results), + "response_time_ms": int((time.time() - start_time) * 1000), + "search_algorithm": "database_fallback", + "similarity_threshold": 0.0, + "reranking_enabled": False + } + + # Log search query + await self._log_search_query( + query, user_id, ai_soul_id, filters, + len(results), + response["response_time_ms"] + ) + + return response + + except Exception as e: + logger.error(f"Error in simple hybrid search: {e}") + + # Log failed search + await self._log_search_query( + query, user_id, ai_soul_id, filters, 0, + int((time.time() - start_time) * 1000), + error=str(e) + ) + + # Return empty results instead of raising + return { + "query": query, + "results": [], + "total_found": 0, + "response_time_ms": int((time.time() - start_time) * 1000), + "search_algorithm": "error_fallback", + "similarity_threshold": 0.0, + "reranking_enabled": False, + "error": str(e) + } + + def create_intelligent_chunks_sync( + self, + text: str, + document_id: str, + user_id: str, + document_type: str = "general" + ) -> list[DocumentChunkEnhanced]: + """ + Synchronous version of intelligent chunking for Celery tasks. + + Args: + text: Text content to chunk + document_id: Document ID + user_id: User ID + document_type: Type of document + + Returns: + List of DocumentChunkEnhanced objects + """ + try: + # Get configuration + config = self.db.exec( + select(RAGConfiguration).where( + RAGConfiguration.user_id == uuid.UUID(user_id), + RAGConfiguration.ai_soul_id.is_(None) + ) + ).first() + + if not config: + config = RAGConfiguration( + user_id=uuid.UUID(user_id), + chunking_strategy="semantic", + chunk_size=500, + chunk_overlap=50, + embedding_model="text-embedding-3-small" + ) + + # Simple chunking for sync operation + chunks = [] + chunk_size = min(config.chunk_size, 3500) # Database constraint + overlap = config.chunk_overlap + + start = 0 + chunk_index = 0 + + while start < len(text): + end = start + chunk_size + chunk_content = text[start:end] + + # Create chunk record + if document_type == "training": + from app.models import TrainingDocumentChunkEnhanced + chunk = TrainingDocumentChunkEnhanced( + training_document_id=uuid.UUID(document_id), + ai_soul_id=None, # Will be set by caller + user_id=uuid.UUID(user_id), + content=chunk_content, + chunk_index=chunk_index, + chunk_metadata=json.dumps({ + "type": "simple", + "start_char": start, + "end_char": end + }), + embedding_model=config.embedding_model + ) + else: + chunk = DocumentChunkEnhanced( + document_id=uuid.UUID(document_id), + user_id=uuid.UUID(user_id), + content=chunk_content, + chunk_index=chunk_index, + chunk_metadata=json.dumps({ + "type": "simple", + "start_char": start, + "end_char": end + }), + embedding_model=config.embedding_model + ) + + chunks.append(chunk) + start += chunk_size - overlap + chunk_index += 1 + + return chunks + + except Exception as e: + logger.error(f"Error in sync chunking: {e}") + raise + + def generate_embeddings_batch_sync(self, texts: list[str]) -> list[list[float]]: + """ + Synchronous version of batch embedding generation for Celery tasks. + + Args: + texts: List of texts to embed + + Returns: + List of embedding vectors + """ + try: + from openai import OpenAI + + # Use sync OpenAI client + client = OpenAI(api_key=settings.OPENAI_API_KEY) + + embeddings = [] + + # Process in batches to avoid API limits + batch_size = 100 + for i in range(0, len(texts), batch_size): + batch = texts[i:i + batch_size] + + response = client.embeddings.create( + model="text-embedding-3-small", + input=batch + ) + + batch_embeddings = [item.embedding for item in response.data] + embeddings.extend(batch_embeddings) + + return embeddings + + except Exception as e: + logger.error(f"Error in sync embedding generation: {e}") + # Return zero vectors on error + return [[0.0] * 1536 for _ in texts] + + def update_vector_database(self, chunks: list[DocumentChunkEnhanced]) -> None: + """ + Update vector database with new chunks. + + Args: + chunks: List of chunks to update in vector database + """ + try: + if not self.qdrant_client: + logger.warning("Qdrant client not available - skipping vector database update") + return + + points = [] + for chunk in chunks: + if hasattr(chunk, 'embedding') and chunk.embedding: + try: + embedding = json.loads(chunk.embedding) + point = PointStruct( + id=str(chunk.id), + vector=embedding, + payload={ + "document_id": str(chunk.document_id), + "user_id": str(chunk.user_id), + "chunk_index": chunk.chunk_index, + "content": chunk.content[:500], # Truncated for payload + "created_at": chunk.created_at.isoformat() + } + ) + points.append(point) + except json.JSONDecodeError: + logger.warning(f"Invalid embedding JSON for chunk {chunk.id}") + + if points: + self.qdrant_client.upsert( + collection_name=self.documents_collection, + points=points + ) + logger.info(f"Updated {len(points)} points in vector database") + + except Exception as e: + logger.error(f"Error updating vector database: {e}") diff --git a/backend/app/services/risk_assessment_service.py b/backend/app/services/risk_assessment_service.py new file mode 100644 index 0000000000..7c5c10da42 --- /dev/null +++ b/backend/app/services/risk_assessment_service.py @@ -0,0 +1,516 @@ +""" +Risk Assessment Service for AI Counselor Override System + +This service analyzes user messages for potential risks and determines +whether human counselor intervention is required. +""" + +import json +import logging +import re +from datetime import datetime, timedelta +from typing import Any, Dict, List + +from openai import OpenAI +from sqlmodel import Session, select + +from app.core.config import settings +from app.models import ( + AISoulEntity, + ChatMessage, + Organization, + RiskAssessment, + User, +) +from app.services.cohere_service import CohereService + +logger = logging.getLogger(__name__) + + +class RiskAssessmentService: + """Service for assessing risk levels in user conversations using AI-powered analysis.""" + + def __init__(self): + # Initialize Cohere service for intelligent risk assessment + self.cohere_service = CohereService() + + # Keep OpenAI for backward compatibility with existing AI analysis method + if settings.OPENAI_API_KEY: + self.client = OpenAI(api_key=settings.OPENAI_API_KEY) + else: + self.client = None + logger.warning("OpenAI API key not configured - AI analysis will be limited") + + # Crisis resources (moved from hardcoded keywords to centralized location) + self.crisis_resources = { + "suicide": [ + "🆘 National Suicide Prevention Lifeline: 988 or 1-800-273-8255", + "🆘 Crisis Text Line: Text HOME to 741741", + "🆘 If you're in immediate danger, call 911" + ], + "self_harm": [ + "🆘 Self-Injury Outreach & Support: 1-800-366-8288", + "🆘 Crisis Text Line: Text HOME to 741741", + "🆘 If you're in immediate danger, call 911" + ], + "violence": [ + "🆘 National Domestic Violence Hotline: 1-800-799-7233", + "🆘 If you're in immediate danger, call 911", + "🆘 Crisis Text Line: Text HOME to 741741" + ], + "substance_abuse": [ + "🆘 SAMHSA National Helpline: 1-800-662-HELP (4357)", + "🆘 Crisis Text Line: Text HOME to 741741" + ], + "abuse": [ + "🆘 National Domestic Violence Hotline: 1-800-799-7233", + "🆘 Childhelp National Child Abuse Hotline: 1-800-422-4453", + "🆘 If you're in immediate danger, call 911" + ], + "mental_health_crisis": [ + "🆘 National Suicide Prevention Lifeline: 988", + "🆘 Crisis Text Line: Text HOME to 741741", + "🆘 NAMI Helpline: 1-800-950-NAMI (6264)" + ], + "general_crisis": [ + "🆘 National Suicide Prevention Lifeline: 988", + "🆘 Crisis Text Line: Text HOME to 741741", + "🆘 If you're in immediate danger, call 911" + ] + } + + async def assess_message_risk( + self, + session: Session, + user_message: str, + user_id: str, + ai_soul_id: str, + chat_message_id: str, + organization_id: str | None = None, + content_analysis: Dict[str, Any] | None = None + ) -> Dict[str, Any]: + """ + Assess the risk level of a user message using AI-powered analysis. + + Returns: + Dict containing risk assessment results + """ + try: + # Get conversation context for better analysis + context = await self._get_conversation_context(session, user_id, ai_soul_id) + + # Use Cohere LLM for intelligent risk assessment + logger.info(f"Using Cohere LLM for risk assessment of message from user {user_id}") + cohere_assessment = await self.cohere_service.assess_risk( + content=user_message, + context=context, + analysis_type="crisis_detection" + ) + + # Convert Cohere response to our expected format + assessment_result = { + "risk_level": cohere_assessment.risk_level, + "risk_categories": cohere_assessment.risk_categories, + "confidence_score": cohere_assessment.confidence_score, + "reasoning": cohere_assessment.reasoning, + "requires_human_review": cohere_assessment.requires_human_review, + "auto_response_blocked": cohere_assessment.auto_response_blocked, + "crisis_resources": self._get_crisis_resources_for_categories(cohere_assessment.risk_categories) + } + + # If content analysis is provided, combine insights + if content_analysis and content_analysis.get("flagged"): + content_assessment = self._convert_content_analysis_to_risk_assessment(content_analysis) + + # Use the higher risk level between LLM and content analysis + if self._get_risk_level_priority(content_assessment["risk_level"]) > self._get_risk_level_priority(assessment_result["risk_level"]): + logger.info("Content analysis detected higher risk than LLM - using content analysis result") + assessment_result = content_assessment + else: + logger.info("LLM assessment maintained as primary result") + + # Save assessment to database + risk_assessment = await self._save_risk_assessment( + session=session, + chat_message_id=chat_message_id, + user_id=user_id, + ai_soul_id=ai_soul_id, + organization_id=organization_id, + assessment_result=assessment_result + ) + + # Add database ID to result + assessment_result["assessment_id"] = str(risk_assessment.id) + + logger.info( + f"AI-powered risk assessment completed for user {user_id}: " + f"Level={assessment_result['risk_level']}, " + f"Requires review={assessment_result['requires_human_review']}, " + f"Auto blocked={assessment_result['auto_response_blocked']}, " + f"Confidence={assessment_result['confidence_score']:.2f}" + ) + + return assessment_result + + except Exception as e: + logger.error(f"Error in AI-powered risk assessment: {str(e)}") + # Return safe default - require human review on error + return { + "risk_level": "high", + "risk_categories": ["system_error"], + "confidence_score": 0.0, + "reasoning": f"Risk assessment failed: {str(e)}", + "requires_human_review": True, + "auto_response_blocked": True, + "crisis_resources": self._get_crisis_resources() + } + + def _get_crisis_resources_for_categories(self, risk_categories: List[str]) -> List[str]: + """ + Get appropriate crisis resources based on risk categories. + """ + resources = [] + + for category in risk_categories: + if category in self.crisis_resources: + resources.extend(self.crisis_resources[category]) + + # If no specific resources found, use general crisis resources + if not resources and risk_categories: + resources = self.crisis_resources.get("general_crisis", []) + + # Remove duplicates while preserving order + seen = set() + unique_resources = [] + for resource in resources: + if resource not in seen: + seen.add(resource) + unique_resources.append(resource) + + return unique_resources + + async def _ai_risk_analysis( + self, + message: str, + user_id: str, + ai_soul_id: str, + session: Session + ) -> Dict[str, Any]: + """ + Use AI to perform more nuanced risk analysis. + """ + try: + # Get conversation context for better analysis + context = await self._get_conversation_context(session, user_id, ai_soul_id) + + # Build analysis prompt + system_prompt = """You are a professional risk assessment AI designed to evaluate mental health and safety risks in user messages. + +Your task is to analyze the user's message and conversation context to determine: +1. Risk level: low, medium, high, or critical +2. Risk categories: suicide, self_harm, violence, substance_abuse, abuse, mental_health_crisis, relationship_crisis, financial_crisis +3. Confidence score: 0.0 to 1.0 +4. Whether human counselor review is required +5. Whether AI response should be blocked until review + +Guidelines: +- CRITICAL: Immediate suicide/self-harm intent, specific plans, imminent danger +- HIGH: Strong indicators of crisis, distress, or harmful thoughts without immediate intent +- MEDIUM: Concerning patterns, mild distress indicators, potential risk factors +- LOW: Normal conversation, no significant risk indicators + +Be conservative - err on the side of safety. When in doubt, recommend human review. + +Respond with valid JSON only.""" + + user_prompt = f""" +Analyze this message for risk: + +Message: "{message}" + +Context: {context} + +Provide assessment as JSON with keys: risk_level, risk_categories, confidence_score, reasoning, requires_human_review, auto_response_blocked +""" + + response = self.client.chat.completions.create( + model="gpt-4", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": user_prompt} + ], + max_tokens=500, + temperature=0.1 # Low temperature for consistent risk assessment + ) + + # Parse AI response + ai_result = json.loads(response.choices[0].message.content.strip()) + + # Validate and enhance result + validated_result = self._validate_ai_assessment(ai_result) + + # Add crisis resources if needed + if validated_result["requires_human_review"]: + validated_result["crisis_resources"] = self._get_crisis_resources() + else: + validated_result["crisis_resources"] = [] + + return validated_result + + except Exception as e: + logger.error(f"AI risk analysis failed: {str(e)}") + # Fallback to keyword-based screening + return self._quick_risk_screening(message) + + def _validate_ai_assessment(self, ai_result: Dict[str, Any]) -> Dict[str, Any]: + """ + Validate and sanitize AI assessment results. + """ + # Ensure required fields exist with defaults + validated = { + "risk_level": ai_result.get("risk_level", "medium"), + "risk_categories": ai_result.get("risk_categories", []), + "confidence_score": float(ai_result.get("confidence_score", 0.5)), + "reasoning": ai_result.get("reasoning", "AI analysis completed"), + "requires_human_review": bool(ai_result.get("requires_human_review", False)), + "auto_response_blocked": bool(ai_result.get("auto_response_blocked", False)) + } + + # Validate risk level + if validated["risk_level"] not in ["low", "medium", "high", "critical"]: + validated["risk_level"] = "medium" + + # Validate confidence score + validated["confidence_score"] = max(0.0, min(1.0, validated["confidence_score"])) + + # Ensure critical/high risk requires review + if validated["risk_level"] in ["critical", "high"]: + validated["requires_human_review"] = True + + # Critical risk should block auto response + if validated["risk_level"] == "critical": + validated["auto_response_blocked"] = True + + return validated + + async def _get_conversation_context( + self, + session: Session, + user_id: str, + ai_soul_id: str + ) -> str: + """ + Get recent conversation context for risk analysis. + """ + try: + # Get recent messages + statement = ( + select(ChatMessage) + .where( + ChatMessage.user_id == user_id, + ChatMessage.ai_soul_id == ai_soul_id + ) + .order_by(ChatMessage.timestamp.desc()) + .limit(5) + ) + messages = session.exec(statement).all() + + if not messages: + return "No previous conversation context available." + + context_parts = [] + for msg in reversed(messages): # Show chronological order + role = "User" if msg.is_from_user else "AI" + context_parts.append(f"{role}: {msg.content[:200]}...") + + return "\n".join(context_parts) + + except Exception as e: + logger.error(f"Error getting conversation context: {str(e)}") + return "Context unavailable due to error." + + async def _save_risk_assessment( + self, + session: Session, + chat_message_id: str, + user_id: str, + ai_soul_id: str, + organization_id: str | None, + assessment_result: Dict[str, Any] + ) -> RiskAssessment: + """ + Save risk assessment to database. + """ + risk_assessment = RiskAssessment( + chat_message_id=chat_message_id, + user_id=user_id, + ai_soul_id=ai_soul_id, + organization_id=organization_id, + risk_level=assessment_result["risk_level"], + risk_categories=json.dumps(assessment_result["risk_categories"]), + confidence_score=assessment_result["confidence_score"], + reasoning=assessment_result["reasoning"], + requires_human_review=assessment_result["requires_human_review"], + auto_response_blocked=assessment_result["auto_response_blocked"] + ) + + session.add(risk_assessment) + session.commit() + session.refresh(risk_assessment) + + return risk_assessment + + def _convert_content_analysis_to_risk_assessment(self, content_analysis: Dict[str, Any]) -> Dict[str, Any]: + """Convert content filter analysis to risk assessment format.""" + # Map content filter categories to risk assessment categories + category_mapping = { + "self_harm": "suicide", + "violence": "violence", + "sexual": "mental_health_crisis" # Sexual content concerns mapped to mental health + } + + # Map severity levels + severity_mapping = { + "critical": "critical", + "high": "high", + "medium": "medium", + "low": "low" + } + + risk_categories = [] + for category in content_analysis.get("categories", []): + mapped_category = category_mapping.get(category, "mental_health_crisis") + if mapped_category not in risk_categories: + risk_categories.append(mapped_category) + + risk_level = severity_mapping.get(content_analysis.get("severity", "low"), "low") + + # Determine if human review is required + requires_review = ( + content_analysis.get("action") in ["crisis_intervention", "warn"] or + content_analysis.get("severity") in ["high", "critical"] + ) + + # Block auto-response for crisis situations + block_response = content_analysis.get("action") == "crisis_intervention" + + return { + "risk_level": risk_level, + "risk_categories": risk_categories, + "confidence_score": 0.8, # High confidence since content filter already analyzed + "reasoning": f"Content filter detected {content_analysis.get('severity', 'unknown')} severity content with categories: {', '.join(content_analysis.get('categories', []))}", + "requires_human_review": requires_review, + "auto_response_blocked": block_response, + "crisis_resources": content_analysis.get("crisis_resources", self._get_crisis_resources()) if requires_review else [] + } + + def _get_crisis_resources(self) -> List[str]: + """ + Get crisis intervention resources. + """ + return self.crisis_resources.get("general_crisis", [ + "🆘 National Suicide Prevention Lifeline: 988 or 1-800-273-8255", + "📞 Crisis Text Line: Text HOME to 741741", + "🌐 Online Chat: suicidepreventionlifeline.org", + "🏥 Emergency Services: Call 911 immediately if in immediate danger", + "💬 SAMHSA National Helpline: 1-800-662-4357 (24/7 treatment referral)", + "🤝 Crisis Support: If you're in immediate danger, please contact emergency services or go to your nearest emergency room" + ]) + + async def get_recent_risk_assessments( + self, + session: Session, + user_id: str | None = None, + organization_id: str | None = None, + days: int = 7, + limit: int = 50 + ) -> List[RiskAssessment]: + """ + Get recent risk assessments for monitoring. + """ + try: + cutoff_date = datetime.utcnow() - timedelta(days=days) + + statement = select(RiskAssessment).where( + RiskAssessment.assessed_at >= cutoff_date + ) + + if user_id: + statement = statement.where(RiskAssessment.user_id == user_id) + + if organization_id: + statement = statement.where(RiskAssessment.organization_id == organization_id) + + statement = statement.order_by(RiskAssessment.assessed_at.desc()).limit(limit) + + assessments = session.exec(statement).all() + return list(assessments) + + except Exception as e: + logger.error(f"Error getting recent risk assessments: {str(e)}") + return [] + + async def get_high_risk_conversations( + self, + session: Session, + organization_id: str | None = None, + hours: int = 24 + ) -> List[Dict[str, Any]]: + """ + Get conversations with high risk assessments for counselor dashboard. + """ + try: + cutoff_date = datetime.utcnow() - timedelta(hours=hours) + + statement = ( + select(RiskAssessment) + .where( + RiskAssessment.assessed_at >= cutoff_date, + RiskAssessment.risk_level.in_(["high", "critical"]) + ) + ) + + if organization_id: + statement = statement.where(RiskAssessment.organization_id == organization_id) + + statement = statement.order_by(RiskAssessment.assessed_at.desc()) + + assessments = session.exec(statement).all() + + # Enrich with user and conversation details + enriched_conversations = [] + for assessment in assessments: + user = session.get(User, assessment.user_id) + ai_soul = session.get(AISoulEntity, assessment.ai_soul_id) + chat_message = session.get(ChatMessage, assessment.chat_message_id) + + enriched_conversations.append({ + "assessment_id": str(assessment.id), + "risk_level": assessment.risk_level, + "risk_categories": json.loads(assessment.risk_categories), + "confidence_score": assessment.confidence_score, + "reasoning": assessment.reasoning, + "assessed_at": assessment.assessed_at, + "user_name": user.full_name if user else "Unknown", + "user_email": user.email if user else "Unknown", + "ai_soul_name": ai_soul.name if ai_soul else "Unknown", + "message_content": chat_message.content if chat_message else "Message not found", + "requires_review": assessment.requires_human_review, + "response_blocked": assessment.auto_response_blocked + }) + + return enriched_conversations + + except Exception as e: + logger.error(f"Error getting high risk conversations: {str(e)}") + return [] + + def _get_risk_level_priority(self, risk_level: str) -> int: + """Get priority number for risk level comparison.""" + priority_map = { + "low": 1, + "medium": 2, + "high": 3, + "critical": 4 + } + return priority_map.get(risk_level, 1) \ No newline at end of file diff --git a/backend/app/services/training_service.py b/backend/app/services/training_service.py new file mode 100644 index 0000000000..3275e8ace2 --- /dev/null +++ b/backend/app/services/training_service.py @@ -0,0 +1,559 @@ +import json +import logging +import os +import uuid +from typing import Any + +from fastapi import HTTPException, UploadFile +from openai import OpenAI +from PyPDF2 import PdfReader +from sqlmodel import Session, select + +# ChromaDB removed - using Enhanced RAG with Qdrant instead +from app.core.config import settings +from app.models import ( + AISoulEntity, + TrainingDocument, + TrainingDocumentChunk, + TrainingMessage, +) +from app.utils import get_file_hash +from app.models import User + +logger = logging.getLogger(__name__) + + +class TrainingService: + def __init__(self, db: Session): + self.db = db + self.upload_dir = os.path.join(settings.UPLOAD_DIR, "training") + os.makedirs(self.upload_dir, exist_ok=True) + self.client = OpenAI(api_key=settings.OPENAI_API_KEY) + + # ChromaDB removed - Enhanced RAG with Qdrant will handle training data storage + + async def send_training_message( + self, + user_id: str, + ai_soul_id: str, + content: str, + is_from_trainer: bool = True + ) -> TrainingMessage: + """Send a training message and generate embedding.""" + try: + # Verify AI soul exists + ai_soul = self.db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul not found") + + # Get user to check role + user = self.db.get(User, user_id) + if not user: + raise HTTPException(status_code=404, detail="User not found") + + # Check authorization: admins can train any soul, trainers can only train their own + if not user.is_superuser and user.role not in ["admin", "super_admin"]: + if ai_soul.user_id != uuid.UUID(user_id): + raise HTTPException(status_code=403, detail="Not authorized to train this AI soul") + + # Generate embedding for the message + embedding = await self.generate_embedding(content) + + # Generate message ID + message_id = str(uuid.uuid4()) + + # Create training message + training_message = TrainingMessage( + id=uuid.UUID(message_id), + content=content, + is_from_trainer=is_from_trainer, + ai_soul_id=uuid.UUID(ai_soul_id), + user_id=uuid.UUID(user_id), + embedding=json.dumps(embedding) + ) + + # Increment interaction count for this training conversation pair + ai_soul.interaction_count += 1 + self.db.add(ai_soul) + + self.db.add(training_message) + self.db.commit() + self.db.refresh(training_message) + + # Generate AI response + response_content = await self.generate_ai_response(content, ai_soul_id) + response_embedding = await self.generate_embedding(response_content) + + # Generate response ID + response_id = str(uuid.uuid4()) + + # Create AI response message + response_message = TrainingMessage( + id=uuid.UUID(response_id), + content=response_content, + is_from_trainer=False, + ai_soul_id=uuid.UUID(ai_soul_id), + user_id=uuid.UUID(user_id), + embedding=json.dumps(response_embedding) + ) + + self.db.add(response_message) + self.db.commit() + self.db.refresh(response_message) + + return training_message + + except Exception as e: + logger.error(f"Error sending training message: {str(e)}") + raise HTTPException(status_code=500, detail="Failed to send training message") + + async def generate_ai_response(self, user_message: str, ai_soul_id: str) -> str: + """Generate AI response using similar training data.""" + try: + # Get recent training messages for context (simple database query) + recent_messages = self.db.exec( + select(TrainingMessage) + .where(TrainingMessage.ai_soul_id == uuid.UUID(ai_soul_id)) + .order_by(TrainingMessage.timestamp.desc()) + .limit(5) + ).all() + + # Build context from recent messages + context = "\n".join([ + f"{'Trainer' if msg.is_from_trainer else 'AI'}: {msg.content}" + for msg in recent_messages + ]) + + # Generate response using OpenAI + response = self.client.chat.completions.create( + model="gpt-3.5-turbo", + messages=[ + {"role": "system", "content": "You are an AI assistant trained to respond in a way that reflects the training data provided. Use the context to understand the communication style and preferences of the trainer."}, + {"role": "user", "content": f"Context:\n{context}\n\nUser message: {user_message}\n\nRespond in a way that reflects the training data style:"} + ] + ) + + return response.choices[0].message.content + + except Exception as e: + logger.error(f"Error generating AI response: {str(e)}") + return f"I understand. I'll learn from your message: \"{user_message}\". This helps me better understand your communication style and preferences." + + async def upload_training_document( + self, + file: UploadFile, + user_id: str, + ai_soul_id: str, + description: str | None = None + ) -> TrainingDocument: + """Upload a training document and create initial database record.""" + try: + # Verify AI soul exists + ai_soul = self.db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul not found") + + # Get user to check role + user = self.db.get(User, user_id) + if not user: + raise HTTPException(status_code=404, detail="User not found") + + # Check authorization: admins can upload to any soul, trainers can only upload to their own + if not user.is_superuser and user.role not in ["admin", "super_admin"]: + if ai_soul.user_id != uuid.UUID(user_id): + raise HTTPException(status_code=403, detail="Not authorized to train this AI soul") + + # Validate file type + allowed_types = ["application/pdf", "text/plain", "text/markdown"] + # Some browsers send different MIME types for markdown + if file.content_type not in allowed_types and not file.filename.endswith(('.txt', '.md', '.pdf')): + raise HTTPException( + status_code=400, + detail="Only PDF, TXT, and Markdown files are supported" + ) + + # Read file content and validate + content = await file.read() + if len(content) > settings.MAX_UPLOAD_SIZE: + raise HTTPException(status_code=400, detail="File too large") + + # Generate unique filename + file_hash = get_file_hash(content) + ext = os.path.splitext(file.filename)[1] + filename = f"{file_hash}{ext}" + file_path = os.path.join(self.upload_dir, filename) + + # Save file to disk + with open(file_path, "wb") as f: + f.write(content) + + # Create training document record + training_document = TrainingDocument( + filename=filename, + original_filename=file.filename, + file_size=len(content), + content_type=file.content_type, + description=description, + file_path=file_path, + ai_soul_id=uuid.UUID(ai_soul_id), + user_id=uuid.UUID(user_id), + ) + + self.db.add(training_document) + self.db.commit() + self.db.refresh(training_document) + + # Start async processing + await self.process_training_document(training_document) + + return training_document + + except Exception as e: + logger.error(f"Error uploading training document: {str(e)}") + raise HTTPException(status_code=500, detail="Failed to upload training document") + + async def process_training_document(self, training_document: TrainingDocument) -> None: + """Process uploaded training document and create chunks with embeddings.""" + try: + # Update status to processing + training_document.processing_status = "processing" + self.db.commit() + + # Extract text chunks based on file type + if training_document.content_type == "application/pdf": + chunks = self._extract_pdf_chunks(training_document.file_path) + else: # text/plain, text/markdown, or other text files + chunks = self._extract_text_chunks(training_document.file_path) + + # Create chunks with embeddings + for idx, (content, metadata) in enumerate(chunks): + # Generate embedding for chunk + embedding = await self.generate_embedding(content) + + # Generate chunk ID + chunk_id = str(uuid.uuid4()) + + chunk = TrainingDocumentChunk( + id=uuid.UUID(chunk_id), + training_document_id=training_document.id, + ai_soul_id=training_document.ai_soul_id, + user_id=training_document.user_id, + content=content, + chunk_index=idx, + chunk_metadata=json.dumps(metadata), + embedding=json.dumps(embedding) + ) + self.db.add(chunk) + + # Update document status and chunk count + training_document.processing_status = "completed" + training_document.chunk_count = len(chunks) + self.db.commit() + + except Exception as e: + logger.error(f"Error processing training document: {str(e)}") + training_document.processing_status = "failed" + self.db.commit() + raise + + def _extract_pdf_chunks(self, file_path: str) -> list[tuple[str, dict[str, Any]]]: + """Extract text from PDF and split into optimized chunks for better context.""" + chunks = [] + + try: + with open(file_path, "rb") as file: + pdf_reader = PdfReader(file) + + for page_num, page in enumerate(pdf_reader.pages): + text = page.extract_text() + + if text.strip(): + # Enhanced chunking strategy for maximum context + # Use larger chunk size (1000 words) with 200-word overlap for better context + words = text.split() + chunk_size = 1000 # Increased from 200 for more context + overlap_size = 200 # Overlap for context continuity + + for i in range(0, len(words), chunk_size - overlap_size): + chunk_words = words[i:i + chunk_size] + chunk_text = " ".join(chunk_words) + + # Only create chunk if it has substantial content + if len(chunk_text.strip()) > 100: + metadata = { + "page": page_num + 1, + "chunk_start": i, + "chunk_end": i + len(chunk_words), + "chunk_size": len(chunk_words), + "source": "pdf", + "total_pages": len(pdf_reader.pages) + } + + chunks.append((chunk_text, metadata)) + + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Failed to extract text from PDF: {str(e)}" + ) + + return chunks + + def _extract_text_chunks(self, file_path: str) -> list[tuple[str, dict[str, Any]]]: + """Extract text from plain text file and split into optimized chunks.""" + chunks = [] + + try: + with open(file_path, encoding="utf-8") as file: + text = file.read() + + # Enhanced chunking strategy for text files + # Split by paragraphs first, then by words if needed + paragraphs = text.split('\n\n') + current_chunk = "" + chunk_index = 0 + word_count = 0 + max_words_per_chunk = 1000 # Increased for more context + overlap_words = 200 + + for paragraph in paragraphs: + paragraph = paragraph.strip() + if not paragraph: + continue + + paragraph_words = len(paragraph.split()) + + # If adding this paragraph would exceed limit, save current chunk + if word_count + paragraph_words > max_words_per_chunk and current_chunk: + metadata = { + "chunk_index": chunk_index, + "word_count": word_count, + "source": "text", + "chunk_type": "paragraph_based" + } + + chunks.append((current_chunk.strip(), metadata)) + + # Start new chunk with overlap from previous chunk + words = current_chunk.split() + if len(words) > overlap_words: + overlap_text = " ".join(words[-overlap_words:]) + current_chunk = overlap_text + "\n\n" + paragraph + word_count = overlap_words + paragraph_words + else: + current_chunk = paragraph + word_count = paragraph_words + + chunk_index += 1 + else: + # Add paragraph to current chunk + if current_chunk: + current_chunk += "\n\n" + paragraph + else: + current_chunk = paragraph + word_count += paragraph_words + + # Add final chunk if it has content + if current_chunk.strip(): + metadata = { + "chunk_index": chunk_index, + "word_count": word_count, + "source": "text", + "chunk_type": "paragraph_based" + } + + chunks.append((current_chunk.strip(), metadata)) + + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Failed to extract text from file: {str(e)}" + ) + + return chunks + + async def generate_embedding(self, text: str) -> list[float]: + """Generate embedding for text using OpenAI.""" + try: + response = self.client.embeddings.create( + model="text-embedding-ada-002", + input=text + ) + return response.data[0].embedding + except Exception as e: + logger.error(f"Error generating embedding: {str(e)}") + raise HTTPException( + status_code=500, + detail="Failed to generate embedding" + ) + + async def get_training_data( + self, + ai_soul_id: str, + user_id: str, + query: str, + limit: int = 10 + ) -> list[dict[str, Any]]: + """Get relevant training data for AI soul based on semantic similarity with strict isolation.""" + try: + # Verify AI soul exists and get owner info + ai_soul = self.db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul not found") + + logger.info(f"Searching training data for AI soul {ai_soul_id} with query: '{query}'") + logger.info(f"AI Soul owner: {ai_soul.user_id}, Requester: {user_id}") + + # Generate embedding for the query + query_embedding = await self.generate_embedding(query) + + results = [] + + # Get ONLY training messages for THIS specific AI soul (strict isolation) + training_messages = self.db.exec( + select(TrainingMessage) + .where( + TrainingMessage.ai_soul_id == uuid.UUID(ai_soul_id), + TrainingMessage.embedding.is_not(None) + ) + .order_by(TrainingMessage.timestamp.desc()) + .limit(100) # Increased limit for better search + ).all() + + logger.info(f"Found {len(training_messages)} training messages with embeddings for AI soul {ai_soul_id}") + + # Calculate semantic similarity for training messages + for message in training_messages: + try: + # Parse the stored embedding + message_embedding = json.loads(message.embedding) + + # Calculate cosine similarity + similarity = self.cosine_similarity(query_embedding, message_embedding) + + # Boost trainer messages slightly for better learning + if message.is_from_trainer: + similarity += 0.05 + + # Only include results with reasonable similarity (lowered threshold for better recall) + if similarity > 0.25: # Lowered from 0.3 for better recall + results.append({ + "type": "message", + "content": message.content, + "similarity": similarity, + "timestamp": message.timestamp, + "is_from_trainer": message.is_from_trainer, + "ai_soul_id": str(message.ai_soul_id) # Include for verification + }) + + except (json.JSONDecodeError, TypeError) as e: + logger.warning(f"Failed to parse embedding for message {message.id}: {e}") + continue + + # Get ONLY training document chunks for THIS specific AI soul (strict isolation) + training_chunks = self.db.exec( + select(TrainingDocumentChunk) + .where( + TrainingDocumentChunk.ai_soul_id == uuid.UUID(ai_soul_id), + TrainingDocumentChunk.embedding.is_not(None) + ) + .limit(50) # Increased limit for better search + ).all() + + logger.info(f"Found {len(training_chunks)} document chunks with embeddings for AI soul {ai_soul_id}") + + # Calculate semantic similarity for document chunks + for chunk in training_chunks: + try: + # Parse the stored embedding + chunk_embedding = json.loads(chunk.embedding) + + # Calculate cosine similarity + similarity = self.cosine_similarity(query_embedding, chunk_embedding) + + # Only include results with reasonable similarity + if similarity > 0.25: # Lowered threshold for better recall + results.append({ + "type": "document", + "content": chunk.content, + "similarity": similarity, + "metadata": json.loads(chunk.chunk_metadata) if chunk.chunk_metadata else {}, + "ai_soul_id": str(chunk.ai_soul_id) # Include for verification + }) + + except (json.JSONDecodeError, TypeError) as e: + logger.warning(f"Failed to parse embedding for chunk {chunk.id}: {e}") + continue + + # Sort by similarity (highest first) + results.sort(key=lambda x: x["similarity"], reverse=True) + + # Verify data isolation - all results should belong to the requested AI soul + for result in results: + if result.get("ai_soul_id") != ai_soul_id: + logger.error(f"Data isolation breach detected! Found data from soul {result.get('ai_soul_id')} in results for soul {ai_soul_id}") + raise HTTPException(status_code=500, detail="Data isolation error") + + logger.info(f"Returning {len(results[:limit])} relevant training results. Top scores: {[round(r['similarity'], 3) for r in results[:3]]}") + return results[:limit] + + except Exception as e: + logger.error(f"Error getting training data: {str(e)}") + return [] + + def cosine_similarity(self, vec1: list[float], vec2: list[float]) -> float: + """Calculate cosine similarity between two vectors.""" + try: + import math + + dot_product = sum(a * b for a, b in zip(vec1, vec2, strict=False)) + magnitude1 = math.sqrt(sum(a * a for a in vec1)) + magnitude2 = math.sqrt(sum(a * a for a in vec2)) + + if magnitude1 == 0 or magnitude2 == 0: + return 0 + + return dot_product / (magnitude1 * magnitude2) + + except Exception as e: + logger.error(f"Error calculating cosine similarity: {str(e)}") + return 0 + + def get_training_messages( + self, + ai_soul_id: str, + user_id: str, + skip: int = 0, + limit: int = 50 + ) -> list[TrainingMessage]: + """Get training messages for an AI soul.""" + try: + # Verify AI soul exists + ai_soul = self.db.get(AISoulEntity, ai_soul_id) + if not ai_soul: + raise HTTPException(status_code=404, detail="AI Soul not found") + + # Get user to check role + user = self.db.get(User, user_id) + if not user: + raise HTTPException(status_code=404, detail="User not found") + + # Check authorization: admins can view any soul's training, trainers can only view their own + if not user.is_superuser and user.role not in ["admin", "super_admin"]: + if ai_soul.user_id != uuid.UUID(user_id): + raise HTTPException(status_code=403, detail="Not authorized to access this AI soul") + + # Get training messages + messages = self.db.exec( + select(TrainingMessage) + .where(TrainingMessage.ai_soul_id == uuid.UUID(ai_soul_id)) + .order_by(TrainingMessage.timestamp.desc()) + .offset(skip) + .limit(limit) + ).all() + + return list(messages) + + except Exception as e: + logger.error(f"Error getting training messages: {str(e)}") + return [] diff --git a/backend/app/tasks/__init__.py b/backend/app/tasks/__init__.py new file mode 100644 index 0000000000..cd1aa15839 --- /dev/null +++ b/backend/app/tasks/__init__.py @@ -0,0 +1 @@ +# Tasks package for Celery background processing diff --git a/backend/app/tasks/cleanup_tasks.py b/backend/app/tasks/cleanup_tasks.py new file mode 100644 index 0000000000..6dc1f80023 --- /dev/null +++ b/backend/app/tasks/cleanup_tasks.py @@ -0,0 +1,209 @@ +""" +Cleanup and Maintenance Tasks for Celery + +This module contains tasks for: +- Cleaning up expired sessions +- Removing old processing logs +- Archiving old data +- Database maintenance +""" + +import logging +from datetime import datetime, timedelta, timezone +from typing import Any + +from sqlmodel import Session, delete, select + +from app.core.db import engine +from app.models import ( + AISoulEntity, + ChatMessage, + Document, + DocumentChunk, + TrainingDocument, + TrainingDocumentChunk, + TrainingMessage, + User, +) + +logger = logging.getLogger(__name__) + + +def cleanup_expired_chat_sessions(): + """ + Clean up old chat messages and training data. + """ + try: + with Session(engine) as session: + # Clean up old chat messages (older than 90 days) + ninety_days_ago = datetime.now(timezone.utc) - timedelta(days=90) + + old_messages = session.exec( + select(ChatMessage).where( + ChatMessage.timestamp < ninety_days_ago + ) + ).all() + + if not old_messages: + return {"status": "success", "message": "No old chat messages to clean up"} + + # Delete old messages + session.exec( + delete(ChatMessage).where( + ChatMessage.timestamp < ninety_days_ago + ) + ) + + session.commit() + logger.info(f"Cleaned up {len(old_messages)} old chat messages") + + return { + "status": "success", + "message": f"Cleaned up {len(old_messages)} old chat messages" + } + + except Exception as exc: + logger.error(f"Error cleaning up expired chat sessions: {exc}") + return {"status": "error", "message": str(exc)} + + +def cleanup_old_documents(): + """ + Clean up old document processing logs and unused documents. + """ + try: + with Session(engine) as session: + # Clean up old document chunks (older than 180 days) + six_months_ago = datetime.now(timezone.utc) - timedelta(days=180) + + old_chunks = session.exec( + select(DocumentChunk).where( + DocumentChunk.created_at < six_months_ago + ) + ).all() + + if old_chunks: + # Delete old chunks + session.exec( + delete(DocumentChunk).where( + DocumentChunk.created_at < six_months_ago + ) + ) + + session.commit() + logger.info(f"Cleaned up {len(old_chunks)} old document chunks") + + return { + "status": "success", + "message": f"Cleaned up {len(old_chunks)} old document chunks" + } + else: + return {"status": "success", "message": "No old document chunks to clean up"} + + except Exception as exc: + logger.error(f"Error cleaning up old documents: {exc}") + return {"status": "error", "message": str(exc)} + + +def cleanup_old_training_data(): + """ + Clean up old training data that is no longer needed. + """ + try: + with Session(engine) as session: + # Clean up training data older than 1 year + one_year_ago = datetime.now(timezone.utc) - timedelta(days=365) + + old_training_chunks = session.exec( + select(TrainingDocumentChunk).where( + TrainingDocumentChunk.created_at < one_year_ago + ) + ).all() + + old_training_messages = session.exec( + select(TrainingMessage).where( + TrainingMessage.timestamp < one_year_ago + ) + ).all() + + chunks_deleted = 0 + messages_deleted = 0 + + if old_training_chunks: + session.exec( + delete(TrainingDocumentChunk).where( + TrainingDocumentChunk.created_at < one_year_ago + ) + ) + chunks_deleted = len(old_training_chunks) + + if old_training_messages: + session.exec( + delete(TrainingMessage).where( + TrainingMessage.timestamp < one_year_ago + ) + ) + messages_deleted = len(old_training_messages) + + if chunks_deleted > 0 or messages_deleted > 0: + session.commit() + logger.info(f"Cleaned up {chunks_deleted} training chunks and {messages_deleted} training messages") + + return { + "status": "success", + "chunks_deleted": chunks_deleted, + "messages_deleted": messages_deleted + } + else: + return {"status": "success", "message": "No old training data to clean up"} + + except Exception as exc: + logger.error(f"Error cleaning up old training data: {exc}") + return {"status": "error", "message": str(exc)} + + +def get_system_stats(): + """ + Get system statistics for monitoring. + """ + try: + with Session(engine) as session: + # Count various entities + total_users = session.exec(select(User)).count() + total_ai_souls = session.exec(select(AISoulEntity)).count() + total_chat_messages = session.exec(select(ChatMessage)).count() + total_documents = session.exec(select(Document)).count() + total_training_documents = session.exec(select(TrainingDocument)).count() + total_training_messages = session.exec(select(TrainingMessage)).count() + + # Get recent activity (last 7 days) + seven_days_ago = datetime.now(timezone.utc) - timedelta(days=7) + recent_messages = session.exec( + select(ChatMessage).where( + ChatMessage.timestamp >= seven_days_ago + ) + ).count() + + recent_training = session.exec( + select(TrainingMessage).where( + TrainingMessage.timestamp >= seven_days_ago + ) + ).count() + + return { + "status": "success", + "stats": { + "total_users": total_users, + "total_ai_souls": total_ai_souls, + "total_chat_messages": total_chat_messages, + "total_documents": total_documents, + "total_training_documents": total_training_documents, + "total_training_messages": total_training_messages, + "recent_chat_messages": recent_messages, + "recent_training_messages": recent_training + } + } + + except Exception as exc: + logger.error(f"Error getting system stats: {exc}") + return {"status": "error", "message": str(exc)} diff --git a/backend/app/tasks/document_processing.py b/backend/app/tasks/document_processing.py new file mode 100644 index 0000000000..c15735588c --- /dev/null +++ b/backend/app/tasks/document_processing.py @@ -0,0 +1,331 @@ +""" +Document Processing Tasks for Celery + +This module contains background tasks for processing uploaded documents: +- Text extraction from various file formats +- Intelligent chunking +- Embedding generation +- Database indexing +""" + +import json +import logging +import uuid +from datetime import datetime + +from celery import current_task +from sqlmodel import Session, select + +from app.celery_app import celery_app +from app.core.db import engine +from app.models import ( + Document, + DocumentChunk, + DocumentChunkEnhanced, + DocumentProcessingLog, + TrainingDocument, + TrainingDocumentChunkEnhanced, +) +from app.services.document_service import DocumentService +from app.services.enhanced_rag_service import EnhancedRAGService + +logger = logging.getLogger(__name__) + + +@celery_app.task(bind=True, max_retries=3, default_retry_delay=60) +def process_document(self, document_id: str, user_id: str, document_type: str = "general"): + """ + Process an uploaded document: extract text, create chunks, and generate embeddings. + + Args: + document_id: UUID of the document to process + user_id: UUID of the user who uploaded the document + document_type: Type of document ("general" or "training") + """ + try: + with Session(engine) as session: + # Get document + if document_type == "training": + document = session.get(TrainingDocument, document_id) + else: + document = session.get(Document, document_id) + + if not document: + logger.error(f"Document {document_id} not found") + return {"status": "error", "message": "Document not found"} + + # Log processing start + log_entry = DocumentProcessingLog( + document_id=uuid.UUID(document_id), + user_id=uuid.UUID(user_id), + processing_stage="text_extraction", + status="started" + ) + session.add(log_entry) + session.commit() + + # Update document status + document.processing_status = "processing" + session.add(document) + session.commit() + + # Initialize services + doc_service = DocumentService(session) + rag_service = EnhancedRAGService(session) + + # Extract text from document + current_task.update_state( + state="PROGRESS", + meta={"stage": "text_extraction", "progress": 10} + ) + + text_content = doc_service.extract_text_from_file(document.file_path) + + if not text_content: + raise Exception("Failed to extract text from document") + + # Log text extraction completion + log_entry.status = "completed" + log_entry.processing_stage = "chunking" + log_entry.status = "started" + session.add(log_entry) + session.commit() + + # Create chunks + current_task.update_state( + state="PROGRESS", + meta={"stage": "chunking", "progress": 30} + ) + + chunks = rag_service.create_intelligent_chunks_sync( + text_content, + document_id=document_id, + user_id=user_id, + document_type=document_type + ) + + # Log chunking completion + log_entry.status = "completed" + log_entry.processing_stage = "embedding" + log_entry.status = "started" + log_entry.chunks_created = len(chunks) + session.add(log_entry) + session.commit() + + # Generate embeddings + current_task.update_state( + state="PROGRESS", + meta={"stage": "embedding", "progress": 60} + ) + + embedding_results = rag_service.generate_embeddings_batch_sync( + [chunk.content for chunk in chunks] + ) + + # Store chunks with embeddings + current_task.update_state( + state="PROGRESS", + meta={"stage": "indexing", "progress": 80} + ) + + total_tokens = 0 + for i, (chunk, embedding) in enumerate(zip(chunks, embedding_results, strict=False)): + chunk.embedding = json.dumps(embedding.tolist()) + session.add(chunk) + total_tokens += len(chunk.content.split()) + + # Update document + document.processing_status = "completed" + document.chunk_count = len(chunks) + session.add(document) + + # Log final completion + log_entry.status = "completed" + log_entry.processing_stage = "indexing" + log_entry.total_tokens = total_tokens + log_entry.completed_at = datetime.utcnow() + session.add(log_entry) + + session.commit() + + current_task.update_state( + state="SUCCESS", + meta={"stage": "completed", "progress": 100, "chunks_created": len(chunks)} + ) + + return { + "status": "success", + "chunks_created": len(chunks), + "total_tokens": total_tokens, + "document_id": document_id + } + + except Exception as exc: + logger.error(f"Error processing document {document_id}: {exc}") + + # Update document status + try: + with Session(engine) as session: + if document_type == "training": + document = session.get(TrainingDocument, document_id) + else: + document = session.get(Document, document_id) + + if document: + document.processing_status = "failed" + session.add(document) + session.commit() + + # Log error + log_entry = DocumentProcessingLog( + document_id=uuid.UUID(document_id), + user_id=uuid.UUID(user_id), + processing_stage="error", + status="failed", + error_message=str(exc) + ) + session.add(log_entry) + session.commit() + + except Exception as log_exc: + logger.error(f"Error logging failure: {log_exc}") + + # Retry logic + if self.request.retries < self.max_retries: + logger.info(f"Retrying document processing for {document_id}") + raise self.retry(exc=exc) + + return {"status": "error", "message": str(exc)} + + +@celery_app.task(bind=True, max_retries=2, default_retry_delay=30) +def reprocess_failed_document(self, document_id: str, user_id: str, document_type: str = "general"): + """ + Reprocess a failed document. + + Args: + document_id: UUID of the document to reprocess + user_id: UUID of the user who uploaded the document + document_type: Type of document ("general" or "training") + """ + try: + with Session(engine) as session: + # Get document + if document_type == "training": + document = session.get(TrainingDocument, document_id) + else: + document = session.get(Document, document_id) + + if not document: + return {"status": "error", "message": "Document not found"} + + # Reset document status + document.processing_status = "pending" + session.add(document) + session.commit() + + # Call main processing task + return process_document.delay(document_id, user_id, document_type) + + except Exception as exc: + logger.error(f"Error reprocessing document {document_id}: {exc}") + + if self.request.retries < self.max_retries: + raise self.retry(exc=exc) + + return {"status": "error", "message": str(exc)} + + +@celery_app.task +def batch_process_documents(document_ids: list[str], user_id: str, document_type: str = "general"): + """ + Process multiple documents in batch. + + Args: + document_ids: List of document UUIDs to process + user_id: UUID of the user who uploaded the documents + document_type: Type of documents ("general" or "training") + """ + results = [] + + for doc_id in document_ids: + try: + result = process_document.delay(doc_id, user_id, document_type) + results.append({ + "document_id": doc_id, + "task_id": result.id, + "status": "queued" + }) + except Exception as exc: + logger.error(f"Error queueing document {doc_id}: {exc}") + results.append({ + "document_id": doc_id, + "status": "error", + "message": str(exc) + }) + + return { + "status": "success", + "total_documents": len(document_ids), + "results": results + } + + +@celery_app.task +def cleanup_orphaned_chunks(): + """ + Clean up document chunks that no longer have associated documents. + """ + try: + with Session(engine) as session: + # Find orphaned regular chunks + orphaned_chunks = session.exec( + select(DocumentChunk).where( + ~DocumentChunk.document_id.in_( + select(Document.id) + ) + ) + ).all() + + # Find orphaned enhanced chunks + orphaned_enhanced = session.exec( + select(DocumentChunkEnhanced).where( + ~DocumentChunkEnhanced.document_id.in_( + select(Document.id) + ) + ) + ).all() + + # Find orphaned training chunks + orphaned_training = session.exec( + select(TrainingDocumentChunkEnhanced).where( + ~TrainingDocumentChunkEnhanced.training_document_id.in_( + select(TrainingDocument.id) + ) + ) + ).all() + + # Delete orphaned chunks + for chunk in orphaned_chunks: + session.delete(chunk) + + for chunk in orphaned_enhanced: + session.delete(chunk) + + for chunk in orphaned_training: + session.delete(chunk) + + session.commit() + + total_cleaned = len(orphaned_chunks) + len(orphaned_enhanced) + len(orphaned_training) + + logger.info(f"Cleaned up {total_cleaned} orphaned chunks") + + return { + "status": "success", + "chunks_cleaned": total_cleaned + } + + except Exception as exc: + logger.error(f"Error cleaning up orphaned chunks: {exc}") + return {"status": "error", "message": str(exc)} diff --git a/backend/app/tasks/rag_tasks.py b/backend/app/tasks/rag_tasks.py new file mode 100644 index 0000000000..a8cee3129e --- /dev/null +++ b/backend/app/tasks/rag_tasks.py @@ -0,0 +1,421 @@ +""" +RAG-related Background Tasks for Celery + +This module contains tasks for: +- Search analytics and optimization +- Vector database maintenance +- Index rebuilding and optimization +- Performance monitoring +""" + +import json +import logging +import uuid +from datetime import datetime, timedelta + +from sqlmodel import Session, select + +from app.celery_app import celery_app +from app.core.db import engine +from app.models import ( + DocumentChunkEnhanced, + RAGConfiguration, + SearchQuery, + SearchResultClick, + TrainingDocumentChunkEnhanced, +) +from app.services.enhanced_rag_service import EnhancedRAGService + +logger = logging.getLogger(__name__) + + +@celery_app.task +def update_search_analytics(): + """ + Update search analytics and performance metrics. + + This task runs daily to: + - Calculate search performance metrics + - Update chunk relevance scores + - Identify popular search patterns + - Generate optimization recommendations + """ + try: + with Session(engine) as session: + # Get recent search queries (last 7 days) + seven_days_ago = datetime.utcnow() - timedelta(days=7) + + recent_queries = session.exec( + select(SearchQuery).where( + SearchQuery.created_at >= seven_days_ago + ) + ).all() + + # Calculate metrics + total_queries = len(recent_queries) + avg_response_time = sum(q.response_time_ms for q in recent_queries) / total_queries if total_queries > 0 else 0 + queries_with_clicks = sum(1 for q in recent_queries if q.user_clicked_result) + click_through_rate = queries_with_clicks / total_queries if total_queries > 0 else 0 + + # Update chunk performance metrics + chunk_clicks = session.exec( + select(SearchResultClick).where( + SearchResultClick.clicked_at >= seven_days_ago + ) + ).all() + + # Group clicks by chunk + chunk_performance = {} + for click in chunk_clicks: + chunk_id = str(click.chunk_id) + if chunk_id not in chunk_performance: + chunk_performance[chunk_id] = { + "clicks": 0, + "total_similarity": 0, + "positions": [] + } + + chunk_performance[chunk_id]["clicks"] += 1 + chunk_performance[chunk_id]["total_similarity"] += click.similarity_score + chunk_performance[chunk_id]["positions"].append(click.result_position) + + # Update chunk relevance scores + for chunk_id, metrics in chunk_performance.items(): + chunk = session.get(DocumentChunkEnhanced, chunk_id) + if chunk: + # Calculate relevance score based on clicks and position + avg_position = sum(metrics["positions"]) / len(metrics["positions"]) + avg_similarity = metrics["total_similarity"] / metrics["clicks"] + + # Simple relevance formula (can be improved) + relevance_score = (avg_similarity * 0.7) + ((10 - avg_position) / 10 * 0.3) + + chunk.relevance_score = relevance_score + chunk.search_count += metrics["clicks"] + chunk.last_accessed = datetime.utcnow() + session.add(chunk) + + session.commit() + + logger.info(f"Updated search analytics: {total_queries} queries, {click_through_rate:.2%} CTR") + + return { + "status": "success", + "total_queries": total_queries, + "avg_response_time_ms": avg_response_time, + "click_through_rate": click_through_rate, + "chunks_updated": len(chunk_performance) + } + + except Exception as exc: + logger.error(f"Error updating search analytics: {exc}") + return {"status": "error", "message": str(exc)} + + +@celery_app.task(bind=True, max_retries=2, default_retry_delay=300) +def rebuild_vector_index(self, user_id: str, ai_soul_id: str | None = None): + """ + Rebuild vector index for a user's documents or specific AI soul. + + Args: + user_id: UUID of the user + ai_soul_id: Optional UUID of specific AI soul to rebuild + """ + try: + with Session(engine) as session: + rag_service = EnhancedRAGService(session) + + # Get chunks to reindex + if ai_soul_id: + # Rebuild for specific AI soul (training documents) + chunks = session.exec( + select(TrainingDocumentChunkEnhanced).where( + TrainingDocumentChunkEnhanced.ai_soul_id == uuid.UUID(ai_soul_id) + ) + ).all() + else: + # Rebuild for all user documents + chunks = session.exec( + select(DocumentChunkEnhanced).where( + DocumentChunkEnhanced.user_id == uuid.UUID(user_id) + ) + ).all() + + if not chunks: + return {"status": "success", "message": "No chunks to reindex"} + + # Regenerate embeddings and update vector database + chunk_contents = [chunk.content for chunk in chunks] + + # Generate new embeddings + embedding_results = rag_service.generate_embeddings_batch_sync(chunk_contents) + + # Update chunks with new embeddings + for chunk, embedding in zip(chunks, embedding_results, strict=False): + chunk.embedding = json.dumps(embedding.tolist()) + chunk.last_accessed = datetime.utcnow() + session.add(chunk) + + session.commit() + + # Update vector database + rag_service.update_vector_database(chunks) + + logger.info(f"Rebuilt vector index for {len(chunks)} chunks") + + return { + "status": "success", + "chunks_reindexed": len(chunks), + "user_id": user_id, + "ai_soul_id": ai_soul_id + } + + except Exception as exc: + logger.error(f"Error rebuilding vector index: {exc}") + + if self.request.retries < self.max_retries: + raise self.retry(exc=exc) + + return {"status": "error", "message": str(exc)} + + +@celery_app.task +def optimize_rag_configuration(user_id: str): + """ + Analyze user's search patterns and optimize RAG configuration. + + Args: + user_id: UUID of the user to optimize for + """ + try: + with Session(engine) as session: + # Get user's search history + thirty_days_ago = datetime.utcnow() - timedelta(days=30) + + user_queries = session.exec( + select(SearchQuery).where( + SearchQuery.user_id == uuid.UUID(user_id), + SearchQuery.created_at >= thirty_days_ago + ) + ).all() + + if not user_queries: + return {"status": "success", "message": "No search history to analyze"} + + # Analyze search patterns + avg_response_time = sum(q.response_time_ms for q in user_queries) / len(user_queries) + avg_results_count = sum(q.results_count for q in user_queries) / len(user_queries) + queries_with_clicks = sum(1 for q in user_queries if q.user_clicked_result) + click_through_rate = queries_with_clicks / len(user_queries) + + # Get current RAG configuration + rag_config = session.exec( + select(RAGConfiguration).where( + RAGConfiguration.user_id == uuid.UUID(user_id) + ) + ).first() + + if not rag_config: + # Create default configuration + rag_config = RAGConfiguration( + user_id=uuid.UUID(user_id), + chunking_strategy="semantic", + chunk_size=500, + chunk_overlap=50, + embedding_model="text-embedding-3-small", + search_algorithm="hybrid", + similarity_threshold=0.7, + max_results=10, + enable_reranking=True + ) + session.add(rag_config) + + # Optimization recommendations + recommendations = {} + + # If response time is too high, suggest smaller chunks or fewer results + if avg_response_time > 2000: # 2 seconds + recommendations["reduce_chunk_size"] = True + recommendations["reduce_max_results"] = True + rag_config.chunk_size = min(rag_config.chunk_size, 400) + rag_config.max_results = min(rag_config.max_results, 8) + + # If CTR is low, suggest enabling reranking or adjusting threshold + if click_through_rate < 0.3: + recommendations["enable_reranking"] = True + recommendations["lower_similarity_threshold"] = True + rag_config.enable_reranking = True + rag_config.similarity_threshold = max(rag_config.similarity_threshold - 0.1, 0.5) + + # If users are getting too few results, increase max_results + if avg_results_count < 3: + recommendations["increase_max_results"] = True + rag_config.max_results = min(rag_config.max_results + 2, 15) + + # Update configuration + rag_config.updated_at = datetime.utcnow() + session.add(rag_config) + session.commit() + + logger.info(f"Optimized RAG configuration for user {user_id}") + + return { + "status": "success", + "user_id": user_id, + "avg_response_time_ms": avg_response_time, + "click_through_rate": click_through_rate, + "recommendations": recommendations, + "updated_config": { + "chunk_size": rag_config.chunk_size, + "max_results": rag_config.max_results, + "similarity_threshold": rag_config.similarity_threshold, + "enable_reranking": rag_config.enable_reranking + } + } + + except Exception as exc: + logger.error(f"Error optimizing RAG configuration: {exc}") + return {"status": "error", "message": str(exc)} + + +@celery_app.task +def update_chunk_popularity(): + """ + Update chunk popularity metrics based on recent search activity. + """ + try: + with Session(engine) as session: + # Get recent search result clicks (last 24 hours) + yesterday = datetime.utcnow() - timedelta(days=1) + + recent_clicks = session.exec( + select(SearchResultClick).where( + SearchResultClick.clicked_at >= yesterday + ) + ).all() + + # Group by chunk and update metrics + chunk_updates = {} + for click in recent_clicks: + chunk_id = str(click.chunk_id) + if chunk_id not in chunk_updates: + chunk_updates[chunk_id] = { + "clicks": 0, + "ratings": [] + } + + chunk_updates[chunk_id]["clicks"] += 1 + if click.user_rating: + chunk_updates[chunk_id]["ratings"].append(click.user_rating) + + # Update chunks + for chunk_id, metrics in chunk_updates.items(): + chunk = session.get(DocumentChunkEnhanced, chunk_id) + if chunk: + chunk.click_count += metrics["clicks"] + + # Update relevance score if we have ratings + if metrics["ratings"]: + avg_rating = sum(metrics["ratings"]) / len(metrics["ratings"]) + # Weighted average with existing score + if chunk.relevance_score: + chunk.relevance_score = (chunk.relevance_score * 0.7) + (avg_rating / 5 * 0.3) + else: + chunk.relevance_score = avg_rating / 5 + + session.add(chunk) + + session.commit() + + logger.info(f"Updated popularity metrics for {len(chunk_updates)} chunks") + + return { + "status": "success", + "chunks_updated": len(chunk_updates), + "total_clicks": sum(metrics["clicks"] for metrics in chunk_updates.values()) + } + + except Exception as exc: + logger.error(f"Error updating chunk popularity: {exc}") + return {"status": "error", "message": str(exc)} + + +@celery_app.task +def generate_search_suggestions(user_id: str): + """ + Generate search suggestions based on user's document content and search history. + + Args: + user_id: UUID of the user to generate suggestions for + """ + try: + with Session(engine) as session: + # Get user's recent search queries + thirty_days_ago = datetime.utcnow() - timedelta(days=30) + + recent_queries = session.exec( + select(SearchQuery).where( + SearchQuery.user_id == uuid.UUID(user_id), + SearchQuery.created_at >= thirty_days_ago + ) + ).all() + + # Get user's document chunks to analyze content + user_chunks = session.exec( + select(DocumentChunkEnhanced).where( + DocumentChunkEnhanced.user_id == uuid.UUID(user_id) + ).limit(100) # Limit for performance + ).all() + + if not user_chunks: + return {"status": "success", "suggestions": []} + + # Extract common terms and topics from chunks + # This is a simplified approach - in production, you'd use NLP techniques + content_words = [] + for chunk in user_chunks: + # Simple word extraction (you'd want proper NLP here) + words = chunk.content.lower().split() + content_words.extend([w for w in words if len(w) > 4]) + + # Count word frequency + word_counts = {} + for word in content_words: + word_counts[word] = word_counts.get(word, 0) + 1 + + # Get most common words as potential suggestions + common_words = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)[:20] + + # Generate suggestions + suggestions = [] + for word, count in common_words[:10]: + suggestions.append({ + "query": word.capitalize(), + "frequency": count, + "type": "content_based" + }) + + # Add suggestions based on search history patterns + query_patterns = [q.query_text for q in recent_queries] + for pattern in set(query_patterns): + if len(pattern) > 3: + suggestions.append({ + "query": pattern, + "frequency": query_patterns.count(pattern), + "type": "history_based" + }) + + # Sort by frequency and limit + suggestions = sorted(suggestions, key=lambda x: x["frequency"], reverse=True)[:15] + + logger.info(f"Generated {len(suggestions)} search suggestions for user {user_id}") + + return { + "status": "success", + "user_id": user_id, + "suggestions": suggestions + } + + except Exception as exc: + logger.error(f"Error generating search suggestions: {exc}") + return {"status": "error", "message": str(exc)} diff --git a/backend/app/utils.py b/backend/app/utils.py index ac029f6342..642b3c206e 100644 --- a/backend/app/utils.py +++ b/backend/app/utils.py @@ -1,15 +1,14 @@ +import hashlib import logging from dataclasses import dataclass -from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta from pathlib import Path from typing import Any import emails # type: ignore import jwt from jinja2 import Template -from jwt.exceptions import InvalidTokenError -from app.core import security from app.core.config import settings logging.basicConfig(level=logging.INFO) @@ -31,12 +30,12 @@ def render_email_template(*, template_name: str, context: dict[str, Any]) -> str def send_email( - *, email_to: str, - subject: str = "", - html_content: str = "", + subject: str, + html_content: str, ) -> None: - assert settings.emails_enabled, "no provided configuration for email variables" + """Send email with subject and HTML content.""" + assert settings.EMAILS_ENABLED, "no provided configuration for email variables" message = emails.Message( subject=subject, html=html_content, @@ -45,79 +44,118 @@ def send_email( smtp_options = {"host": settings.SMTP_HOST, "port": settings.SMTP_PORT} if settings.SMTP_TLS: smtp_options["tls"] = True - elif settings.SMTP_SSL: - smtp_options["ssl"] = True if settings.SMTP_USER: smtp_options["user"] = settings.SMTP_USER if settings.SMTP_PASSWORD: smtp_options["password"] = settings.SMTP_PASSWORD response = message.send(to=email_to, smtp=smtp_options) - logger.info(f"send email result: {response}") + logging.info(f"Email sent to {email_to}, response: {response.status_code}") + + +def send_test_email(email_to: str) -> None: + project_name = settings.PROJECT_NAME + subject = f"{project_name} - Test email" + html_content = f""" + + +

Test Email from {project_name}

+

This is a test email sent to {email_to}

+ + + """ + send_email(email_to=email_to, subject=subject, html_content=html_content) def generate_test_email(email_to: str) -> EmailData: + """Generate test email data.""" project_name = settings.PROJECT_NAME subject = f"{project_name} - Test email" - html_content = render_email_template( - template_name="test_email.html", - context={"project_name": settings.PROJECT_NAME, "email": email_to}, - ) + html_content = f""" + + +

Test Email from {project_name}

+

This is a test email sent to {email_to}

+ + + """ return EmailData(html_content=html_content, subject=subject) def generate_reset_password_email(email_to: str, email: str, token: str) -> EmailData: + """Generate reset password email data.""" project_name = settings.PROJECT_NAME subject = f"{project_name} - Password recovery for user {email}" - link = f"{settings.FRONTEND_HOST}/reset-password?token={token}" - html_content = render_email_template( - template_name="reset_password.html", - context={ - "project_name": settings.PROJECT_NAME, - "username": email, - "email": email_to, - "valid_hours": settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS, - "link": link, - }, - ) + server_host = settings.SERVER_HOST + link = f"{server_host}/reset-password?token={token}" + html_content = f""" + + +

Password Recovery for {project_name}

+

Hello {email},

+

You have requested to reset your password. Click the link below to reset it:

+

Reset Password

+

This link will expire in {settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS} hours.

+

If you did not request this, please ignore this email.

+ + + """ return EmailData(html_content=html_content, subject=subject) -def generate_new_account_email( - email_to: str, username: str, password: str -) -> EmailData: +def send_reset_password_email(email_to: str, email: str, token: str) -> None: + """Send reset password email.""" + email_data = generate_reset_password_email(email_to=email_to, email=email, token=token) + send_email(email_to=email_to, subject=email_data.subject, html_content=email_data.html_content) + + +def generate_new_account_email(email_to: str, username: str, password: str) -> EmailData: + """Generate new account email data.""" project_name = settings.PROJECT_NAME subject = f"{project_name} - New account for user {username}" - html_content = render_email_template( - template_name="new_account.html", - context={ - "project_name": settings.PROJECT_NAME, - "username": username, - "password": password, - "email": email_to, - "link": settings.FRONTEND_HOST, - }, - ) + link = settings.SERVER_HOST + html_content = f""" + + +

Welcome to {project_name}

+

Hello {username},

+

Your account has been created successfully!

+

Email: {email_to}

+

Password: {password}

+

You can login at: {link}

+

Please change your password after your first login.

+ + + """ return EmailData(html_content=html_content, subject=subject) +def send_new_account_email(email_to: str, username: str, password: str) -> None: + """Send new account email.""" + email_data = generate_new_account_email(email_to=email_to, username=username, password=password) + send_email(email_to=email_to, subject=email_data.subject, html_content=email_data.html_content) + + def generate_password_reset_token(email: str) -> str: delta = timedelta(hours=settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS) - now = datetime.now(timezone.utc) + now = datetime.utcnow() expires = now + delta exp = expires.timestamp() encoded_jwt = jwt.encode( {"exp": exp, "nbf": now, "sub": email}, settings.SECRET_KEY, - algorithm=security.ALGORITHM, + algorithm="HS256", ) return encoded_jwt def verify_password_reset_token(token: str) -> str | None: try: - decoded_token = jwt.decode( - token, settings.SECRET_KEY, algorithms=[security.ALGORITHM] - ) - return str(decoded_token["sub"]) - except InvalidTokenError: + decoded_token = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"]) + return decoded_token["sub"] + except jwt.JWTError: return None + + +def get_file_hash(content: bytes) -> str: + """Generate a unique hash for file content.""" + return hashlib.sha256(content).hexdigest()[:16] # Using first 16 chars for shorter filenames diff --git a/backend/pyproject.toml b/backend/pyproject.toml index d1fbd0641c..515bbbb664 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -1,42 +1,93 @@ [project] name = "app" version = "0.1.0" -description = "" +description = "Backend API for AI Soul Entity" requires-python = ">=3.10,<4.0" dependencies = [ - "fastapi[standard]<1.0.0,>=0.114.2", - "python-multipart<1.0.0,>=0.0.7", + "fastapi>=0.100.0", + "uvicorn>=0.22.0", + "sqlmodel>=0.0.8", + "python-jose[cryptography]>=3.3.0", + "passlib[bcrypt]>=1.7.4", + "python-multipart>=0.0.6", + "emails>=0.6", + "psycopg>=3.1.18", + "alembic>=1.11.1", + "tenacity>=8.2.2", + "pydantic[email]>=2.0.0", + "openai>=1.0.0", + "PyPDF2>=3.0.0", + "chromadb>=0.4.22", "email-validator<3.0.0.0,>=2.1.0.post1", - "passlib[bcrypt]<2.0.0,>=1.7.4", - "tenacity<9.0.0,>=8.2.3", - "pydantic>2.0", - "emails<1.0,>=0.6", "jinja2<4.0.0,>=3.1.4", - "alembic<2.0.0,>=1.12.1", - "httpx<1.0.0,>=0.25.1", - "psycopg[binary]<4.0.0,>=3.1.13", - "sqlmodel<1.0.0,>=0.0.21", - # Pin bcrypt until passlib supports the latest + "httpx>=0.24.1", "bcrypt==4.3.0", "pydantic-settings<3.0.0,>=2.2.1", "sentry-sdk[fastapi]<2.0.0,>=1.40.6", "pyjwt<3.0.0,>=2.8.0", + "langchain<1.0.0,>=0.2.0", + "langchain-openai<1.0.0,>=0.1.0", + "tiktoken<1.0.0,>=0.7.0", + # Enhanced RAG System Dependencies + "qdrant-client>=1.7.0", + "sentence-transformers>=2.2.2", + "transformers>=4.30.0", + "torch>=2.0.0", + "numpy>=1.24.0", + "scikit-learn>=1.3.0", + "nltk>=3.8.0", + "spacy>=3.6.0", + "redis>=4.5.0", + "aioredis>=2.0.0", + "python-docx>=0.8.11", + "python-pptx>=0.6.21", + "openpyxl>=3.1.0", + "markdown>=3.4.0", + "beautifulsoup4>=4.12.0", + "lxml>=4.9.0", + "pymupdf>=1.23.0", # Better PDF processing + "textstat>=0.7.0", # Text readability metrics + "langdetect>=1.0.9", # Language detection + "python-magic>=0.4.27", # File type detection + "celery>=5.3.0", # Background task processing + "flower>=2.0.0", # Celery monitoring + "psutil>=5.9.0", # System and process utilities ] +[project.urls] +Homepage = "https://github.com/yourusername/ai-soul-entity" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build] +packages = ["app"] +include = [ + "app/**/*.py", + "app/**/*.ini", + "app/**/*.json", + "app/**/*.mjml", +] + +[tool.hatch.metadata] +allow-direct-references = true + [tool.uv] dev-dependencies = [ - "pytest<8.0.0,>=7.4.3", - "mypy<2.0.0,>=1.8.0", + "pytest>=7.4.0", + "httpx>=0.24.1", + "pytest-cov>=4.1.0", + "black>=23.7.0", + "isort>=5.12.0", + "flake8>=6.1.0", + "mypy>=1.4.1", "ruff<1.0.0,>=0.2.2", "pre-commit<4.0.0,>=3.6.2", "types-passlib<2.0.0.0,>=1.7.7.20240106", "coverage<8.0.0,>=7.4.3", ] -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - [tool.mypy] strict = true exclude = ["venv", ".venv", "alembic"] @@ -64,5 +115,16 @@ ignore = [ ] [tool.ruff.lint.pyupgrade] -# Preserve types, even if a file imports `from __future__ import annotations`. keep-runtime-typing = true + +[tool.rye] +managed = true +dev-dependencies = [ + "pytest>=7.4.0", + "httpx>=0.24.1", + "pytest-cov>=4.1.0", + "black>=23.7.0", + "isort>=5.12.0", + "flake8>=6.1.0", + "mypy>=1.4.1", +] diff --git a/backend/scripts/add_sample_ai_souls.py b/backend/scripts/add_sample_ai_souls.py new file mode 100644 index 0000000000..e112253abf --- /dev/null +++ b/backend/scripts/add_sample_ai_souls.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +""" +Script to add sample AI souls for testing +""" + +import logging + +from sqlmodel import Session, select + +from app.core.db import engine +from app.models import AISoulEntity, User + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +def create_sample_ai_souls(): + """Create sample AI souls for testing""" + + sample_souls = [ + { + "name": "Spiritual Guide", + "description": "A wise and compassionate spiritual guide to help with meditation, mindfulness, and personal growth.", + "persona_type": "spiritual", + "specializations": "meditation, mindfulness, personal growth, spirituality, wisdom traditions", + "base_prompt": "You are a wise and compassionate spiritual guide. You help people with meditation, mindfulness, and personal growth. You speak with gentle wisdom and offer practical guidance rooted in various spiritual traditions. You are patient, understanding, and always encourage self-reflection and inner peace.", + }, + { + "name": "Life Coach", + "description": "An energetic and motivational life coach focused on goal setting, motivation, and personal development.", + "persona_type": "coach", + "specializations": "goal setting, motivation, personal development, habit formation, productivity", + "base_prompt": "You are an energetic and motivational life coach. You help people set and achieve their goals, build positive habits, and unlock their potential. You are encouraging, practical, and always focus on actionable steps. You believe in people's ability to change and grow.", + }, + { + "name": "Emotional Support", + "description": "A caring and empathetic companion for emotional support, active listening, and stress management.", + "persona_type": "support", + "specializations": "emotional intelligence, active listening, empathy, stress management, mental wellness", + "base_prompt": "You are a caring and empathetic emotional support companion. You provide a safe space for people to express their feelings and thoughts. You listen actively, offer comfort, and help people process their emotions. You are non-judgmental, supportive, and always prioritize emotional well-being.", + }, + { + "name": "Wisdom Teacher", + "description": "A knowledgeable teacher sharing wisdom from philosophy, critical thinking, and life lessons.", + "persona_type": "teacher", + "specializations": "philosophy, wisdom traditions, critical thinking, life lessons, ethics", + "base_prompt": "You are a knowledgeable wisdom teacher. You share insights from philosophy, various wisdom traditions, and life experience. You encourage critical thinking, ethical reflection, and the pursuit of wisdom. You present ideas clearly and help people think deeply about important questions.", + }, + { + "name": "Mindfulness Mentor", + "description": "A peaceful mentor specializing in mindfulness practices, meditation techniques, and present-moment awareness.", + "persona_type": "mentor", + "specializations": "mindfulness, meditation, present-moment awareness, breathing techniques, stress reduction", + "base_prompt": "You are a peaceful mindfulness mentor. You guide people in developing mindfulness practices, meditation techniques, and present-moment awareness. You speak with calm presence and offer practical exercises for stress reduction and mental clarity. You emphasize the power of the present moment.", + }, + { + "name": "Creative Inspiration", + "description": "An inspiring creative companion for artistic expression, creative problem-solving, and innovation.", + "persona_type": "creative", + "specializations": "creativity, artistic expression, innovation, creative problem-solving, inspiration", + "base_prompt": "You are an inspiring creative companion. You help people unlock their creative potential, explore artistic expression, and approach problems with innovative thinking. You are imaginative, encouraging, and always ready to explore new possibilities. You believe creativity is a powerful force for personal transformation.", + }, + ] + + with Session(engine) as session: + # Get the first user to assign souls to (admin user) + stmt = select(User).where(User.email == "admin@example.com") + result = session.exec(stmt) + admin_user = result.first() + + if not admin_user: + logger.error("Admin user not found. Please run docker_reset_users.py first.") + return + + for soul_data in sample_souls: + # Check if soul already exists + stmt = select(AISoulEntity).where( + AISoulEntity.name == soul_data["name"], + AISoulEntity.user_id == admin_user.id + ) + result = session.exec(stmt) + existing_soul = result.first() + + if existing_soul: + logger.info(f"AI Soul '{soul_data['name']}' already exists, skipping...") + continue + + # Create new AI soul + soul = AISoulEntity( + name=soul_data["name"], + description=soul_data["description"], + persona_type=soul_data["persona_type"], + specializations=soul_data["specializations"], + base_prompt=soul_data["base_prompt"], + user_id=admin_user.id, + is_active=True, + ) + + session.add(soul) + logger.info(f"Created AI Soul: {soul_data['name']} ({soul_data['persona_type']})") + + session.commit() + logger.info("Sample AI souls created successfully!") + +def main(): + """Main function""" + logger.info("Creating sample AI souls...") + create_sample_ai_souls() + logger.info("Done!") + +if __name__ == "__main__": + main() diff --git a/backend/scripts/add_test_ai_souls.py b/backend/scripts/add_test_ai_souls.py new file mode 100755 index 0000000000..e499746433 --- /dev/null +++ b/backend/scripts/add_test_ai_souls.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +import sys +from pathlib import Path + +# Add the backend directory to the Python path +backend_dir = Path(__file__).parent.parent / "backend" +sys.path.append(str(backend_dir)) + +from sqlmodel import Session, create_engine, select + +from app.core.config import settings +from app.models import AISoulEntity, User + +# Create SQLModel engine +db_url = str(settings.SQLALCHEMY_DATABASE_URI) +engine = create_engine(db_url, echo=True) + +def create_test_ai_souls(db: Session, user_id: str): + """Create test AI souls for the given user.""" + test_souls = [ + { + "name": "Spiritual Guide", + "description": "A wise spiritual guide to help you on your journey of self-discovery and enlightenment.", + "persona_type": "guide", + "specializations": "spirituality, meditation, mindfulness, personal growth", + "base_prompt": "You are a wise spiritual guide with deep knowledge of various spiritual traditions, meditation practices, and personal growth techniques. Help users explore their spiritual path, find inner peace, and develop a deeper understanding of themselves.", + "is_active": True, + }, + { + "name": "Life Coach", + "description": "A supportive life coach to help you achieve your goals and overcome obstacles.", + "persona_type": "coach", + "specializations": "goal setting, motivation, personal development, habit formation", + "base_prompt": "You are a supportive life coach with expertise in goal setting, motivation, and personal development. Help users identify their goals, create action plans, and develop positive habits to achieve success.", + "is_active": True, + }, + { + "name": "Emotional Support", + "description": "An empathetic companion to help you process emotions and provide emotional support.", + "persona_type": "counselor", + "specializations": "emotional intelligence, active listening, empathy, stress management", + "base_prompt": "You are an empathetic counselor with expertise in emotional intelligence and stress management. Help users process their emotions, develop coping strategies, and build emotional resilience.", + "is_active": True, + }, + { + "name": "Wisdom Teacher", + "description": "A philosophical teacher sharing ancient wisdom and modern insights.", + "persona_type": "teacher", + "specializations": "philosophy, wisdom traditions, critical thinking, life lessons", + "base_prompt": "You are a wise teacher with deep knowledge of philosophical traditions and life wisdom. Help users explore profound questions, develop wisdom, and apply philosophical insights to their lives.", + "is_active": True, + }, + { + "name": "Creative Muse", + "description": "An inspiring muse to spark creativity and artistic expression.", + "persona_type": "muse", + "specializations": "creativity, artistic expression, inspiration, innovation", + "base_prompt": "You are a creative muse with the power to inspire artistic expression and innovative thinking. Help users unlock their creative potential, overcome creative blocks, and explore new forms of expression.", + "is_active": True, + } + ] + + for soul_data in test_souls: + # Check if soul already exists + statement = select(AISoulEntity).where( + AISoulEntity.user_id == user_id, + AISoulEntity.name == soul_data["name"] + ) + existing_soul = db.exec(statement).first() + + if not existing_soul: + soul = AISoulEntity(user_id=user_id, **soul_data) + db.add(soul) + print(f"Created AI soul: {soul.name}") + else: + print(f"AI soul already exists: {soul_data['name']}") + + db.commit() + +def main(): + """Main function to add test AI souls.""" + if len(sys.argv) != 2: + print("Usage: python add_test_ai_souls.py ") + sys.exit(1) + + user_email = sys.argv[1] + + with Session(engine) as db: + # Get user by email + statement = select(User).where(User.email == user_email) + user = db.exec(statement).first() + + if not user: + print(f"User not found: {user_email}") + sys.exit(1) + + create_test_ai_souls(db, user.id) + print("Test AI souls created successfully!") + +if __name__ == "__main__": + main() diff --git a/backend/scripts/create_test_counselor.py b/backend/scripts/create_test_counselor.py new file mode 100644 index 0000000000..ee3eda0e26 --- /dev/null +++ b/backend/scripts/create_test_counselor.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +""" +Script to create a test counselor user for testing the counselor system. +""" + +import uuid +from sqlmodel import Session, select +from app.core.db import engine +from app.core.security import get_password_hash +from app.models import User, Counselor, Organization + + +def create_test_counselor(): + """Create a test counselor user.""" + print("👩‍⚕️ Creating test counselor user...") + + with Session(engine) as session: + # Check if test counselor already exists + existing_user = session.exec( + select(User).where(User.email == "test.counselor@example.com") + ).first() + + if existing_user: + print("✅ Test counselor user already exists") + return + + # Get or create default organization + default_org = session.exec(select(Organization)).first() + if not default_org: + print("🏢 Creating default organization...") + default_org = Organization( + name="Test Organization", + description="Test organization for counselors", + is_active=True + ) + session.add(default_org) + session.commit() + session.refresh(default_org) + + # Create test counselor user + test_user = User( + email="test.counselor@example.com", + full_name="Test Counselor", + hashed_password=get_password_hash("testpassword123"), + role="counselor", + is_active=True, + organization_id=default_org.id + ) + session.add(test_user) + session.commit() + session.refresh(test_user) + + # Create counselor profile + counselor = Counselor( + user_id=test_user.id, + organization_id=default_org.id, + specializations="general counseling, crisis intervention, trauma therapy", + license_number="TEST-COUNSELOR-001", + license_type="Licensed Clinical Social Worker (LCSW)", + is_available=True, + max_concurrent_cases=15 + ) + session.add(counselor) + session.commit() + session.refresh(counselor) + + print("✅ Test counselor user created successfully!") + print(f" Email: {test_user.email}") + print(f" Password: testpassword123") + print(f" Role: {test_user.role}") + print(f" Counselor ID: {counselor.id}") + print(f" Organization: {default_org.name}") + + +if __name__ == "__main__": + create_test_counselor() \ No newline at end of file diff --git a/backend/scripts/docker_reset_users.py b/backend/scripts/docker_reset_users.py new file mode 100644 index 0000000000..253b51c336 --- /dev/null +++ b/backend/scripts/docker_reset_users.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python3 +""" +Script to reset users and create test data - designed to run inside Docker container. +""" + +import os +import sys +import json +from datetime import datetime, timedelta + +# Add the app directory to the path so we can import from it +sys.path.insert(0, '/app') + +from sqlmodel import Session, select, delete +from app.core.db import engine +from app.core.security import get_password_hash +from app.models import ( + User, Counselor, Organization, AISoulEntity, + ChatMessage, PendingResponse, RiskAssessment +) + + +def reset_and_create_test_data(): + """Reset database and create comprehensive test data.""" + print("🔄 Resetting database and creating test data...") + + try: + with Session(engine) as session: + # Delete all existing data in proper order + print("🗑️ Deleting existing data...") + + # Delete in proper order to avoid foreign key constraints + session.exec(delete(ChatMessage)) + session.exec(delete(PendingResponse)) + session.exec(delete(RiskAssessment)) + session.exec(delete(AISoulEntity)) + session.exec(delete(Counselor)) + session.exec(delete(User)) + session.commit() + print(" ✅ All existing data deleted") + + # Get or create default organization + default_org = session.exec(select(Organization)).first() + if not default_org: + print("🏢 Creating default organization...") + default_org = Organization( + name="Test Organization", + domain="test-org.example.com", + description="Default organization for testing", + is_active=True + ) + session.add(default_org) + session.commit() + session.refresh(default_org) + + # Create test users + print("👥 Creating test users...") + test_users = [ + { + "email": "admin@example.com", + "password": "TestPass123!", + "full_name": "System Administrator", + "role": "admin", + "is_superuser": True + }, + { + "email": "counselor@example.com", + "password": "TestPass123!", + "full_name": "Dr. Sarah Wilson", + "role": "counselor", + "is_superuser": False + }, + { + "email": "trainer@example.com", + "password": "TestPass123!", + "full_name": "AI Trainer Smith", + "role": "trainer", + "is_superuser": False + }, + { + "email": "user@example.com", + "password": "TestPass123!", + "full_name": "John Doe", + "role": "user", + "is_superuser": False + } + ] + + created_users = {} + + for user_data in test_users: + user = User( + email=user_data["email"], + full_name=user_data["full_name"], + hashed_password=get_password_hash(user_data["password"]), + role=user_data["role"], + is_superuser=user_data["is_superuser"], + is_active=True, + organization_id=default_org.id + ) + session.add(user) + session.commit() + session.refresh(user) + + created_users[user_data["role"]] = user + print(f" ✅ Created {user_data['role']}: {user_data['email']}") + + # Create counselor profile + counselor_user = created_users["counselor"] + counselor = Counselor( + user_id=counselor_user.id, + organization_id=default_org.id, + specializations="general counseling, crisis intervention, trauma therapy", + license_number="LCSW-12345", + license_type="Licensed Clinical Social Worker", + is_available=True, + max_concurrent_cases=15 + ) + session.add(counselor) + session.commit() + session.refresh(counselor) + print(f" ✅ Created counselor profile") + + # Create sample AI soul + trainer_user = created_users["trainer"] + ai_soul = AISoulEntity( + name="Therapy Assistant", + description="A compassionate AI assistant for mental health support", + personality="Empathetic, professional, and supportive", + background="Trained in cognitive behavioral therapy techniques", + persona_type="therapist", + specializations="cognitive behavioral therapy, crisis intervention, mental health support", + base_prompt="You are a compassionate AI therapist trained in cognitive behavioral therapy techniques. You provide empathetic, professional, and supportive responses to users seeking mental health support.", + user_id=trainer_user.id + ) + session.add(ai_soul) + session.commit() + session.refresh(ai_soul) + print(f" ✅ Created AI soul") + + # Create test chat messages and pending responses + print("💬 Creating test chat messages and pending responses...") + regular_user = created_users["user"] + + test_messages = [ + { + "content": "I've been feeling really overwhelmed lately and having trouble sleeping.", + "risk_level": "medium", + "ai_response": "I understand you're feeling overwhelmed and having sleep difficulties. These feelings are valid and it's important that you reached out. Can you tell me more about what's been contributing to these feelings of being overwhelmed?" + }, + { + "content": "I sometimes think about hurting myself when things get really bad.", + "risk_level": "high", + "ai_response": "I'm very concerned about what you've shared. These thoughts about self-harm are serious, and I want you to know that you're not alone. There are people who want to help you through this difficult time." + }, + { + "content": "I can't take this anymore. I have a plan and I'm going to end it all tonight.", + "risk_level": "critical", + "ai_response": "I'm extremely concerned about your safety right now. What you're feeling is temporary, but ending your life is permanent. Please reach out for immediate help - you deserve support and care." + } + ] + + for i, msg_data in enumerate(test_messages): + # Create user chat message + user_message = ChatMessage( + content=msg_data["content"], + user_id=regular_user.id, + ai_soul_id=ai_soul.id, + is_from_user=True, + timestamp=datetime.utcnow() - timedelta(hours=i+1) + ) + session.add(user_message) + session.commit() + session.refresh(user_message) + + # Create risk assessment + risk_categories = [] + if msg_data["risk_level"] == "medium": + risk_categories = ["mental_health_crisis", "sleep_disturbance"] + elif msg_data["risk_level"] == "high": + risk_categories = ["self_harm", "mental_health_crisis"] + elif msg_data["risk_level"] == "critical": + risk_categories = ["suicide", "self_harm", "mental_health_crisis"] + + risk_assessment = RiskAssessment( + chat_message_id=user_message.id, + user_id=regular_user.id, + ai_soul_id=ai_soul.id, + organization_id=default_org.id, + risk_level=msg_data["risk_level"], + risk_categories=json.dumps(risk_categories), + confidence_score=0.8 + (i * 0.1), + reasoning=f"Analysis indicates {msg_data['risk_level']} risk based on content and context", + requires_human_review=msg_data["risk_level"] in ["high", "critical"], + auto_response_blocked=msg_data["risk_level"] == "critical" + ) + session.add(risk_assessment) + session.commit() + session.refresh(risk_assessment) + + # Create pending response if human review is required + if risk_assessment.requires_human_review: + priority = "urgent" if msg_data["risk_level"] == "critical" else "high" + + pending_response = PendingResponse( + chat_message_id=str(user_message.id), + risk_assessment_id=str(risk_assessment.id), + user_id=regular_user.id, + ai_soul_id=ai_soul.id, + organization_id=default_org.id, + original_user_message=msg_data["content"], + ai_generated_response=msg_data["ai_response"], + priority=priority, + assigned_counselor_id=counselor.id, + response_time_limit=datetime.utcnow() + timedelta(hours=2), + status="pending" + ) + session.add(pending_response) + session.commit() + + print(f" ✅ Created {priority} priority pending response") + else: + # Create AI response message for low/medium risk + ai_message = ChatMessage( + content=msg_data["ai_response"], + user_id=regular_user.id, + ai_soul_id=ai_soul.id, + is_from_user=False, + timestamp=datetime.utcnow() - timedelta(hours=i+1) + timedelta(minutes=5) + ) + session.add(ai_message) + session.commit() + print(f" ✅ Created AI response for {msg_data['risk_level']} risk message") + + print("✅ Database reset and test data creation completed!") + print("\n📋 Summary:") + print("-" * 50) + print("Users created:") + print(" - admin@example.com (password: TestPass123!) - Admin") + print(" - counselor@example.com (password: TestPass123!) - Counselor") + print(" - trainer@example.com (password: TestPass123!) - Trainer") + print(" - user@example.com (password: TestPass123!) - User") + print("\nTest data:") + print(" - 1 AI Soul (Therapy Assistant)") + print(" - 3 Chat messages with different risk levels") + print(" - 2 Pending responses for counselor review") + print(" - Risk assessments for all messages") + print("-" * 50) + + except Exception as e: + print(f"❌ Error: {str(e)}") + import traceback + traceback.print_exc() + + +if __name__ == "__main__": + reset_and_create_test_data() \ No newline at end of file diff --git a/backend/scripts/prestart.sh b/backend/scripts/prestart.sh index 1b395d513f..fc92099c51 100644 --- a/backend/scripts/prestart.sh +++ b/backend/scripts/prestart.sh @@ -3,8 +3,20 @@ set -e set -x -# Let the DB start -python app/backend_pre_start.py +# Let the DB start and retry for up to 60 seconds +max_retries=30 +counter=0 +until python app/backend_pre_start.py || [ $counter -eq $max_retries ] +do + echo "Waiting for database to be ready... ($counter/$max_retries)" + sleep 2 + counter=$((counter+1)) +done + +if [ $counter -eq $max_retries ]; then + echo "Database connection failed after $max_retries retries" + exit 1 +fi # Run migrations alembic upgrade head diff --git a/backend/uv.lock b/backend/uv.lock index fdaaf98efe..8c8c0cb9ec 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -1,11 +1,26 @@ version = 1 -revision = 1 +revision = 2 requires-python = ">=3.10, <4.0" resolution-markers = [ - "python_full_version < '3.13'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", + "python_full_version < '3.11'", "python_full_version >= '3.13'", ] +[[package]] +name = "aioredis" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-timeout" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/cf/9eb144a0b05809ffc5d29045c4b51039000ea275bc1268d0351c9e7dfc06/aioredis-2.0.1.tar.gz", hash = "sha256:eaa51aaf993f2d71f54b70527c440437ba65340588afeb786cd87c55c89cd98e", size = 111047, upload_time = "2021-12-27T20:28:17.557Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/a9/0da089c3ae7a31cbcd2dcf0214f6f571e1295d292b6139e2bac68ec081d0/aioredis-2.0.1-py3-none-any.whl", hash = "sha256:9ac0d0b3b485d293b8ca1987e6de8658d7dafcca1cddfcd1d506cae8cdebfdd6", size = 71243, upload_time = "2021-12-27T20:28:16.36Z" }, +] + [[package]] name = "alembic" version = "1.15.2" @@ -15,18 +30,30 @@ dependencies = [ { name = "sqlalchemy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e6/57/e314c31b261d1e8a5a5f1908065b4ff98270a778ce7579bd4254477209a7/alembic-1.15.2.tar.gz", hash = "sha256:1c72391bbdeffccfe317eefba686cb9a3c078005478885413b95c3b26c57a8a7", size = 1925573 } +sdist = { url = "https://files.pythonhosted.org/packages/e6/57/e314c31b261d1e8a5a5f1908065b4ff98270a778ce7579bd4254477209a7/alembic-1.15.2.tar.gz", hash = "sha256:1c72391bbdeffccfe317eefba686cb9a3c078005478885413b95c3b26c57a8a7", size = 1925573, upload_time = "2025-03-28T13:52:00.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/18/d89a443ed1ab9bcda16264716f809c663866d4ca8de218aa78fd50b38ead/alembic-1.15.2-py3-none-any.whl", hash = "sha256:2e76bd916d547f6900ec4bb5a90aeac1485d2c92536923d0b138c02b126edc53", size = 231911, upload_time = "2025-03-28T13:52:02.218Z" }, +] + +[[package]] +name = "amqp" +version = "5.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "vine" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/79/fc/ec94a357dfc6683d8c86f8b4cfa5416a4c36b28052ec8260c77aca96a443/amqp-5.3.1.tar.gz", hash = "sha256:cddc00c725449522023bad949f70fff7b48f0b1ade74d170a6f10ab044739432", size = 129013, upload_time = "2024-11-12T19:55:44.051Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/18/d89a443ed1ab9bcda16264716f809c663866d4ca8de218aa78fd50b38ead/alembic-1.15.2-py3-none-any.whl", hash = "sha256:2e76bd916d547f6900ec4bb5a90aeac1485d2c92536923d0b138c02b126edc53", size = 231911 }, + { url = "https://files.pythonhosted.org/packages/26/99/fc813cd978842c26c82534010ea849eee9ab3a13ea2b74e95cb9c99e747b/amqp-5.3.1-py3-none-any.whl", hash = "sha256:43b3319e1b4e7d1251833a93d672b4af1e40f3d632d479b98661a95f117880a2", size = 50944, upload_time = "2024-11-12T19:55:41.782Z" }, ] [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload_time = "2024-05-20T21:33:25.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload_time = "2024-05-20T21:33:24.1Z" }, ] [[package]] @@ -39,9 +66,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/49/f3f17ec11c4a91fe79275c426658e509b07547f874b14c1a526d86a83fc8/anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb", size = 170983 } +sdist = { url = "https://files.pythonhosted.org/packages/78/49/f3f17ec11c4a91fe79275c426658e509b07547f874b14c1a526d86a83fc8/anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb", size = 170983, upload_time = "2024-09-21T10:33:28.479Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/ef/7a4f225581a0d7886ea28359179cb861d7fbcdefad29663fc1167b86f69f/anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a", size = 89631 }, + { url = "https://files.pythonhosted.org/packages/9e/ef/7a4f225581a0d7886ea28359179cb861d7fbcdefad29663fc1167b86f69f/anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a", size = 89631, upload_time = "2024-09-21T10:33:27.05Z" }, ] [[package]] @@ -49,926 +76,3023 @@ name = "app" version = "0.1.0" source = { editable = "." } dependencies = [ + { name = "aioredis" }, { name = "alembic" }, { name = "bcrypt" }, + { name = "beautifulsoup4" }, + { name = "celery" }, + { name = "chromadb" }, { name = "email-validator" }, { name = "emails" }, - { name = "fastapi", extra = ["standard"] }, + { name = "fastapi" }, + { name = "flower" }, { name = "httpx" }, { name = "jinja2" }, + { name = "langchain" }, + { name = "langchain-openai" }, + { name = "langdetect" }, + { name = "lxml" }, + { name = "markdown" }, + { name = "nltk" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "openai" }, + { name = "openpyxl" }, { name = "passlib", extra = ["bcrypt"] }, - { name = "psycopg", extra = ["binary"] }, - { name = "pydantic" }, + { name = "psutil" }, + { name = "psycopg" }, + { name = "pydantic", extra = ["email"] }, { name = "pydantic-settings" }, { name = "pyjwt" }, + { name = "pymupdf" }, + { name = "pypdf2" }, + { name = "python-docx" }, + { name = "python-jose", extra = ["cryptography"] }, + { name = "python-magic" }, { name = "python-multipart" }, + { name = "python-pptx" }, + { name = "qdrant-client" }, + { name = "redis" }, + { name = "scikit-learn" }, + { name = "sentence-transformers" }, { name = "sentry-sdk", extra = ["fastapi"] }, + { name = "spacy" }, { name = "sqlmodel" }, { name = "tenacity" }, + { name = "textstat" }, + { name = "tiktoken" }, + { name = "torch" }, + { name = "transformers" }, + { name = "uvicorn" }, ] [package.dev-dependencies] dev = [ + { name = "black" }, { name = "coverage" }, + { name = "flake8" }, + { name = "httpx" }, + { name = "isort" }, { name = "mypy" }, { name = "pre-commit" }, { name = "pytest" }, + { name = "pytest-cov" }, { name = "ruff" }, { name = "types-passlib" }, ] [package.metadata] requires-dist = [ - { name = "alembic", specifier = ">=1.12.1,<2.0.0" }, + { name = "aioredis", specifier = ">=2.0.0" }, + { name = "alembic", specifier = ">=1.11.1" }, { name = "bcrypt", specifier = "==4.3.0" }, + { name = "beautifulsoup4", specifier = ">=4.12.0" }, + { name = "celery", specifier = ">=5.3.0" }, + { name = "chromadb", specifier = ">=0.4.22" }, { name = "email-validator", specifier = ">=2.1.0.post1,<3.0.0.0" }, - { name = "emails", specifier = ">=0.6,<1.0" }, - { name = "fastapi", extras = ["standard"], specifier = ">=0.114.2,<1.0.0" }, - { name = "httpx", specifier = ">=0.25.1,<1.0.0" }, + { name = "emails", specifier = ">=0.6" }, + { name = "fastapi", specifier = ">=0.100.0" }, + { name = "flower", specifier = ">=2.0.0" }, + { name = "httpx", specifier = ">=0.24.1" }, { name = "jinja2", specifier = ">=3.1.4,<4.0.0" }, - { name = "passlib", extras = ["bcrypt"], specifier = ">=1.7.4,<2.0.0" }, - { name = "psycopg", extras = ["binary"], specifier = ">=3.1.13,<4.0.0" }, - { name = "pydantic", specifier = ">2.0" }, + { name = "langchain", specifier = ">=0.2.0,<1.0.0" }, + { name = "langchain-openai", specifier = ">=0.1.0,<1.0.0" }, + { name = "langdetect", specifier = ">=1.0.9" }, + { name = "lxml", specifier = ">=4.9.0" }, + { name = "markdown", specifier = ">=3.4.0" }, + { name = "nltk", specifier = ">=3.8.0" }, + { name = "numpy", specifier = ">=1.24.0" }, + { name = "openai", specifier = ">=1.0.0" }, + { name = "openpyxl", specifier = ">=3.1.0" }, + { name = "passlib", extras = ["bcrypt"], specifier = ">=1.7.4" }, + { name = "psutil", specifier = ">=5.9.0" }, + { name = "psycopg", specifier = ">=3.1.18" }, + { name = "pydantic", extras = ["email"], specifier = ">=2.0.0" }, { name = "pydantic-settings", specifier = ">=2.2.1,<3.0.0" }, { name = "pyjwt", specifier = ">=2.8.0,<3.0.0" }, - { name = "python-multipart", specifier = ">=0.0.7,<1.0.0" }, + { name = "pymupdf", specifier = ">=1.23.0" }, + { name = "pypdf2", specifier = ">=3.0.0" }, + { name = "python-docx", specifier = ">=0.8.11" }, + { name = "python-jose", extras = ["cryptography"], specifier = ">=3.3.0" }, + { name = "python-magic", specifier = ">=0.4.27" }, + { name = "python-multipart", specifier = ">=0.0.6" }, + { name = "python-pptx", specifier = ">=0.6.21" }, + { name = "qdrant-client", specifier = ">=1.7.0" }, + { name = "redis", specifier = ">=4.5.0" }, + { name = "scikit-learn", specifier = ">=1.3.0" }, + { name = "sentence-transformers", specifier = ">=2.2.2" }, { name = "sentry-sdk", extras = ["fastapi"], specifier = ">=1.40.6,<2.0.0" }, - { name = "sqlmodel", specifier = ">=0.0.21,<1.0.0" }, - { name = "tenacity", specifier = ">=8.2.3,<9.0.0" }, + { name = "spacy", specifier = ">=3.6.0" }, + { name = "sqlmodel", specifier = ">=0.0.8" }, + { name = "tenacity", specifier = ">=8.2.2" }, + { name = "textstat", specifier = ">=0.7.0" }, + { name = "tiktoken", specifier = ">=0.7.0,<1.0.0" }, + { name = "torch", specifier = ">=2.0.0" }, + { name = "transformers", specifier = ">=4.30.0" }, + { name = "uvicorn", specifier = ">=0.22.0" }, ] [package.metadata.requires-dev] dev = [ + { name = "black", specifier = ">=23.7.0" }, { name = "coverage", specifier = ">=7.4.3,<8.0.0" }, - { name = "mypy", specifier = ">=1.8.0,<2.0.0" }, + { name = "flake8", specifier = ">=6.1.0" }, + { name = "httpx", specifier = ">=0.24.1" }, + { name = "isort", specifier = ">=5.12.0" }, + { name = "mypy", specifier = ">=1.4.1" }, { name = "pre-commit", specifier = ">=3.6.2,<4.0.0" }, - { name = "pytest", specifier = ">=7.4.3,<8.0.0" }, + { name = "pytest", specifier = ">=7.4.0" }, + { name = "pytest-cov", specifier = ">=4.1.0" }, { name = "ruff", specifier = ">=0.2.2,<1.0.0" }, { name = "types-passlib", specifier = ">=1.7.7.20240106,<2.0.0.0" }, ] [[package]] -name = "bcrypt" -version = "4.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/5d/6d7433e0f3cd46ce0b43cd65e1db465ea024dbb8216fb2404e919c2ad77b/bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", size = 25697 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/2c/3d44e853d1fe969d229bd58d39ae6902b3d924af0e2b5a60d17d4b809ded/bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281", size = 483719 }, - { url = "https://files.pythonhosted.org/packages/a1/e2/58ff6e2a22eca2e2cff5370ae56dba29d70b1ea6fc08ee9115c3ae367795/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb", size = 272001 }, - { url = "https://files.pythonhosted.org/packages/37/1f/c55ed8dbe994b1d088309e366749633c9eb90d139af3c0a50c102ba68a1a/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180", size = 277451 }, - { url = "https://files.pythonhosted.org/packages/d7/1c/794feb2ecf22fe73dcfb697ea7057f632061faceb7dcf0f155f3443b4d79/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f", size = 272792 }, - { url = "https://files.pythonhosted.org/packages/13/b7/0b289506a3f3598c2ae2bdfa0ea66969812ed200264e3f61df77753eee6d/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09", size = 289752 }, - { url = "https://files.pythonhosted.org/packages/dc/24/d0fb023788afe9e83cc118895a9f6c57e1044e7e1672f045e46733421fe6/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d", size = 277762 }, - { url = "https://files.pythonhosted.org/packages/e4/38/cde58089492e55ac4ef6c49fea7027600c84fd23f7520c62118c03b4625e/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd", size = 272384 }, - { url = "https://files.pythonhosted.org/packages/de/6a/d5026520843490cfc8135d03012a413e4532a400e471e6188b01b2de853f/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af", size = 277329 }, - { url = "https://files.pythonhosted.org/packages/b3/a3/4fc5255e60486466c389e28c12579d2829b28a527360e9430b4041df4cf9/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231", size = 305241 }, - { url = "https://files.pythonhosted.org/packages/c7/15/2b37bc07d6ce27cc94e5b10fd5058900eb8fb11642300e932c8c82e25c4a/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c", size = 309617 }, - { url = "https://files.pythonhosted.org/packages/5f/1f/99f65edb09e6c935232ba0430c8c13bb98cb3194b6d636e61d93fe60ac59/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f", size = 335751 }, - { url = "https://files.pythonhosted.org/packages/00/1b/b324030c706711c99769988fcb694b3cb23f247ad39a7823a78e361bdbb8/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d", size = 355965 }, - { url = "https://files.pythonhosted.org/packages/aa/dd/20372a0579dd915dfc3b1cd4943b3bca431866fcb1dfdfd7518c3caddea6/bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4", size = 155316 }, - { url = "https://files.pythonhosted.org/packages/6d/52/45d969fcff6b5577c2bf17098dc36269b4c02197d551371c023130c0f890/bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669", size = 147752 }, - { url = "https://files.pythonhosted.org/packages/11/22/5ada0b9af72b60cbc4c9a399fdde4af0feaa609d27eb0adc61607997a3fa/bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d", size = 498019 }, - { url = "https://files.pythonhosted.org/packages/b8/8c/252a1edc598dc1ce57905be173328eda073083826955ee3c97c7ff5ba584/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", size = 279174 }, - { url = "https://files.pythonhosted.org/packages/29/5b/4547d5c49b85f0337c13929f2ccbe08b7283069eea3550a457914fc078aa/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", size = 283870 }, - { url = "https://files.pythonhosted.org/packages/be/21/7dbaf3fa1745cb63f776bb046e481fbababd7d344c5324eab47f5ca92dd2/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", size = 279601 }, - { url = "https://files.pythonhosted.org/packages/6d/64/e042fc8262e971347d9230d9abbe70d68b0a549acd8611c83cebd3eaec67/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", size = 297660 }, - { url = "https://files.pythonhosted.org/packages/50/b8/6294eb84a3fef3b67c69b4470fcdd5326676806bf2519cda79331ab3c3a9/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", size = 284083 }, - { url = "https://files.pythonhosted.org/packages/62/e6/baff635a4f2c42e8788fe1b1633911c38551ecca9a749d1052d296329da6/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", size = 279237 }, - { url = "https://files.pythonhosted.org/packages/39/48/46f623f1b0c7dc2e5de0b8af5e6f5ac4cc26408ac33f3d424e5ad8da4a90/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", size = 283737 }, - { url = "https://files.pythonhosted.org/packages/49/8b/70671c3ce9c0fca4a6cc3cc6ccbaa7e948875a2e62cbd146e04a4011899c/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", size = 312741 }, - { url = "https://files.pythonhosted.org/packages/27/fb/910d3a1caa2d249b6040a5caf9f9866c52114d51523ac2fb47578a27faee/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", size = 316472 }, - { url = "https://files.pythonhosted.org/packages/dc/cf/7cf3a05b66ce466cfb575dbbda39718d45a609daa78500f57fa9f36fa3c0/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", size = 343606 }, - { url = "https://files.pythonhosted.org/packages/e3/b8/e970ecc6d7e355c0d892b7f733480f4aa8509f99b33e71550242cf0b7e63/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", size = 362867 }, - { url = "https://files.pythonhosted.org/packages/a9/97/8d3118efd8354c555a3422d544163f40d9f236be5b96c714086463f11699/bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", size = 160589 }, - { url = "https://files.pythonhosted.org/packages/29/07/416f0b99f7f3997c69815365babbc2e8754181a4b1899d921b3c7d5b6f12/bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", size = 152794 }, - { url = "https://files.pythonhosted.org/packages/6e/c1/3fa0e9e4e0bfd3fd77eb8b52ec198fd6e1fd7e9402052e43f23483f956dd/bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", size = 498969 }, - { url = "https://files.pythonhosted.org/packages/ce/d4/755ce19b6743394787fbd7dff6bf271b27ee9b5912a97242e3caf125885b/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", size = 279158 }, - { url = "https://files.pythonhosted.org/packages/9b/5d/805ef1a749c965c46b28285dfb5cd272a7ed9fa971f970435a5133250182/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", size = 284285 }, - { url = "https://files.pythonhosted.org/packages/ab/2b/698580547a4a4988e415721b71eb45e80c879f0fb04a62da131f45987b96/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", size = 279583 }, - { url = "https://files.pythonhosted.org/packages/f2/87/62e1e426418204db520f955ffd06f1efd389feca893dad7095bf35612eec/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", size = 297896 }, - { url = "https://files.pythonhosted.org/packages/cb/c6/8fedca4c2ada1b6e889c52d2943b2f968d3427e5d65f595620ec4c06fa2f/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", size = 284492 }, - { url = "https://files.pythonhosted.org/packages/4d/4d/c43332dcaaddb7710a8ff5269fcccba97ed3c85987ddaa808db084267b9a/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", size = 279213 }, - { url = "https://files.pythonhosted.org/packages/dc/7f/1e36379e169a7df3a14a1c160a49b7b918600a6008de43ff20d479e6f4b5/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", size = 284162 }, - { url = "https://files.pythonhosted.org/packages/1c/0a/644b2731194b0d7646f3210dc4d80c7fee3ecb3a1f791a6e0ae6bb8684e3/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", size = 312856 }, - { url = "https://files.pythonhosted.org/packages/dc/62/2a871837c0bb6ab0c9a88bf54de0fc021a6a08832d4ea313ed92a669d437/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", size = 316726 }, - { url = "https://files.pythonhosted.org/packages/0c/a1/9898ea3faac0b156d457fd73a3cb9c2855c6fd063e44b8522925cdd8ce46/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", size = 343664 }, - { url = "https://files.pythonhosted.org/packages/40/f2/71b4ed65ce38982ecdda0ff20c3ad1b15e71949c78b2c053df53629ce940/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", size = 363128 }, - { url = "https://files.pythonhosted.org/packages/11/99/12f6a58eca6dea4be992d6c681b7ec9410a1d9f5cf368c61437e31daa879/bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", size = 160598 }, - { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799 }, - { url = "https://files.pythonhosted.org/packages/55/2d/0c7e5ab0524bf1a443e34cdd3926ec6f5879889b2f3c32b2f5074e99ed53/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c950d682f0952bafcceaf709761da0a32a942272fad381081b51096ffa46cea1", size = 275367 }, - { url = "https://files.pythonhosted.org/packages/10/4f/f77509f08bdff8806ecc4dc472b6e187c946c730565a7470db772d25df70/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:107d53b5c67e0bbc3f03ebf5b030e0403d24dda980f8e244795335ba7b4a027d", size = 280644 }, - { url = "https://files.pythonhosted.org/packages/35/18/7d9dc16a3a4d530d0a9b845160e9e5d8eb4f00483e05d44bb4116a1861da/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b693dbb82b3c27a1604a3dff5bfc5418a7e6a781bb795288141e5f80cf3a3492", size = 274881 }, - { url = "https://files.pythonhosted.org/packages/df/c4/ae6921088adf1e37f2a3a6a688e72e7d9e45fdd3ae5e0bc931870c1ebbda/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:b6354d3760fcd31994a14c89659dee887f1351a06e5dac3c1142307172a79f90", size = 280203 }, - { url = "https://files.pythonhosted.org/packages/4c/b1/1289e21d710496b88340369137cc4c5f6ee036401190ea116a7b4ae6d32a/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a839320bf27d474e52ef8cb16449bb2ce0ba03ca9f44daba6d93fa1d8828e48a", size = 275103 }, - { url = "https://files.pythonhosted.org/packages/94/41/19be9fe17e4ffc5d10b7b67f10e459fc4eee6ffe9056a88de511920cfd8d/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:bdc6a24e754a555d7316fa4774e64c6c3997d27ed2d1964d55920c7c227bc4ce", size = 280513 }, - { url = "https://files.pythonhosted.org/packages/aa/73/05687a9ef89edebdd8ad7474c16d8af685eb4591c3c38300bb6aad4f0076/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:55a935b8e9a1d2def0626c4269db3fcd26728cbff1e84f0341465c31c4ee56d8", size = 274685 }, - { url = "https://files.pythonhosted.org/packages/63/13/47bba97924ebe86a62ef83dc75b7c8a881d53c535f83e2c54c4bd701e05c/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:57967b7a28d855313a963aaea51bf6df89f833db4320da458e5b3c5ab6d4c938", size = 280110 }, -] - -[[package]] -name = "cachetools" -version = "5.5.0" +name = "async-timeout" +version = "4.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/38/a0f315319737ecf45b4319a8cd1f3a908e29d9277b46942263292115eee7/cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a", size = 27661 } +sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345, upload_time = "2023-08-10T16:35:56.907Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/07/14f8ad37f2d12a5ce41206c21820d8cb6561b728e51fad4530dff0552a67/cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292", size = 9524 }, + { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721, upload_time = "2023-08-10T16:35:55.203Z" }, ] [[package]] -name = "certifi" -version = "2024.8.30" +name = "attrs" +version = "25.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload_time = "2025-03-13T11:10:22.779Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload_time = "2025-03-13T11:10:21.14Z" }, ] [[package]] -name = "cfgv" -version = "3.4.0" +name = "backoff" +version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +sdist = { url = "https://files.pythonhosted.org/packages/47/d7/5bbeb12c44d7c4f2fb5b56abce497eb5ed9f34d85701de869acedd602619/backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", size = 17001, upload_time = "2022-10-05T19:19:32.061Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, + { url = "https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148, upload_time = "2022-10-05T19:19:30.546Z" }, ] [[package]] -name = "chardet" -version = "5.2.0" +name = "bcrypt" +version = "4.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/f7b6ab21ec75897ed80c17d79b15951a719226b9fababf1e40ea74d69079/chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", size = 2069618 } +sdist = { url = "https://files.pythonhosted.org/packages/bb/5d/6d7433e0f3cd46ce0b43cd65e1db465ea024dbb8216fb2404e919c2ad77b/bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", size = 25697, upload_time = "2025-02-28T01:24:09.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970", size = 199385 }, -] - -[[package]] -name = "charset-normalizer" -version = "3.3.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", size = 194219 }, - { url = "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", size = 122521 }, - { url = "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", size = 120383 }, - { url = "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", size = 138223 }, - { url = "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", size = 148101 }, - { url = "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", size = 140699 }, - { url = "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", size = 142065 }, - { url = "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", size = 144505 }, - { url = "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", size = 139425 }, - { url = "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", size = 145287 }, - { url = "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", size = 149929 }, - { url = "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", size = 141605 }, - { url = "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", size = 142646 }, - { url = "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", size = 92846 }, - { url = "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", size = 100343 }, - { url = "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", size = 191647 }, - { url = "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", size = 121434 }, - { url = "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", size = 118979 }, - { url = "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", size = 136582 }, - { url = "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", size = 146645 }, - { url = "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", size = 139398 }, - { url = "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", size = 140273 }, - { url = "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", size = 142577 }, - { url = "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", size = 137747 }, - { url = "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", size = 143375 }, - { url = "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", size = 148474 }, - { url = "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", size = 140232 }, - { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859 }, - { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509 }, - { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870 }, - { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892 }, - { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213 }, - { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404 }, - { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275 }, - { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518 }, - { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182 }, - { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869 }, - { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042 }, - { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275 }, - { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819 }, - { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415 }, - { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212 }, - { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167 }, - { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041 }, - { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397 }, - { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543 }, + { url = "https://files.pythonhosted.org/packages/bf/2c/3d44e853d1fe969d229bd58d39ae6902b3d924af0e2b5a60d17d4b809ded/bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281", size = 483719, upload_time = "2025-02-28T01:22:34.539Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e2/58ff6e2a22eca2e2cff5370ae56dba29d70b1ea6fc08ee9115c3ae367795/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb", size = 272001, upload_time = "2025-02-28T01:22:38.078Z" }, + { url = "https://files.pythonhosted.org/packages/37/1f/c55ed8dbe994b1d088309e366749633c9eb90d139af3c0a50c102ba68a1a/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180", size = 277451, upload_time = "2025-02-28T01:22:40.787Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1c/794feb2ecf22fe73dcfb697ea7057f632061faceb7dcf0f155f3443b4d79/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f", size = 272792, upload_time = "2025-02-28T01:22:43.144Z" }, + { url = "https://files.pythonhosted.org/packages/13/b7/0b289506a3f3598c2ae2bdfa0ea66969812ed200264e3f61df77753eee6d/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09", size = 289752, upload_time = "2025-02-28T01:22:45.56Z" }, + { url = "https://files.pythonhosted.org/packages/dc/24/d0fb023788afe9e83cc118895a9f6c57e1044e7e1672f045e46733421fe6/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d", size = 277762, upload_time = "2025-02-28T01:22:47.023Z" }, + { url = "https://files.pythonhosted.org/packages/e4/38/cde58089492e55ac4ef6c49fea7027600c84fd23f7520c62118c03b4625e/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd", size = 272384, upload_time = "2025-02-28T01:22:49.221Z" }, + { url = "https://files.pythonhosted.org/packages/de/6a/d5026520843490cfc8135d03012a413e4532a400e471e6188b01b2de853f/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af", size = 277329, upload_time = "2025-02-28T01:22:51.603Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a3/4fc5255e60486466c389e28c12579d2829b28a527360e9430b4041df4cf9/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231", size = 305241, upload_time = "2025-02-28T01:22:53.283Z" }, + { url = "https://files.pythonhosted.org/packages/c7/15/2b37bc07d6ce27cc94e5b10fd5058900eb8fb11642300e932c8c82e25c4a/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c", size = 309617, upload_time = "2025-02-28T01:22:55.461Z" }, + { url = "https://files.pythonhosted.org/packages/5f/1f/99f65edb09e6c935232ba0430c8c13bb98cb3194b6d636e61d93fe60ac59/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f", size = 335751, upload_time = "2025-02-28T01:22:57.81Z" }, + { url = "https://files.pythonhosted.org/packages/00/1b/b324030c706711c99769988fcb694b3cb23f247ad39a7823a78e361bdbb8/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d", size = 355965, upload_time = "2025-02-28T01:22:59.181Z" }, + { url = "https://files.pythonhosted.org/packages/aa/dd/20372a0579dd915dfc3b1cd4943b3bca431866fcb1dfdfd7518c3caddea6/bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4", size = 155316, upload_time = "2025-02-28T01:23:00.763Z" }, + { url = "https://files.pythonhosted.org/packages/6d/52/45d969fcff6b5577c2bf17098dc36269b4c02197d551371c023130c0f890/bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669", size = 147752, upload_time = "2025-02-28T01:23:02.908Z" }, + { url = "https://files.pythonhosted.org/packages/11/22/5ada0b9af72b60cbc4c9a399fdde4af0feaa609d27eb0adc61607997a3fa/bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d", size = 498019, upload_time = "2025-02-28T01:23:05.838Z" }, + { url = "https://files.pythonhosted.org/packages/b8/8c/252a1edc598dc1ce57905be173328eda073083826955ee3c97c7ff5ba584/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", size = 279174, upload_time = "2025-02-28T01:23:07.274Z" }, + { url = "https://files.pythonhosted.org/packages/29/5b/4547d5c49b85f0337c13929f2ccbe08b7283069eea3550a457914fc078aa/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", size = 283870, upload_time = "2025-02-28T01:23:09.151Z" }, + { url = "https://files.pythonhosted.org/packages/be/21/7dbaf3fa1745cb63f776bb046e481fbababd7d344c5324eab47f5ca92dd2/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", size = 279601, upload_time = "2025-02-28T01:23:11.461Z" }, + { url = "https://files.pythonhosted.org/packages/6d/64/e042fc8262e971347d9230d9abbe70d68b0a549acd8611c83cebd3eaec67/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", size = 297660, upload_time = "2025-02-28T01:23:12.989Z" }, + { url = "https://files.pythonhosted.org/packages/50/b8/6294eb84a3fef3b67c69b4470fcdd5326676806bf2519cda79331ab3c3a9/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", size = 284083, upload_time = "2025-02-28T01:23:14.5Z" }, + { url = "https://files.pythonhosted.org/packages/62/e6/baff635a4f2c42e8788fe1b1633911c38551ecca9a749d1052d296329da6/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", size = 279237, upload_time = "2025-02-28T01:23:16.686Z" }, + { url = "https://files.pythonhosted.org/packages/39/48/46f623f1b0c7dc2e5de0b8af5e6f5ac4cc26408ac33f3d424e5ad8da4a90/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", size = 283737, upload_time = "2025-02-28T01:23:18.897Z" }, + { url = "https://files.pythonhosted.org/packages/49/8b/70671c3ce9c0fca4a6cc3cc6ccbaa7e948875a2e62cbd146e04a4011899c/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", size = 312741, upload_time = "2025-02-28T01:23:21.041Z" }, + { url = "https://files.pythonhosted.org/packages/27/fb/910d3a1caa2d249b6040a5caf9f9866c52114d51523ac2fb47578a27faee/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", size = 316472, upload_time = "2025-02-28T01:23:23.183Z" }, + { url = "https://files.pythonhosted.org/packages/dc/cf/7cf3a05b66ce466cfb575dbbda39718d45a609daa78500f57fa9f36fa3c0/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", size = 343606, upload_time = "2025-02-28T01:23:25.361Z" }, + { url = "https://files.pythonhosted.org/packages/e3/b8/e970ecc6d7e355c0d892b7f733480f4aa8509f99b33e71550242cf0b7e63/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", size = 362867, upload_time = "2025-02-28T01:23:26.875Z" }, + { url = "https://files.pythonhosted.org/packages/a9/97/8d3118efd8354c555a3422d544163f40d9f236be5b96c714086463f11699/bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", size = 160589, upload_time = "2025-02-28T01:23:28.381Z" }, + { url = "https://files.pythonhosted.org/packages/29/07/416f0b99f7f3997c69815365babbc2e8754181a4b1899d921b3c7d5b6f12/bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", size = 152794, upload_time = "2025-02-28T01:23:30.187Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c1/3fa0e9e4e0bfd3fd77eb8b52ec198fd6e1fd7e9402052e43f23483f956dd/bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", size = 498969, upload_time = "2025-02-28T01:23:31.945Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d4/755ce19b6743394787fbd7dff6bf271b27ee9b5912a97242e3caf125885b/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", size = 279158, upload_time = "2025-02-28T01:23:34.161Z" }, + { url = "https://files.pythonhosted.org/packages/9b/5d/805ef1a749c965c46b28285dfb5cd272a7ed9fa971f970435a5133250182/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", size = 284285, upload_time = "2025-02-28T01:23:35.765Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2b/698580547a4a4988e415721b71eb45e80c879f0fb04a62da131f45987b96/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", size = 279583, upload_time = "2025-02-28T01:23:38.021Z" }, + { url = "https://files.pythonhosted.org/packages/f2/87/62e1e426418204db520f955ffd06f1efd389feca893dad7095bf35612eec/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", size = 297896, upload_time = "2025-02-28T01:23:39.575Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c6/8fedca4c2ada1b6e889c52d2943b2f968d3427e5d65f595620ec4c06fa2f/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", size = 284492, upload_time = "2025-02-28T01:23:40.901Z" }, + { url = "https://files.pythonhosted.org/packages/4d/4d/c43332dcaaddb7710a8ff5269fcccba97ed3c85987ddaa808db084267b9a/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", size = 279213, upload_time = "2025-02-28T01:23:42.653Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/1e36379e169a7df3a14a1c160a49b7b918600a6008de43ff20d479e6f4b5/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", size = 284162, upload_time = "2025-02-28T01:23:43.964Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0a/644b2731194b0d7646f3210dc4d80c7fee3ecb3a1f791a6e0ae6bb8684e3/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", size = 312856, upload_time = "2025-02-28T01:23:46.011Z" }, + { url = "https://files.pythonhosted.org/packages/dc/62/2a871837c0bb6ab0c9a88bf54de0fc021a6a08832d4ea313ed92a669d437/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", size = 316726, upload_time = "2025-02-28T01:23:47.575Z" }, + { url = "https://files.pythonhosted.org/packages/0c/a1/9898ea3faac0b156d457fd73a3cb9c2855c6fd063e44b8522925cdd8ce46/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", size = 343664, upload_time = "2025-02-28T01:23:49.059Z" }, + { url = "https://files.pythonhosted.org/packages/40/f2/71b4ed65ce38982ecdda0ff20c3ad1b15e71949c78b2c053df53629ce940/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", size = 363128, upload_time = "2025-02-28T01:23:50.399Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/12f6a58eca6dea4be992d6c681b7ec9410a1d9f5cf368c61437e31daa879/bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", size = 160598, upload_time = "2025-02-28T01:23:51.775Z" }, + { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799, upload_time = "2025-02-28T01:23:53.139Z" }, + { url = "https://files.pythonhosted.org/packages/55/2d/0c7e5ab0524bf1a443e34cdd3926ec6f5879889b2f3c32b2f5074e99ed53/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c950d682f0952bafcceaf709761da0a32a942272fad381081b51096ffa46cea1", size = 275367, upload_time = "2025-02-28T01:23:54.578Z" }, + { url = "https://files.pythonhosted.org/packages/10/4f/f77509f08bdff8806ecc4dc472b6e187c946c730565a7470db772d25df70/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:107d53b5c67e0bbc3f03ebf5b030e0403d24dda980f8e244795335ba7b4a027d", size = 280644, upload_time = "2025-02-28T01:23:56.547Z" }, + { url = "https://files.pythonhosted.org/packages/35/18/7d9dc16a3a4d530d0a9b845160e9e5d8eb4f00483e05d44bb4116a1861da/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b693dbb82b3c27a1604a3dff5bfc5418a7e6a781bb795288141e5f80cf3a3492", size = 274881, upload_time = "2025-02-28T01:23:57.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/c4/ae6921088adf1e37f2a3a6a688e72e7d9e45fdd3ae5e0bc931870c1ebbda/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:b6354d3760fcd31994a14c89659dee887f1351a06e5dac3c1142307172a79f90", size = 280203, upload_time = "2025-02-28T01:23:59.331Z" }, + { url = "https://files.pythonhosted.org/packages/4c/b1/1289e21d710496b88340369137cc4c5f6ee036401190ea116a7b4ae6d32a/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a839320bf27d474e52ef8cb16449bb2ce0ba03ca9f44daba6d93fa1d8828e48a", size = 275103, upload_time = "2025-02-28T01:24:00.764Z" }, + { url = "https://files.pythonhosted.org/packages/94/41/19be9fe17e4ffc5d10b7b67f10e459fc4eee6ffe9056a88de511920cfd8d/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:bdc6a24e754a555d7316fa4774e64c6c3997d27ed2d1964d55920c7c227bc4ce", size = 280513, upload_time = "2025-02-28T01:24:02.243Z" }, + { url = "https://files.pythonhosted.org/packages/aa/73/05687a9ef89edebdd8ad7474c16d8af685eb4591c3c38300bb6aad4f0076/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:55a935b8e9a1d2def0626c4269db3fcd26728cbff1e84f0341465c31c4ee56d8", size = 274685, upload_time = "2025-02-28T01:24:04.512Z" }, + { url = "https://files.pythonhosted.org/packages/63/13/47bba97924ebe86a62ef83dc75b7c8a881d53c535f83e2c54c4bd701e05c/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:57967b7a28d855313a963aaea51bf6df89f833db4320da458e5b3c5ab6d4c938", size = 280110, upload_time = "2025-02-28T01:24:05.896Z" }, ] [[package]] -name = "click" -version = "8.1.7" +name = "beautifulsoup4" +version = "4.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "soupsieve" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload_time = "2025-04-15T17:05:13.836Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, + { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload_time = "2025-04-15T17:05:12.221Z" }, ] [[package]] -name = "colorama" -version = "0.4.6" +name = "billiard" +version = "4.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/7c/58/1546c970afcd2a2428b1bfafecf2371d8951cc34b46701bea73f4280989e/billiard-4.2.1.tar.gz", hash = "sha256:12b641b0c539073fc8d3f5b8b7be998956665c4233c7c1fcd66a7e677c4fb36f", size = 155031, upload_time = "2024-09-21T13:40:22.491Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/30/da/43b15f28fe5f9e027b41c539abc5469052e9d48fd75f8ff094ba2a0ae767/billiard-4.2.1-py3-none-any.whl", hash = "sha256:40b59a4ac8806ba2c2369ea98d876bc6108b051c227baffd928c644d15d8f3cb", size = 86766, upload_time = "2024-09-21T13:40:20.188Z" }, ] [[package]] -name = "coverage" -version = "7.6.1" +name = "black" +version = "25.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f7/08/7e37f82e4d1aead42a7443ff06a1e406aabf7302c4f00a546e4b320b994c/coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", size = 798791 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/61/eb7ce5ed62bacf21beca4937a90fe32545c91a3c8a42a30c6616d48fc70d/coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", size = 206690 }, - { url = "https://files.pythonhosted.org/packages/7d/73/041928e434442bd3afde5584bdc3f932fb4562b1597629f537387cec6f3d/coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", size = 207127 }, - { url = "https://files.pythonhosted.org/packages/c7/c8/6ca52b5147828e45ad0242388477fdb90df2c6cbb9a441701a12b3c71bc8/coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", size = 235654 }, - { url = "https://files.pythonhosted.org/packages/d5/da/9ac2b62557f4340270942011d6efeab9833648380109e897d48ab7c1035d/coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc", size = 233598 }, - { url = "https://files.pythonhosted.org/packages/53/23/9e2c114d0178abc42b6d8d5281f651a8e6519abfa0ef460a00a91f80879d/coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", size = 234732 }, - { url = "https://files.pythonhosted.org/packages/0f/7e/a0230756fb133343a52716e8b855045f13342b70e48e8ad41d8a0d60ab98/coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", size = 233816 }, - { url = "https://files.pythonhosted.org/packages/28/7c/3753c8b40d232b1e5eeaed798c875537cf3cb183fb5041017c1fdb7ec14e/coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", size = 232325 }, - { url = "https://files.pythonhosted.org/packages/57/e3/818a2b2af5b7573b4b82cf3e9f137ab158c90ea750a8f053716a32f20f06/coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", size = 233418 }, - { url = "https://files.pythonhosted.org/packages/c8/fb/4532b0b0cefb3f06d201648715e03b0feb822907edab3935112b61b885e2/coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", size = 209343 }, - { url = "https://files.pythonhosted.org/packages/5a/25/af337cc7421eca1c187cc9c315f0a755d48e755d2853715bfe8c418a45fa/coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", size = 210136 }, - { url = "https://files.pythonhosted.org/packages/ad/5f/67af7d60d7e8ce61a4e2ddcd1bd5fb787180c8d0ae0fbd073f903b3dd95d/coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", size = 206796 }, - { url = "https://files.pythonhosted.org/packages/e1/0e/e52332389e057daa2e03be1fbfef25bb4d626b37d12ed42ae6281d0a274c/coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", size = 207244 }, - { url = "https://files.pythonhosted.org/packages/aa/cd/766b45fb6e090f20f8927d9c7cb34237d41c73a939358bc881883fd3a40d/coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", size = 239279 }, - { url = "https://files.pythonhosted.org/packages/70/6c/a9ccd6fe50ddaf13442a1e2dd519ca805cbe0f1fcd377fba6d8339b98ccb/coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", size = 236859 }, - { url = "https://files.pythonhosted.org/packages/14/6f/8351b465febb4dbc1ca9929505202db909c5a635c6fdf33e089bbc3d7d85/coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", size = 238549 }, - { url = "https://files.pythonhosted.org/packages/68/3c/289b81fa18ad72138e6d78c4c11a82b5378a312c0e467e2f6b495c260907/coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", size = 237477 }, - { url = "https://files.pythonhosted.org/packages/ed/1c/aa1efa6459d822bd72c4abc0b9418cf268de3f60eeccd65dc4988553bd8d/coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", size = 236134 }, - { url = "https://files.pythonhosted.org/packages/fb/c8/521c698f2d2796565fe9c789c2ee1ccdae610b3aa20b9b2ef980cc253640/coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", size = 236910 }, - { url = "https://files.pythonhosted.org/packages/7d/30/033e663399ff17dca90d793ee8a2ea2890e7fdf085da58d82468b4220bf7/coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", size = 209348 }, - { url = "https://files.pythonhosted.org/packages/20/05/0d1ccbb52727ccdadaa3ff37e4d2dc1cd4d47f0c3df9eb58d9ec8508ca88/coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", size = 210230 }, - { url = "https://files.pythonhosted.org/packages/7e/d4/300fc921dff243cd518c7db3a4c614b7e4b2431b0d1145c1e274fd99bd70/coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", size = 206983 }, - { url = "https://files.pythonhosted.org/packages/e1/ab/6bf00de5327ecb8db205f9ae596885417a31535eeda6e7b99463108782e1/coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", size = 207221 }, - { url = "https://files.pythonhosted.org/packages/92/8f/2ead05e735022d1a7f3a0a683ac7f737de14850395a826192f0288703472/coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", size = 240342 }, - { url = "https://files.pythonhosted.org/packages/0f/ef/94043e478201ffa85b8ae2d2c79b4081e5a1b73438aafafccf3e9bafb6b5/coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", size = 237371 }, - { url = "https://files.pythonhosted.org/packages/1f/0f/c890339dd605f3ebc269543247bdd43b703cce6825b5ed42ff5f2d6122c7/coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", size = 239455 }, - { url = "https://files.pythonhosted.org/packages/d1/04/7fd7b39ec7372a04efb0f70c70e35857a99b6a9188b5205efb4c77d6a57a/coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", size = 238924 }, - { url = "https://files.pythonhosted.org/packages/ed/bf/73ce346a9d32a09cf369f14d2a06651329c984e106f5992c89579d25b27e/coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", size = 237252 }, - { url = "https://files.pythonhosted.org/packages/86/74/1dc7a20969725e917b1e07fe71a955eb34bc606b938316bcc799f228374b/coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", size = 238897 }, - { url = "https://files.pythonhosted.org/packages/b6/e9/d9cc3deceb361c491b81005c668578b0dfa51eed02cd081620e9a62f24ec/coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", size = 209606 }, - { url = "https://files.pythonhosted.org/packages/47/c8/5a2e41922ea6740f77d555c4d47544acd7dc3f251fe14199c09c0f5958d3/coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", size = 210373 }, - { url = "https://files.pythonhosted.org/packages/8c/f9/9aa4dfb751cb01c949c990d136a0f92027fbcc5781c6e921df1cb1563f20/coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", size = 207007 }, - { url = "https://files.pythonhosted.org/packages/b9/67/e1413d5a8591622a46dd04ff80873b04c849268831ed5c304c16433e7e30/coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", size = 207269 }, - { url = "https://files.pythonhosted.org/packages/14/5b/9dec847b305e44a5634d0fb8498d135ab1d88330482b74065fcec0622224/coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", size = 239886 }, - { url = "https://files.pythonhosted.org/packages/7b/b7/35760a67c168e29f454928f51f970342d23cf75a2bb0323e0f07334c85f3/coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", size = 237037 }, - { url = "https://files.pythonhosted.org/packages/f7/95/d2fd31f1d638df806cae59d7daea5abf2b15b5234016a5ebb502c2f3f7ee/coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", size = 239038 }, - { url = "https://files.pythonhosted.org/packages/6e/bd/110689ff5752b67924efd5e2aedf5190cbbe245fc81b8dec1abaffba619d/coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", size = 238690 }, - { url = "https://files.pythonhosted.org/packages/d3/a8/08d7b38e6ff8df52331c83130d0ab92d9c9a8b5462f9e99c9f051a4ae206/coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", size = 236765 }, - { url = "https://files.pythonhosted.org/packages/d6/6a/9cf96839d3147d55ae713eb2d877f4d777e7dc5ba2bce227167d0118dfe8/coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", size = 238611 }, - { url = "https://files.pythonhosted.org/packages/74/e4/7ff20d6a0b59eeaab40b3140a71e38cf52547ba21dbcf1d79c5a32bba61b/coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", size = 209671 }, - { url = "https://files.pythonhosted.org/packages/35/59/1812f08a85b57c9fdb6d0b383d779e47b6f643bc278ed682859512517e83/coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", size = 210368 }, - { url = "https://files.pythonhosted.org/packages/9c/15/08913be1c59d7562a3e39fce20661a98c0a3f59d5754312899acc6cb8a2d/coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", size = 207758 }, - { url = "https://files.pythonhosted.org/packages/c4/ae/b5d58dff26cade02ada6ca612a76447acd69dccdbb3a478e9e088eb3d4b9/coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", size = 208035 }, - { url = "https://files.pythonhosted.org/packages/b8/d7/62095e355ec0613b08dfb19206ce3033a0eedb6f4a67af5ed267a8800642/coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", size = 250839 }, - { url = "https://files.pythonhosted.org/packages/7c/1e/c2967cb7991b112ba3766df0d9c21de46b476d103e32bb401b1b2adf3380/coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", size = 246569 }, - { url = "https://files.pythonhosted.org/packages/8b/61/a7a6a55dd266007ed3b1df7a3386a0d760d014542d72f7c2c6938483b7bd/coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", size = 248927 }, - { url = "https://files.pythonhosted.org/packages/c8/fa/13a6f56d72b429f56ef612eb3bc5ce1b75b7ee12864b3bd12526ab794847/coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", size = 248401 }, - { url = "https://files.pythonhosted.org/packages/75/06/0429c652aa0fb761fc60e8c6b291338c9173c6aa0f4e40e1902345b42830/coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", size = 246301 }, - { url = "https://files.pythonhosted.org/packages/52/76/1766bb8b803a88f93c3a2d07e30ffa359467810e5cbc68e375ebe6906efb/coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", size = 247598 }, - { url = "https://files.pythonhosted.org/packages/66/8b/f54f8db2ae17188be9566e8166ac6df105c1c611e25da755738025708d54/coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", size = 210307 }, - { url = "https://files.pythonhosted.org/packages/9f/b0/e0dca6da9170aefc07515cce067b97178cefafb512d00a87a1c717d2efd5/coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", size = 211453 }, - { url = "https://files.pythonhosted.org/packages/a5/2b/0354ed096bca64dc8e32a7cbcae28b34cb5ad0b1fe2125d6d99583313ac0/coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", size = 198926 }, +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] - -[[package]] -name = "cssselect" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d1/91/d51202cc41fbfca7fa332f43a5adac4b253962588c7cc5a54824b019081c/cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc", size = 41423 } +sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload_time = "2025-01-29T04:15:40.373Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/a9/2da08717a6862c48f1d61ef957a7bba171e7eefa6c0aa0ceb96a140c2a6b/cssselect-1.2.0-py2.py3-none-any.whl", hash = "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e", size = 18687 }, + { url = "https://files.pythonhosted.org/packages/4d/3b/4ba3f93ac8d90410423fdd31d7541ada9bcee1df32fb90d26de41ed40e1d/black-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759e7ec1e050a15f89b770cefbf91ebee8917aac5c20483bc2d80a6c3a04df32", size = 1629419, upload_time = "2025-01-29T05:37:06.642Z" }, + { url = "https://files.pythonhosted.org/packages/b4/02/0bde0485146a8a5e694daed47561785e8b77a0466ccc1f3e485d5ef2925e/black-25.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e519ecf93120f34243e6b0054db49c00a35f84f195d5bce7e9f5cfc578fc2da", size = 1461080, upload_time = "2025-01-29T05:37:09.321Z" }, + { url = "https://files.pythonhosted.org/packages/52/0e/abdf75183c830eaca7589144ff96d49bce73d7ec6ad12ef62185cc0f79a2/black-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:055e59b198df7ac0b7efca5ad7ff2516bca343276c466be72eb04a3bcc1f82d7", size = 1766886, upload_time = "2025-01-29T04:18:24.432Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a6/97d8bb65b1d8a41f8a6736222ba0a334db7b7b77b8023ab4568288f23973/black-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:db8ea9917d6f8fc62abd90d944920d95e73c83a5ee3383493e35d271aca872e9", size = 1419404, upload_time = "2025-01-29T04:19:04.296Z" }, + { url = "https://files.pythonhosted.org/packages/7e/4f/87f596aca05c3ce5b94b8663dbfe242a12843caaa82dd3f85f1ffdc3f177/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0", size = 1614372, upload_time = "2025-01-29T05:37:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/e7/d0/2c34c36190b741c59c901e56ab7f6e54dad8df05a6272a9747ecef7c6036/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299", size = 1442865, upload_time = "2025-01-29T05:37:14.309Z" }, + { url = "https://files.pythonhosted.org/packages/21/d4/7518c72262468430ead45cf22bd86c883a6448b9eb43672765d69a8f1248/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096", size = 1749699, upload_time = "2025-01-29T04:18:17.688Z" }, + { url = "https://files.pythonhosted.org/packages/58/db/4f5beb989b547f79096e035c4981ceb36ac2b552d0ac5f2620e941501c99/black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2", size = 1428028, upload_time = "2025-01-29T04:18:51.711Z" }, + { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988, upload_time = "2025-01-29T05:37:16.707Z" }, + { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985, upload_time = "2025-01-29T05:37:18.273Z" }, + { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816, upload_time = "2025-01-29T04:18:33.823Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860, upload_time = "2025-01-29T04:19:12.944Z" }, + { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673, upload_time = "2025-01-29T05:37:20.574Z" }, + { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190, upload_time = "2025-01-29T05:37:22.106Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926, upload_time = "2025-01-29T04:18:58.564Z" }, + { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613, upload_time = "2025-01-29T04:19:27.63Z" }, + { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload_time = "2025-01-29T04:15:38.082Z" }, ] [[package]] -name = "cssutils" -version = "2.11.1" +name = "blis" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "more-itertools" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/9f/329d26121fe165be44b1dfff21aa0dc348f04633931f1d20ed6cf448a236/cssutils-2.11.1.tar.gz", hash = "sha256:0563a76513b6af6eebbe788c3bf3d01c920e46b3f90c8416738c5cfc773ff8e2", size = 711657 } +sdist = { url = "https://files.pythonhosted.org/packages/96/f3/7c5a47a0d5ec0362bab29fd4f497b4b1975473bf30b7a02bc9c0b0e84f7a/blis-1.3.0.tar.gz", hash = "sha256:1695a87e3fc4c20d9b9140f5238cac0514c411b750e8cdcec5d8320c71f62e99", size = 2510328, upload_time = "2025-04-03T15:09:47.767Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/ec/bb273b7208c606890dc36540fe667d06ce840a6f62f9fae7e658fcdc90fb/cssutils-2.11.1-py3-none-any.whl", hash = "sha256:a67bfdfdff4f3867fab43698ec4897c1a828eca5973f4073321b3bccaf1199b1", size = 385747 }, + { url = "https://files.pythonhosted.org/packages/fc/95/9221d2e7b2940ff7de87c84c6ac7a8dedfc24f703f0fb9c71b049a6e414f/blis-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:03c5d2d59415c58ec60e16a0d35d6516a50dae8f17963445845fd961530fcfb0", size = 6973671, upload_time = "2025-04-03T15:08:36.838Z" }, + { url = "https://files.pythonhosted.org/packages/17/96/51608bc2ef3bf7ebcb81905626ab2d08c620fd02b70cecb14174b6e64c98/blis-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d1b5c7e7b337e4b0b4887d4837c25e787a940c38d691c6b2936baebf1d008f1b", size = 1280540, upload_time = "2025-04-03T15:08:38.749Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f1/70ef665581e672be4678237598bc281098e90c45c2659e447007a5964b13/blis-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f446f853e755e71e7abb9b23ad25fe36f7e3dc6a88ba3e071a06dedd029fb5dc", size = 2983851, upload_time = "2025-04-03T15:08:40.281Z" }, + { url = "https://files.pythonhosted.org/packages/13/63/86e04159482d6b42692d95ac545e2dddff6d6c263a82dfc5358c1a712800/blis-1.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9448cd77af47afbecaf0267168016b76298553cc46e51c1c00c22256df21c7", size = 3187729, upload_time = "2025-04-03T15:08:41.849Z" }, + { url = "https://files.pythonhosted.org/packages/52/b1/be8346c859967d09a8d5bc61c06131885e0124eb84c8cec599c509beb5c4/blis-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb2571616da1dfa4a927f2952ae90afc7b061f287da47a0a1bd8318c3a53e178", size = 11531202, upload_time = "2025-04-03T15:08:44.045Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/6da6e1ae7562cf53852cc05ff938468dc03a96ef9e753a48b0bce01a372d/blis-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9995848456a3684a81585e1d19e7315023614cff9e52ae292129ad600117d7d9", size = 2989619, upload_time = "2025-04-03T15:08:46.076Z" }, + { url = "https://files.pythonhosted.org/packages/dd/54/9ae34552e894765e05d8508b37575f0e26cb70d07a67971258869ae6dbf4/blis-1.3.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:520a21fea2355bce4a103893b13c581ecb7034547d4d71d22f7033419c6ace75", size = 4226545, upload_time = "2025-04-03T15:08:47.532Z" }, + { url = "https://files.pythonhosted.org/packages/60/9e/bfbf3c6b68ae9dbbc49164aa49da8421afa223390f461f7fbf528740757d/blis-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5cb979397cb69ecffe7a67614dd044de0c43486348e1591d1cf77f425c1eb7bd", size = 14690321, upload_time = "2025-04-03T15:08:49.649Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a3/f4f3327d0b3b11e8a6f5ad0d522c9c9275db59038ec605f5e6bccf3d3817/blis-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:2cbc7b6997be35d94e004587eaf211ca187e4013f9a2df0bb949f3dfba18c68c", size = 6248962, upload_time = "2025-04-03T15:08:51.94Z" }, + { url = "https://files.pythonhosted.org/packages/64/a1/ea38adca95fbea0835fd09fd7e1a5fd4d15e723645108360fce8e860e961/blis-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:456833a6006dce2165d68e1ab0aa7678608a9a99a18aa37af7aa0437c972f7f6", size = 6976242, upload_time = "2025-04-03T15:08:53.473Z" }, + { url = "https://files.pythonhosted.org/packages/c1/13/a3b66fd57c75343a5b2e6323cd8f73bdd2e9b328deba7cf676ec334ec754/blis-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8072fbb03505444c818810536ad77616a18d97bbde06e8ec69755d917abb7f31", size = 1281504, upload_time = "2025-04-03T15:08:54.934Z" }, + { url = "https://files.pythonhosted.org/packages/3b/a1/22d728aac953c1293d9d9ba119f467233c8991cb4ecb00689970bf6c2449/blis-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:594c2332bcb1a0fdacb5e857a1afaf338d52c05ba24710515cddbf25862787ac", size = 3101280, upload_time = "2025-04-03T15:08:56.35Z" }, + { url = "https://files.pythonhosted.org/packages/e0/8b/40301bfa2dab268c4a52735d830939a26ef2e1d6d5ce5add4d3c4a9ba276/blis-1.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2cf336a810bd0e6ab52e8ba5455c42ff02f6216acb196ffc831cd30ab084127e", size = 3316521, upload_time = "2025-04-03T15:08:59.852Z" }, + { url = "https://files.pythonhosted.org/packages/da/77/6fbd4d9b923f3914c589d38a19dfc8fd45f54296aef75aba908a7d176871/blis-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cad91ae2c8a11286b32e80ac7e579d7028f8c0a22afa1e817edddc18051f05b2", size = 11650028, upload_time = "2025-04-03T15:09:02.009Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/336d40ed5b4ca33f098eb6e753814526279837069b7770db7bd25fcba9a7/blis-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1bf4267616fb97a3b869cc8d278383faa86882dc8330067421f9bf9c06e6b80c", size = 3115887, upload_time = "2025-04-03T15:09:03.987Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ee/a69b3322b0659705c5e2aeec3bbbd474eb37d028fd58fd32795cfc5cbf84/blis-1.3.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:45c6f6e801c712592f487f4021c9a85079d6ff8fc487f3d8202212edd4900f8e", size = 4348881, upload_time = "2025-04-03T15:09:05.976Z" }, + { url = "https://files.pythonhosted.org/packages/95/c9/774812eac52a11be854f0d41afdade2ac1ce1be0b749aec63c3816b57b7d/blis-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:570113bc81bce8890fa2c067a30f6e6caa82bb3be7de0926d659e986e40f5509", size = 14840892, upload_time = "2025-04-03T15:09:08.439Z" }, + { url = "https://files.pythonhosted.org/packages/35/3a/f9414cf9b2c43aad87e8687ad2cdb0e66e996c20288584621a12725e83dd/blis-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:75ecaa548589cba2ba75e621e2a8b89888e3f326ef1a27e7a9b1713114467ff2", size = 6232289, upload_time = "2025-04-03T15:09:11.029Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3f/67140d6588e600577f92d2c938e9492a8cd0706bab770978ee84ecb86e70/blis-1.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ef188f1f914d52acbbd75993ba25554e381ec9099758b340cd0da41af94ae8ae", size = 6988854, upload_time = "2025-04-03T15:09:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/d1/05/30587d1b168fa27d1bf6869a1be4bcb3f10493f836381a033aa9c7a10ab8/blis-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:626f84522faa51d5a52f9820551a84a5e02490bf6d1abdfc8d27934a0ff939de", size = 1282465, upload_time = "2025-04-03T15:09:15.081Z" }, + { url = "https://files.pythonhosted.org/packages/35/13/60d2dd0443a7a56a0a160d873444e4b9189bb2939d93457864432ee18c90/blis-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f56e0454ce44bc08797383ce427ee5e2b044aab1eafb450eab82e86f8bfac853", size = 3061088, upload_time = "2025-04-03T15:09:16.535Z" }, + { url = "https://files.pythonhosted.org/packages/2f/30/4909baf57c3cd48414c284e4fced42157c4768f83bf6c95b0bb446192b45/blis-1.3.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9bb5770efe233374d73a567af5cdef24f48bead83d118bdb9bd5c2187b0f010", size = 3259127, upload_time = "2025-04-03T15:09:18.528Z" }, + { url = "https://files.pythonhosted.org/packages/bb/bf/625121119107d3beafe96eb776b00a472f0210c07d07b1ed160ab7db292a/blis-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d52ce33a1895d82f2f39f7689d5e70b06ebba6bc6f610046ecd81db88d650aac", size = 11619003, upload_time = "2025-04-03T15:09:20.139Z" }, + { url = "https://files.pythonhosted.org/packages/81/92/0bad7a4c29c7a1ab10db27b04babec7ca4a3f504543ef2d1f985fb84c41a/blis-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6c78e8dd420e0e695df0ceecf950f3cf823e0a1b8c2871a7e35117c744d45861", size = 3062135, upload_time = "2025-04-03T15:09:22.142Z" }, + { url = "https://files.pythonhosted.org/packages/35/b5/ea9b4f6b75c9dce24ce0d6fa15d5eaab54b115a57967d504e460db901c59/blis-1.3.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7a060700ee98ea44a1b9833b16d3dd1375aaa9d3230222bfc5f13c4664e5710e", size = 4298755, upload_time = "2025-04-03T15:09:24.064Z" }, + { url = "https://files.pythonhosted.org/packages/e5/c5/9b7383752cdc4ca92359c161b1086bd158b4f3cda5813a390ff9c8c1b892/blis-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:250f0b0aeca0fdde7117751a54ae6d6b6818a446a619f3c0c63f3deb77f700a8", size = 14785385, upload_time = "2025-04-03T15:09:25.74Z" }, + { url = "https://files.pythonhosted.org/packages/0c/92/6bb1940a491ce9d3ec52372bc35988bec779b16ace7e87287d981df31eeb/blis-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:2e6f468467a18a7c2ac2e411643f5cfa45a435701e2c04ad4aa46bb02fc3aa5c", size = 6260208, upload_time = "2025-04-03T15:09:28.207Z" }, + { url = "https://files.pythonhosted.org/packages/91/ec/2b1e366e7b4e3cdb052a4eeba33cc6a3e25fe20566f3062dbe59a8dd7f78/blis-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4d6a91c8726d0bc3345a8e0c8b7b8e800bee0b9acc4c2a0dbeb782b8b651f824", size = 6985730, upload_time = "2025-04-03T15:09:29.884Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8b/a3374a970e1ae6138b2ec6bffeb1018068c5f0dbf2b12dd8ab16a47ae4a0/blis-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e3c20bc3d7143383195cc472373fb301d3bafbacd8ab8f3bffc27c68bef45d81", size = 1280751, upload_time = "2025-04-03T15:09:32.007Z" }, + { url = "https://files.pythonhosted.org/packages/53/97/83cc91c451709c85650714df3464024bf37ef791be1e0fae0d2a0f945da6/blis-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:778c4b84c6eccab223d8afe20727820f6c7dd7a010c3bfb262104cc83b0a8e4c", size = 3047726, upload_time = "2025-04-03T15:09:33.521Z" }, + { url = "https://files.pythonhosted.org/packages/ae/21/fbf9b45d6af91c5ce32df4007886c0332b977558cba34b0bc00b98ebc188/blis-1.3.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69584589977366366cd99cc7cb23a76a814df8bcae8b777fde4a94e8684c1fb8", size = 3249935, upload_time = "2025-04-03T15:09:36.264Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b1/5716b8cd784c0a0d08f9b3773c8eb4c37f5f9ed3a9f6ef961373e123b1cf/blis-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b2adc4549e610b59e8db5a57ab7206e4ac1502ac5b261ed0e6de42d3fb311d5", size = 11614296, upload_time = "2025-04-03T15:09:38.342Z" }, + { url = "https://files.pythonhosted.org/packages/36/0f/e2ed2642cf41dcae3431cfbcd94543646adba46eaa2736ac27647216e4f7/blis-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9aaa84df638e0bb7909a35e3c220168df2b90f267967b3004a88f57b49fbe4ec", size = 3063082, upload_time = "2025-04-03T15:09:40.329Z" }, + { url = "https://files.pythonhosted.org/packages/cb/f0/627a36b99a9cd9af73be7bb451d6884d5b4aece297eb29b9fc13e70c1f2b/blis-1.3.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0da7b54331bed31aa55839da2d0e5451447e1f5e8a9367cce7ff1fb27498a22a", size = 4290919, upload_time = "2025-04-03T15:09:41.845Z" }, + { url = "https://files.pythonhosted.org/packages/5b/f9/a415707185a82082b96ab857e5c3b7a59b0ad73ed04ace1cbb64835c3432/blis-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:682175bf2d047129b3715e3f1305c6b23a45e2ce24c4b1d0fa2eb03eb877edd4", size = 14795975, upload_time = "2025-04-03T15:09:43.611Z" }, + { url = "https://files.pythonhosted.org/packages/16/f1/8cc8118946dbb9cbd74f406d30d31ee8d2f723f6fb4c8245e2bc67175fd4/blis-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:91de2baf03da3a173cf62771f1d6b9236a27a8cbd0e0033be198f06ef6224986", size = 6258624, upload_time = "2025-04-03T15:09:46.056Z" }, ] [[package]] -name = "distlib" -version = "0.3.8" +name = "build" +version = "1.2.2.post1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c4/91/e2df406fb4efacdf46871c25cde65d3c6ee5e173b7e5a4547a47bae91920/distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64", size = 609931 } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10.2'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/46/aeab111f8e06793e4f0e421fcad593d547fb8313b50990f31681ee2fb1ad/build-1.2.2.post1.tar.gz", hash = "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7", size = 46701, upload_time = "2024-10-06T17:22:25.251Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/41/9307e4f5f9976bc8b7fea0b66367734e8faf3ec84bc0d412d8cfabbb66cd/distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784", size = 468850 }, + { url = "https://files.pythonhosted.org/packages/84/c2/80633736cd183ee4a62107413def345f7e6e3c01563dbca1417363cf957e/build-1.2.2.post1-py3-none-any.whl", hash = "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", size = 22950, upload_time = "2024-10-06T17:22:23.299Z" }, ] [[package]] -name = "dnspython" -version = "2.6.1" +name = "cachetools" +version = "5.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/7d/c871f55054e403fdfd6b8f65fd6d1c4e147ed100d3e9f9ba1fe695403939/dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc", size = 332727 } +sdist = { url = "https://files.pythonhosted.org/packages/c3/38/a0f315319737ecf45b4319a8cd1f3a908e29d9277b46942263292115eee7/cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a", size = 27661, upload_time = "2024-08-18T20:28:44.639Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/a1/8c5287991ddb8d3e4662f71356d9656d91ab3a36618c3dd11b280df0d255/dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", size = 307696 }, + { url = "https://files.pythonhosted.org/packages/a4/07/14f8ad37f2d12a5ce41206c21820d8cb6561b728e51fad4530dff0552a67/cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292", size = 9524, upload_time = "2024-08-18T20:28:43.404Z" }, ] [[package]] -name = "email-validator" -version = "2.2.0" +name = "catalogue" +version = "2.0.10" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dnspython" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967 } +sdist = { url = "https://files.pythonhosted.org/packages/38/b4/244d58127e1cdf04cf2dc7d9566f0d24ef01d5ce21811bab088ecc62b5ea/catalogue-2.0.10.tar.gz", hash = "sha256:4f56daa940913d3f09d589c191c74e5a6d51762b3a9e37dd53b7437afd6cda15", size = 19561, upload_time = "2023-09-25T06:29:24.962Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521 }, + { url = "https://files.pythonhosted.org/packages/9e/96/d32b941a501ab566a16358d68b6eb4e4acc373fab3c3c4d7d9e649f7b4bb/catalogue-2.0.10-py3-none-any.whl", hash = "sha256:58c2de0020aa90f4a2da7dfad161bf7b3b054c86a5f09fcedc0b2b740c109a9f", size = 17325, upload_time = "2023-09-25T06:29:23.337Z" }, ] [[package]] -name = "emails" -version = "0.6" +name = "celery" +version = "5.5.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "chardet" }, - { name = "cssutils" }, - { name = "lxml" }, - { name = "premailer" }, + { name = "billiard" }, + { name = "click" }, + { name = "click-didyoumean" }, + { name = "click-plugins" }, + { name = "click-repl" }, + { name = "kombu" }, { name = "python-dateutil" }, - { name = "requests" }, + { name = "vine" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d3/f9/c1e315aa82ed9f037186c30109200fb4b4c51b5483b8065daa0ca836a336/emails-0.6.tar.gz", hash = "sha256:a4c2d67ea8b8831967a750d8edc6e77040d7693143fe280e6d2a367d9c36ff88", size = 44066 } +sdist = { url = "https://files.pythonhosted.org/packages/bb/7d/6c289f407d219ba36d8b384b42489ebdd0c84ce9c413875a8aae0c85f35b/celery-5.5.3.tar.gz", hash = "sha256:6c972ae7968c2b5281227f01c3a3f984037d21c5129d07bf3550cc2afc6b10a5", size = 1667144, upload_time = "2025-06-01T11:08:12.563Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/55/7e/b648d640d88d31de49e566832aca9cce025c52d6349b0a0fc65e9df1f4c5/emails-0.6-py2.py3-none-any.whl", hash = "sha256:72c1e3198075709cc35f67e1b49e2da1a2bc087e9b444073db61a379adfb7f3c", size = 56250 }, + { url = "https://files.pythonhosted.org/packages/c9/af/0dcccc7fdcdf170f9a1585e5e96b6fb0ba1749ef6be8c89a6202284759bd/celery-5.5.3-py3-none-any.whl", hash = "sha256:0b5761a07057acee94694464ca482416b959568904c9dfa41ce8413a7d65d525", size = 438775, upload_time = "2025-06-01T11:08:09.94Z" }, ] [[package]] -name = "exceptiongroup" -version = "1.2.2" +name = "certifi" +version = "2024.8.30" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507, upload_time = "2024-08-30T01:55:04.365Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, + { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321, upload_time = "2024-08-30T01:55:02.591Z" }, ] [[package]] -name = "fastapi" -version = "0.115.0" +name = "cffi" +version = "1.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pydantic" }, - { name = "starlette" }, - { name = "typing-extensions" }, + { name = "pycparser" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7b/5e/bf0471f14bf6ebfbee8208148a3396d1a23298531a6cc10776c59f4c0f87/fastapi-0.115.0.tar.gz", hash = "sha256:f93b4ca3529a8ebc6fc3fcf710e5efa8de3df9b41570958abf1d97d843138004", size = 302295 } +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload_time = "2024-09-04T20:45:21.852Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/ab/a1f7eed031aeb1c406a6e9d45ca04bff401c8a25a30dd0e4fd2caae767c3/fastapi-0.115.0-py3-none-any.whl", hash = "sha256:17ea427674467486e997206a5ab25760f6b09e069f099b96f5b55a32fb6f1631", size = 94625 }, -] - -[package.optional-dependencies] -standard = [ - { name = "email-validator" }, - { name = "fastapi-cli", extra = ["standard"] }, - { name = "httpx" }, - { name = "jinja2" }, - { name = "python-multipart" }, - { name = "uvicorn", extra = ["standard"] }, + { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191, upload_time = "2024-09-04T20:43:30.027Z" }, + { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592, upload_time = "2024-09-04T20:43:32.108Z" }, + { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024, upload_time = "2024-09-04T20:43:34.186Z" }, + { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188, upload_time = "2024-09-04T20:43:36.286Z" }, + { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571, upload_time = "2024-09-04T20:43:38.586Z" }, + { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687, upload_time = "2024-09-04T20:43:40.084Z" }, + { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211, upload_time = "2024-09-04T20:43:41.526Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325, upload_time = "2024-09-04T20:43:43.117Z" }, + { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784, upload_time = "2024-09-04T20:43:45.256Z" }, + { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564, upload_time = "2024-09-04T20:43:46.779Z" }, + { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804, upload_time = "2024-09-04T20:43:48.186Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299, upload_time = "2024-09-04T20:43:49.812Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload_time = "2024-09-04T20:43:51.124Z" }, + { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload_time = "2024-09-04T20:43:52.872Z" }, + { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload_time = "2024-09-04T20:43:56.123Z" }, + { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload_time = "2024-09-04T20:43:57.891Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload_time = "2024-09-04T20:44:00.18Z" }, + { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload_time = "2024-09-04T20:44:01.585Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload_time = "2024-09-04T20:44:03.467Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload_time = "2024-09-04T20:44:05.023Z" }, + { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload_time = "2024-09-04T20:44:06.444Z" }, + { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload_time = "2024-09-04T20:44:08.206Z" }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload_time = "2024-09-04T20:44:09.481Z" }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload_time = "2024-09-04T20:44:10.873Z" }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload_time = "2024-09-04T20:44:12.232Z" }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload_time = "2024-09-04T20:44:13.739Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload_time = "2024-09-04T20:44:15.231Z" }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload_time = "2024-09-04T20:44:17.188Z" }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload_time = "2024-09-04T20:44:18.688Z" }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload_time = "2024-09-04T20:44:20.248Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload_time = "2024-09-04T20:44:21.673Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload_time = "2024-09-04T20:44:23.245Z" }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload_time = "2024-09-04T20:44:24.757Z" }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload_time = "2024-09-04T20:44:26.208Z" }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload_time = "2024-09-04T20:44:27.578Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload_time = "2024-09-04T20:44:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload_time = "2024-09-04T20:44:30.289Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload_time = "2024-09-04T20:44:32.01Z" }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload_time = "2024-09-04T20:44:33.606Z" }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload_time = "2024-09-04T20:44:35.191Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload_time = "2024-09-04T20:44:36.743Z" }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload_time = "2024-09-04T20:44:38.492Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload_time = "2024-09-04T20:44:40.046Z" }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload_time = "2024-09-04T20:44:41.616Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload_time = "2024-09-04T20:44:43.733Z" }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload_time = "2024-09-04T20:44:45.309Z" }, ] [[package]] -name = "fastapi-cli" -version = "0.0.5" +name = "cfgv" +version = "3.4.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typer" }, - { name = "uvicorn", extra = ["standard"] }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c5/f8/1ad5ce32d029aeb9117e9a5a9b3e314a8477525d60c12a9b7730a3c186ec/fastapi_cli-0.0.5.tar.gz", hash = "sha256:d30e1239c6f46fcb95e606f02cdda59a1e2fa778a54b64686b3ff27f6211ff9f", size = 15571 } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload_time = "2023-08-12T20:38:17.776Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/24/ea/4b5011012ac925fe2f83b19d0e09cee9d324141ec7bf5e78bb2817f96513/fastapi_cli-0.0.5-py3-none-any.whl", hash = "sha256:e94d847524648c748a5350673546bbf9bcaeb086b33c24f2e82e021436866a46", size = 9489 }, -] - -[package.optional-dependencies] -standard = [ - { name = "uvicorn", extra = ["standard"] }, + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload_time = "2023-08-12T20:38:16.269Z" }, ] [[package]] -name = "filelock" -version = "3.16.1" +name = "chardet" +version = "5.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/f7b6ab21ec75897ed80c17d79b15951a719226b9fababf1e40ea74d69079/chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", size = 2069618, upload_time = "2023-08-01T19:23:02.662Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, -] - -[[package]] -name = "greenlet" -version = "3.1.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2f/ff/df5fede753cc10f6a5be0931204ea30c35fa2f2ea7a35b25bdaf4fe40e46/greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467", size = 186022 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/90/5234a78dc0ef6496a6eb97b67a42a8e96742a56f7dc808cb954a85390448/greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563", size = 271235 }, - { url = "https://files.pythonhosted.org/packages/7c/16/cd631fa0ab7d06ef06387135b7549fdcc77d8d859ed770a0d28e47b20972/greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83", size = 637168 }, - { url = "https://files.pythonhosted.org/packages/2f/b1/aed39043a6fec33c284a2c9abd63ce191f4f1a07319340ffc04d2ed3256f/greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0", size = 648826 }, - { url = "https://files.pythonhosted.org/packages/76/25/40e0112f7f3ebe54e8e8ed91b2b9f970805143efef16d043dfc15e70f44b/greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120", size = 644443 }, - { url = "https://files.pythonhosted.org/packages/fb/2f/3850b867a9af519794784a7eeed1dd5bc68ffbcc5b28cef703711025fd0a/greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc", size = 643295 }, - { url = "https://files.pythonhosted.org/packages/cf/69/79e4d63b9387b48939096e25115b8af7cd8a90397a304f92436bcb21f5b2/greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617", size = 599544 }, - { url = "https://files.pythonhosted.org/packages/46/1d/44dbcb0e6c323bd6f71b8c2f4233766a5faf4b8948873225d34a0b7efa71/greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7", size = 1125456 }, - { url = "https://files.pythonhosted.org/packages/e0/1d/a305dce121838d0278cee39d5bb268c657f10a5363ae4b726848f833f1bb/greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6", size = 1149111 }, - { url = "https://files.pythonhosted.org/packages/96/28/d62835fb33fb5652f2e98d34c44ad1a0feacc8b1d3f1aecab035f51f267d/greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80", size = 298392 }, - { url = "https://files.pythonhosted.org/packages/28/62/1c2665558618553c42922ed47a4e6d6527e2fa3516a8256c2f431c5d0441/greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70", size = 272479 }, - { url = "https://files.pythonhosted.org/packages/76/9d/421e2d5f07285b6e4e3a676b016ca781f63cfe4a0cd8eaecf3fd6f7a71ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159", size = 640404 }, - { url = "https://files.pythonhosted.org/packages/e5/de/6e05f5c59262a584e502dd3d261bbdd2c97ab5416cc9c0b91ea38932a901/greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e", size = 652813 }, - { url = "https://files.pythonhosted.org/packages/49/93/d5f93c84241acdea15a8fd329362c2c71c79e1a507c3f142a5d67ea435ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1", size = 648517 }, - { url = "https://files.pythonhosted.org/packages/15/85/72f77fc02d00470c86a5c982b8daafdf65d38aefbbe441cebff3bf7037fc/greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383", size = 647831 }, - { url = "https://files.pythonhosted.org/packages/f7/4b/1c9695aa24f808e156c8f4813f685d975ca73c000c2a5056c514c64980f6/greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a", size = 602413 }, - { url = "https://files.pythonhosted.org/packages/76/70/ad6e5b31ef330f03b12559d19fda2606a522d3849cde46b24f223d6d1619/greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511", size = 1129619 }, - { url = "https://files.pythonhosted.org/packages/f4/fb/201e1b932e584066e0f0658b538e73c459b34d44b4bd4034f682423bc801/greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395", size = 1155198 }, - { url = "https://files.pythonhosted.org/packages/12/da/b9ed5e310bb8b89661b80cbcd4db5a067903bbcd7fc854923f5ebb4144f0/greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39", size = 298930 }, - { url = "https://files.pythonhosted.org/packages/7d/ec/bad1ac26764d26aa1353216fcbfa4670050f66d445448aafa227f8b16e80/greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d", size = 274260 }, - { url = "https://files.pythonhosted.org/packages/66/d4/c8c04958870f482459ab5956c2942c4ec35cac7fe245527f1039837c17a9/greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79", size = 649064 }, - { url = "https://files.pythonhosted.org/packages/51/41/467b12a8c7c1303d20abcca145db2be4e6cd50a951fa30af48b6ec607581/greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa", size = 663420 }, - { url = "https://files.pythonhosted.org/packages/27/8f/2a93cd9b1e7107d5c7b3b7816eeadcac2ebcaf6d6513df9abaf0334777f6/greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441", size = 658035 }, - { url = "https://files.pythonhosted.org/packages/57/5c/7c6f50cb12be092e1dccb2599be5a942c3416dbcfb76efcf54b3f8be4d8d/greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36", size = 660105 }, - { url = "https://files.pythonhosted.org/packages/f1/66/033e58a50fd9ec9df00a8671c74f1f3a320564c6415a4ed82a1c651654ba/greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9", size = 613077 }, - { url = "https://files.pythonhosted.org/packages/19/c5/36384a06f748044d06bdd8776e231fadf92fc896bd12cb1c9f5a1bda9578/greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0", size = 1135975 }, - { url = "https://files.pythonhosted.org/packages/38/f9/c0a0eb61bdf808d23266ecf1d63309f0e1471f284300ce6dac0ae1231881/greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942", size = 1163955 }, - { url = "https://files.pythonhosted.org/packages/43/21/a5d9df1d21514883333fc86584c07c2b49ba7c602e670b174bd73cfc9c7f/greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01", size = 299655 }, - { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990 }, - { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175 }, - { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425 }, - { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736 }, - { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347 }, - { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583 }, - { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039 }, - { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716 }, - { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490 }, - { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731 }, - { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304 }, - { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537 }, - { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506 }, - { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753 }, - { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731 }, - { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 }, + { url = "https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970", size = 199385, upload_time = "2023-08-01T19:23:00.661Z" }, ] [[package]] -name = "h11" -version = "0.14.0" +name = "charset-normalizer" +version = "3.3.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809, upload_time = "2023-11-01T04:04:59.997Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, + { url = "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", size = 194219, upload_time = "2023-11-01T04:02:29.048Z" }, + { url = "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", size = 122521, upload_time = "2023-11-01T04:02:32.452Z" }, + { url = "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", size = 120383, upload_time = "2023-11-01T04:02:34.11Z" }, + { url = "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", size = 138223, upload_time = "2023-11-01T04:02:36.213Z" }, + { url = "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", size = 148101, upload_time = "2023-11-01T04:02:38.067Z" }, + { url = "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", size = 140699, upload_time = "2023-11-01T04:02:39.436Z" }, + { url = "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", size = 142065, upload_time = "2023-11-01T04:02:41.357Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", size = 144505, upload_time = "2023-11-01T04:02:43.108Z" }, + { url = "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", size = 139425, upload_time = "2023-11-01T04:02:45.427Z" }, + { url = "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", size = 145287, upload_time = "2023-11-01T04:02:46.705Z" }, + { url = "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", size = 149929, upload_time = "2023-11-01T04:02:48.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", size = 141605, upload_time = "2023-11-01T04:02:49.605Z" }, + { url = "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", size = 142646, upload_time = "2023-11-01T04:02:51.35Z" }, + { url = "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", size = 92846, upload_time = "2023-11-01T04:02:52.679Z" }, + { url = "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", size = 100343, upload_time = "2023-11-01T04:02:53.915Z" }, + { url = "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", size = 191647, upload_time = "2023-11-01T04:02:55.329Z" }, + { url = "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", size = 121434, upload_time = "2023-11-01T04:02:57.173Z" }, + { url = "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", size = 118979, upload_time = "2023-11-01T04:02:58.442Z" }, + { url = "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", size = 136582, upload_time = "2023-11-01T04:02:59.776Z" }, + { url = "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", size = 146645, upload_time = "2023-11-01T04:03:02.186Z" }, + { url = "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", size = 139398, upload_time = "2023-11-01T04:03:04.255Z" }, + { url = "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", size = 140273, upload_time = "2023-11-01T04:03:05.983Z" }, + { url = "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", size = 142577, upload_time = "2023-11-01T04:03:07.567Z" }, + { url = "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", size = 137747, upload_time = "2023-11-01T04:03:08.886Z" }, + { url = "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", size = 143375, upload_time = "2023-11-01T04:03:10.613Z" }, + { url = "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", size = 148474, upload_time = "2023-11-01T04:03:11.973Z" }, + { url = "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", size = 140232, upload_time = "2023-11-01T04:03:13.505Z" }, + { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859, upload_time = "2023-11-01T04:03:17.362Z" }, + { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509, upload_time = "2023-11-01T04:03:21.453Z" }, + { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870, upload_time = "2023-11-01T04:03:22.723Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892, upload_time = "2023-11-01T04:03:24.135Z" }, + { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213, upload_time = "2023-11-01T04:03:25.66Z" }, + { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404, upload_time = "2023-11-01T04:03:27.04Z" }, + { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275, upload_time = "2023-11-01T04:03:28.466Z" }, + { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518, upload_time = "2023-11-01T04:03:29.82Z" }, + { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182, upload_time = "2023-11-01T04:03:31.511Z" }, + { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869, upload_time = "2023-11-01T04:03:32.887Z" }, + { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042, upload_time = "2023-11-01T04:03:34.412Z" }, + { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275, upload_time = "2023-11-01T04:03:35.759Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819, upload_time = "2023-11-01T04:03:37.216Z" }, + { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415, upload_time = "2023-11-01T04:03:38.694Z" }, + { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212, upload_time = "2023-11-01T04:03:40.07Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167, upload_time = "2023-11-01T04:03:41.491Z" }, + { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041, upload_time = "2023-11-01T04:03:42.836Z" }, + { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397, upload_time = "2023-11-01T04:03:44.467Z" }, + { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543, upload_time = "2023-11-01T04:04:58.622Z" }, ] [[package]] -name = "httpcore" -version = "1.0.5" +name = "chromadb" +version = "1.0.15" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "certifi" }, - { name = "h11" }, + { name = "bcrypt" }, + { name = "build" }, + { name = "grpcio" }, + { name = "httpx" }, + { name = "importlib-resources" }, + { name = "jsonschema" }, + { name = "kubernetes" }, + { name = "mmh3" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "onnxruntime" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-grpc" }, + { name = "opentelemetry-sdk" }, + { name = "orjson" }, + { name = "overrides" }, + { name = "posthog" }, + { name = "pybase64" }, + { name = "pydantic" }, + { name = "pypika" }, + { name = "pyyaml" }, + { name = "rich" }, + { name = "tenacity" }, + { name = "tokenizers" }, + { name = "tqdm" }, + { name = "typer" }, + { name = "typing-extensions" }, + { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/b0/5e8b8674f8d203335a62fdfcfa0d11ebe09e23613c3391033cbba35f7926/httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", size = 83234 } +sdist = { url = "https://files.pythonhosted.org/packages/ad/e2/0653b2e539db5512d2200c759f1bc7f9ef5609fe47f3c7d24b82f62dc00f/chromadb-1.0.15.tar.gz", hash = "sha256:3e910da3f5414e2204f89c7beca1650847f2bf3bd71f11a2e40aad1eb31050aa", size = 1218840, upload_time = "2025-07-02T17:07:09.875Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/d4/e5d7e4f2174f8a4d63c8897d79eb8fe2503f7ecc03282fee1fa2719c2704/httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5", size = 77926 }, + { url = "https://files.pythonhosted.org/packages/85/5a/866c6f0c2160cbc8dca0cf77b2fb391dcf435b32a58743da1bc1a08dc442/chromadb-1.0.15-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:51791553014297798b53df4e043e9c30f4e8bd157647971a6bb02b04bfa65f82", size = 18838820, upload_time = "2025-07-02T17:07:07.632Z" }, + { url = "https://files.pythonhosted.org/packages/e1/18/ff9b58ab5d334f5ecff7fdbacd6761bac467176708fa4d2500ae7c048af0/chromadb-1.0.15-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:48015803c0631c3a817befc276436dc084bb628c37fd4214047212afb2056291", size = 18057131, upload_time = "2025-07-02T17:07:05.15Z" }, + { url = "https://files.pythonhosted.org/packages/31/49/74e34cc5aeeb25aff2c0ede6790b3671e14c1b91574dd8f98d266a4c5aad/chromadb-1.0.15-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b73cd6fb32fcdd91c577cca16ea6112b691d72b441bb3f2140426d1e79e453a", size = 18595284, upload_time = "2025-07-02T17:06:59.102Z" }, + { url = "https://files.pythonhosted.org/packages/cb/33/190df917a057067e37f8b48d082d769bed8b3c0c507edefc7b6c6bb577d0/chromadb-1.0.15-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:479f1b401af9e7c20f50642ffb3376abbfd78e2b5b170429f7c79eff52e367db", size = 19526626, upload_time = "2025-07-02T17:07:02.163Z" }, + { url = "https://files.pythonhosted.org/packages/a1/30/6890da607358993f87a01e80bcce916b4d91515ce865f07dc06845cb472f/chromadb-1.0.15-cp39-abi3-win_amd64.whl", hash = "sha256:e0cb3b93fdc42b1786f151d413ef36299f30f783a30ce08bf0bfb12e552b4190", size = 19520490, upload_time = "2025-07-02T17:07:11.559Z" }, ] [[package]] -name = "httptools" -version = "0.6.1" +name = "click" +version = "8.1.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/67/1d/d77686502fced061b3ead1c35a2d70f6b281b5f723c4eff7a2277c04e4a2/httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a", size = 191228 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/6a/80bce0216b63babf51cdc34814c3f0f10489e13ab89fb6bc91202736a8a2/httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f", size = 149778 }, - { url = "https://files.pythonhosted.org/packages/bd/7d/4cd75356dfe0ed0b40ca6873646bf9ff7b5138236c72338dc569dc57d509/httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563", size = 77604 }, - { url = "https://files.pythonhosted.org/packages/4e/74/6348ce41fb5c1484f35184c172efb8854a288e6090bb54e2210598268369/httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58", size = 346717 }, - { url = "https://files.pythonhosted.org/packages/65/e7/dd5ba95c84047118a363f0755ad78e639e0529be92424bb020496578aa3b/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", size = 341442 }, - { url = "https://files.pythonhosted.org/packages/d8/97/b37d596bc32be291477a8912bf9d1508d7e8553aa11a30cd871fd89cbae4/httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142", size = 354531 }, - { url = "https://files.pythonhosted.org/packages/99/c9/53ed7176583ec4b4364d941a08624288f2ae55b4ff58b392cdb68db1e1ed/httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658", size = 347754 }, - { url = "https://files.pythonhosted.org/packages/1e/fc/8a26c2adcd3f141e4729897633f03832b71ebea6f4c31cce67a92ded1961/httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b", size = 58165 }, - { url = "https://files.pythonhosted.org/packages/f5/d1/53283b96ed823d5e4d89ee9aa0f29df5a1bdf67f148e061549a595d534e4/httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1", size = 145855 }, - { url = "https://files.pythonhosted.org/packages/80/dd/cebc9d4b1d4b70e9f3d40d1db0829a28d57ca139d0b04197713816a11996/httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0", size = 75604 }, - { url = "https://files.pythonhosted.org/packages/76/7a/45c5a9a2e9d21f7381866eb7b6ead5a84d8fe7e54e35208eeb18320a29b4/httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc", size = 324784 }, - { url = "https://files.pythonhosted.org/packages/59/23/047a89e66045232fb82c50ae57699e40f70e073ae5ccd53f54e532fbd2a2/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", size = 318547 }, - { url = "https://files.pythonhosted.org/packages/82/f5/50708abc7965d7d93c0ee14a148ccc6d078a508f47fe9357c79d5360f252/httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837", size = 330211 }, - { url = "https://files.pythonhosted.org/packages/e3/1e/9823ca7aab323c0e0e9dd82ce835a6e93b69f69aedffbc94d31e327f4283/httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d", size = 322174 }, - { url = "https://files.pythonhosted.org/packages/14/e4/20d28dfe7f5b5603b6b04c33bb88662ad749de51f0c539a561f235f42666/httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3", size = 55434 }, - { url = "https://files.pythonhosted.org/packages/60/13/b62e086b650752adf9094b7e62dab97f4cb7701005664544494b7956a51e/httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0", size = 146354 }, - { url = "https://files.pythonhosted.org/packages/f8/5d/9ad32b79b6c24524087e78aa3f0a2dfcf58c11c90e090e4593b35def8a86/httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2", size = 75785 }, - { url = "https://files.pythonhosted.org/packages/d0/a4/b503851c40f20bcbd453db24ed35d961f62abdae0dccc8f672cd5d350d87/httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90", size = 345396 }, - { url = "https://files.pythonhosted.org/packages/a2/9a/aa406864f3108e06f7320425a528ff8267124dead1fd72a3e9da2067f893/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", size = 344741 }, - { url = "https://files.pythonhosted.org/packages/cf/3a/3fd8dfb987c4247651baf2ac6f28e8e9f889d484ca1a41a9ad0f04dfe300/httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84", size = 345096 }, - { url = "https://files.pythonhosted.org/packages/80/01/379f6466d8e2edb861c1f44ccac255ed1f8a0d4c5c666a1ceb34caad7555/httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb", size = 343535 }, - { url = "https://files.pythonhosted.org/packages/d3/97/60860e9ee87a7d4712b98f7e1411730520053b9d69e9e42b0b9751809c17/httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949", size = 55660 }, +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121, upload_time = "2023-08-17T17:29:11.868Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941, upload_time = "2023-08-17T17:29:10.08Z" }, ] [[package]] -name = "httpx" -version = "0.28.1" +name = "click-didyoumean" +version = "0.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, + { name = "click" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +sdist = { url = "https://files.pythonhosted.org/packages/30/ce/217289b77c590ea1e7c24242d9ddd6e249e52c795ff10fac2c50062c48cb/click_didyoumean-0.3.1.tar.gz", hash = "sha256:4f82fdff0dbe64ef8ab2279bd6aa3f6a99c3b28c05aa09cbfc07c9d7fbb5a463", size = 3089, upload_time = "2024-03-24T08:22:07.499Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, + { url = "https://files.pythonhosted.org/packages/1b/5b/974430b5ffdb7a4f1941d13d83c64a0395114503cc357c6b9ae4ce5047ed/click_didyoumean-0.3.1-py3-none-any.whl", hash = "sha256:5c4bb6007cfea5f2fd6583a2fb6701a22a41eb98957e63d0fac41c10e7c3117c", size = 3631, upload_time = "2024-03-24T08:22:06.356Z" }, ] [[package]] -name = "identify" -version = "2.6.1" +name = "click-plugins" +version = "1.1.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/29/bb/25024dbcc93516c492b75919e76f389bac754a3e4248682fba32b250c880/identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98", size = 99097 } +dependencies = [ + { name = "click" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c3/a4/34847b59150da33690a36da3681d6bbc2ec14ee9a846bc30a6746e5984e4/click_plugins-1.1.1.2.tar.gz", hash = "sha256:d7af3984a99d243c131aa1a828331e7630f4a88a9741fd05c927b204bcf92261", size = 8343, upload_time = "2025-06-25T00:47:37.555Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7d/0c/4ef72754c050979fdcc06c744715ae70ea37e734816bb6514f79df77a42f/identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0", size = 98972 }, + { url = "https://files.pythonhosted.org/packages/3d/9a/2abecb28ae875e39c8cad711eb1186d8d14eab564705325e77e4e6ab9ae5/click_plugins-1.1.1.2-py2.py3-none-any.whl", hash = "sha256:008d65743833ffc1f5417bf0e78e8d2c23aab04d9745ba817bd3e71b0feb6aa6", size = 11051, upload_time = "2025-06-25T00:47:36.731Z" }, ] [[package]] -name = "idna" -version = "3.10" +name = "click-repl" +version = "0.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +dependencies = [ + { name = "click" }, + { name = "prompt-toolkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/a2/57f4ac79838cfae6912f997b4d1a64a858fb0c86d7fcaae6f7b58d267fca/click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9", size = 10449, upload_time = "2023-06-15T12:43:51.141Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, + { url = "https://files.pythonhosted.org/packages/52/40/9d857001228658f0d59e97ebd4c346fe73e138c6de1bce61dc568a57c7f8/click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812", size = 10289, upload_time = "2023-06-15T12:43:48.626Z" }, ] [[package]] -name = "iniconfig" -version = "2.0.0" +name = "cloudpathlib" +version = "0.21.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/15/ae3256348834b92b9594d73eb7230538bae2bf726c2d721b920a668017c5/cloudpathlib-0.21.1.tar.gz", hash = "sha256:f26a855abf34d98f267aafd15efdb2db3c9665913dbabe5fad079df92837a431", size = 45295, upload_time = "2025-05-15T02:32:05.42Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, + { url = "https://files.pythonhosted.org/packages/40/e7/6fea57b887f8e367c1e4a496ba03bfaf57824b766f777723ce1faf28834b/cloudpathlib-0.21.1-py3-none-any.whl", hash = "sha256:bfe580ad72ec030472ec233cd7380701b2d3227da7b2898387bd170aa70c803c", size = 52776, upload_time = "2025-05-15T02:32:03.99Z" }, ] [[package]] -name = "jinja2" -version = "3.1.6" +name = "cmudict" +version = "1.0.33" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "markupsafe" }, + { name = "importlib-metadata" }, + { name = "importlib-resources" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } +sdist = { url = "https://files.pythonhosted.org/packages/34/32/68e3162cb1d6b1678811893bd26c9d46ae0a3f6ada8737868c70b1d30785/cmudict-1.0.33.tar.gz", hash = "sha256:f4c463c8406a2414f9f9058d60e45a7ce69081892ce27102dc91dc1bc6f92115", size = 935502, upload_time = "2025-07-04T20:35:01.648Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, + { url = "https://files.pythonhosted.org/packages/ec/b7/2b227c35949f33a0986a18a0e4830751254e7338062b5b1f10255bca9e21/cmudict-1.0.33-py3-none-any.whl", hash = "sha256:a9e9e7067caaa71a10dd10f3a4821223840529f00961d65163c9041c76759953", size = 939425, upload_time = "2025-07-04T20:35:00.131Z" }, ] [[package]] -name = "lxml" -version = "5.3.0" +name = "colorama" +version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/6b/20c3a4b24751377aaa6307eb230b66701024012c29dd374999cc92983269/lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f", size = 3679318 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/ce/2789e39eddf2b13fac29878bfa465f0910eb6b0096e29090e5176bc8cf43/lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656", size = 8124570 }, - { url = "https://files.pythonhosted.org/packages/24/a8/f4010166a25d41715527129af2675981a50d3bbf7df09c5d9ab8ca24fbf9/lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d", size = 4413042 }, - { url = "https://files.pythonhosted.org/packages/41/a4/7e45756cecdd7577ddf67a68b69c1db0f5ddbf0c9f65021ee769165ffc5a/lxml-5.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a", size = 5139213 }, - { url = "https://files.pythonhosted.org/packages/02/e2/ecf845b12323c92748077e1818b64e8b4dba509a4cb12920b3762ebe7552/lxml-5.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8", size = 4838814 }, - { url = "https://files.pythonhosted.org/packages/12/91/619f9fb72cf75e9ceb8700706f7276f23995f6ad757e6d400fbe35ca4990/lxml-5.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330", size = 5425084 }, - { url = "https://files.pythonhosted.org/packages/25/3b/162a85a8f0fd2a3032ec3f936636911c6e9523a8e263fffcfd581ce98b54/lxml-5.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965", size = 4875993 }, - { url = "https://files.pythonhosted.org/packages/43/af/dd3f58cc7d946da6ae42909629a2b1d5dd2d1b583334d4af9396697d6863/lxml-5.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22", size = 5012462 }, - { url = "https://files.pythonhosted.org/packages/69/c1/5ea46b2d4c98f5bf5c83fffab8a0ad293c9bc74df9ecfbafef10f77f7201/lxml-5.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b", size = 4815288 }, - { url = "https://files.pythonhosted.org/packages/1d/51/a0acca077ad35da458f4d3f729ef98effd2b90f003440d35fc36323f8ae6/lxml-5.3.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7", size = 5472435 }, - { url = "https://files.pythonhosted.org/packages/4d/6b/0989c9368986961a6b0f55b46c80404c4b758417acdb6d87bfc3bd5f4967/lxml-5.3.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8", size = 4976354 }, - { url = "https://files.pythonhosted.org/packages/05/9e/87492d03ff604fbf656ed2bf3e2e8d28f5d58ea1f00ff27ac27b06509079/lxml-5.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32", size = 5029973 }, - { url = "https://files.pythonhosted.org/packages/f9/cc/9ae1baf5472af88e19e2c454b3710c1be9ecafb20eb474eeabcd88a055d2/lxml-5.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86", size = 4888837 }, - { url = "https://files.pythonhosted.org/packages/d2/10/5594ffaec8c120d75b17e3ad23439b740a51549a9b5fd7484b2179adfe8f/lxml-5.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5", size = 5530555 }, - { url = "https://files.pythonhosted.org/packages/ea/9b/de17f05377c8833343b629905571fb06cff2028f15a6f58ae2267662e341/lxml-5.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03", size = 5405314 }, - { url = "https://files.pythonhosted.org/packages/8a/b4/227be0f1f3cca8255925985164c3838b8b36e441ff0cc10c1d3c6bdba031/lxml-5.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7", size = 5079303 }, - { url = "https://files.pythonhosted.org/packages/5c/ee/19abcebb7fc40319bb71cd6adefa1ad94d09b5660228715854d6cc420713/lxml-5.3.0-cp310-cp310-win32.whl", hash = "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80", size = 3475126 }, - { url = "https://files.pythonhosted.org/packages/a1/35/183d32551447e280032b2331738cd850da435a42f850b71ebeaab42c1313/lxml-5.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3", size = 3805065 }, - { url = "https://files.pythonhosted.org/packages/5c/a8/449faa2a3cbe6a99f8d38dcd51a3ee8844c17862841a6f769ea7c2a9cd0f/lxml-5.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b", size = 8141056 }, - { url = "https://files.pythonhosted.org/packages/ac/8a/ae6325e994e2052de92f894363b038351c50ee38749d30cc6b6d96aaf90f/lxml-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18", size = 4425238 }, - { url = "https://files.pythonhosted.org/packages/f8/fb/128dddb7f9086236bce0eeae2bfb316d138b49b159f50bc681d56c1bdd19/lxml-5.3.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442", size = 5095197 }, - { url = "https://files.pythonhosted.org/packages/b4/f9/a181a8ef106e41e3086629c8bdb2d21a942f14c84a0e77452c22d6b22091/lxml-5.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4", size = 4809809 }, - { url = "https://files.pythonhosted.org/packages/25/2f/b20565e808f7f6868aacea48ddcdd7e9e9fb4c799287f21f1a6c7c2e8b71/lxml-5.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f", size = 5407593 }, - { url = "https://files.pythonhosted.org/packages/23/0e/caac672ec246d3189a16c4d364ed4f7d6bf856c080215382c06764058c08/lxml-5.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e", size = 4866657 }, - { url = "https://files.pythonhosted.org/packages/67/a4/1f5fbd3f58d4069000522196b0b776a014f3feec1796da03e495cf23532d/lxml-5.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c", size = 4967017 }, - { url = "https://files.pythonhosted.org/packages/ee/73/623ecea6ca3c530dd0a4ed0d00d9702e0e85cd5624e2d5b93b005fe00abd/lxml-5.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16", size = 4810730 }, - { url = "https://files.pythonhosted.org/packages/1d/ce/fb84fb8e3c298f3a245ae3ea6221c2426f1bbaa82d10a88787412a498145/lxml-5.3.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79", size = 5455154 }, - { url = "https://files.pythonhosted.org/packages/b1/72/4d1ad363748a72c7c0411c28be2b0dc7150d91e823eadad3b91a4514cbea/lxml-5.3.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080", size = 4969416 }, - { url = "https://files.pythonhosted.org/packages/42/07/b29571a58a3a80681722ea8ed0ba569211d9bb8531ad49b5cacf6d409185/lxml-5.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654", size = 5013672 }, - { url = "https://files.pythonhosted.org/packages/b9/93/bde740d5a58cf04cbd38e3dd93ad1e36c2f95553bbf7d57807bc6815d926/lxml-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d", size = 4878644 }, - { url = "https://files.pythonhosted.org/packages/56/b5/645c8c02721d49927c93181de4017164ec0e141413577687c3df8ff0800f/lxml-5.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763", size = 5511531 }, - { url = "https://files.pythonhosted.org/packages/85/3f/6a99a12d9438316f4fc86ef88c5d4c8fb674247b17f3173ecadd8346b671/lxml-5.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec", size = 5402065 }, - { url = "https://files.pythonhosted.org/packages/80/8a/df47bff6ad5ac57335bf552babfb2408f9eb680c074ec1ba412a1a6af2c5/lxml-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be", size = 5069775 }, - { url = "https://files.pythonhosted.org/packages/08/ae/e7ad0f0fbe4b6368c5ee1e3ef0c3365098d806d42379c46c1ba2802a52f7/lxml-5.3.0-cp311-cp311-win32.whl", hash = "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9", size = 3474226 }, - { url = "https://files.pythonhosted.org/packages/c3/b5/91c2249bfac02ee514ab135e9304b89d55967be7e53e94a879b74eec7a5c/lxml-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1", size = 3814971 }, - { url = "https://files.pythonhosted.org/packages/eb/6d/d1f1c5e40c64bf62afd7a3f9b34ce18a586a1cccbf71e783cd0a6d8e8971/lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859", size = 8171753 }, - { url = "https://files.pythonhosted.org/packages/bd/83/26b1864921869784355459f374896dcf8b44d4af3b15d7697e9156cb2de9/lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e", size = 4441955 }, - { url = "https://files.pythonhosted.org/packages/e0/d2/e9bff9fb359226c25cda3538f664f54f2804f4b37b0d7c944639e1a51f69/lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f", size = 5050778 }, - { url = "https://files.pythonhosted.org/packages/88/69/6972bfafa8cd3ddc8562b126dd607011e218e17be313a8b1b9cc5a0ee876/lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e", size = 4748628 }, - { url = "https://files.pythonhosted.org/packages/5d/ea/a6523c7c7f6dc755a6eed3d2f6d6646617cad4d3d6d8ce4ed71bfd2362c8/lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179", size = 5322215 }, - { url = "https://files.pythonhosted.org/packages/99/37/396fbd24a70f62b31d988e4500f2068c7f3fd399d2fd45257d13eab51a6f/lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a", size = 4813963 }, - { url = "https://files.pythonhosted.org/packages/09/91/e6136f17459a11ce1757df864b213efbeab7adcb2efa63efb1b846ab6723/lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3", size = 4923353 }, - { url = "https://files.pythonhosted.org/packages/1d/7c/2eeecf87c9a1fca4f84f991067c693e67340f2b7127fc3eca8fa29d75ee3/lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1", size = 4740541 }, - { url = "https://files.pythonhosted.org/packages/3b/ed/4c38ba58defca84f5f0d0ac2480fdcd99fc7ae4b28fc417c93640a6949ae/lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d", size = 5346504 }, - { url = "https://files.pythonhosted.org/packages/a5/22/bbd3995437e5745cb4c2b5d89088d70ab19d4feabf8a27a24cecb9745464/lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c", size = 4898077 }, - { url = "https://files.pythonhosted.org/packages/0a/6e/94537acfb5b8f18235d13186d247bca478fea5e87d224644e0fe907df976/lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99", size = 4946543 }, - { url = "https://files.pythonhosted.org/packages/8d/e8/4b15df533fe8e8d53363b23a41df9be907330e1fa28c7ca36893fad338ee/lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff", size = 4816841 }, - { url = "https://files.pythonhosted.org/packages/1a/e7/03f390ea37d1acda50bc538feb5b2bda6745b25731e4e76ab48fae7106bf/lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a", size = 5417341 }, - { url = "https://files.pythonhosted.org/packages/ea/99/d1133ab4c250da85a883c3b60249d3d3e7c64f24faff494cf0fd23f91e80/lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8", size = 5327539 }, - { url = "https://files.pythonhosted.org/packages/7d/ed/e6276c8d9668028213df01f598f385b05b55a4e1b4662ee12ef05dab35aa/lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d", size = 5012542 }, - { url = "https://files.pythonhosted.org/packages/36/88/684d4e800f5aa28df2a991a6a622783fb73cf0e46235cfa690f9776f032e/lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30", size = 3486454 }, - { url = "https://files.pythonhosted.org/packages/fc/82/ace5a5676051e60355bd8fb945df7b1ba4f4fb8447f2010fb816bfd57724/lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f", size = 3816857 }, - { url = "https://files.pythonhosted.org/packages/94/6a/42141e4d373903bfea6f8e94b2f554d05506dfda522ada5343c651410dc8/lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a", size = 8156284 }, - { url = "https://files.pythonhosted.org/packages/91/5e/fa097f0f7d8b3d113fb7312c6308af702f2667f22644441715be961f2c7e/lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd", size = 4432407 }, - { url = "https://files.pythonhosted.org/packages/2d/a1/b901988aa6d4ff937f2e5cfc114e4ec561901ff00660c3e56713642728da/lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51", size = 5048331 }, - { url = "https://files.pythonhosted.org/packages/30/0f/b2a54f48e52de578b71bbe2a2f8160672a8a5e103df3a78da53907e8c7ed/lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b", size = 4744835 }, - { url = "https://files.pythonhosted.org/packages/82/9d/b000c15538b60934589e83826ecbc437a1586488d7c13f8ee5ff1f79a9b8/lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002", size = 5316649 }, - { url = "https://files.pythonhosted.org/packages/e3/ee/ffbb9eaff5e541922611d2c56b175c45893d1c0b8b11e5a497708a6a3b3b/lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4", size = 4812046 }, - { url = "https://files.pythonhosted.org/packages/15/ff/7ff89d567485c7b943cdac316087f16b2399a8b997007ed352a1248397e5/lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492", size = 4918597 }, - { url = "https://files.pythonhosted.org/packages/c6/a3/535b6ed8c048412ff51268bdf4bf1cf052a37aa7e31d2e6518038a883b29/lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3", size = 4738071 }, - { url = "https://files.pythonhosted.org/packages/7a/8f/cbbfa59cb4d4fd677fe183725a76d8c956495d7a3c7f111ab8f5e13d2e83/lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4", size = 5342213 }, - { url = "https://files.pythonhosted.org/packages/5c/fb/db4c10dd9958d4b52e34d1d1f7c1f434422aeaf6ae2bbaaff2264351d944/lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367", size = 4893749 }, - { url = "https://files.pythonhosted.org/packages/f2/38/bb4581c143957c47740de18a3281a0cab7722390a77cc6e610e8ebf2d736/lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832", size = 4945901 }, - { url = "https://files.pythonhosted.org/packages/fc/d5/18b7de4960c731e98037bd48fa9f8e6e8f2558e6fbca4303d9b14d21ef3b/lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff", size = 4815447 }, - { url = "https://files.pythonhosted.org/packages/97/a8/cd51ceaad6eb849246559a8ef60ae55065a3df550fc5fcd27014361c1bab/lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd", size = 5411186 }, - { url = "https://files.pythonhosted.org/packages/89/c3/1e3dabab519481ed7b1fdcba21dcfb8832f57000733ef0e71cf6d09a5e03/lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb", size = 5324481 }, - { url = "https://files.pythonhosted.org/packages/b6/17/71e9984cf0570cd202ac0a1c9ed5c1b8889b0fc8dc736f5ef0ffb181c284/lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b", size = 5011053 }, - { url = "https://files.pythonhosted.org/packages/69/68/9f7e6d3312a91e30829368c2b3217e750adef12a6f8eb10498249f4e8d72/lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957", size = 3485634 }, - { url = "https://files.pythonhosted.org/packages/7d/db/214290d58ad68c587bd5d6af3d34e56830438733d0d0856c0275fde43652/lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d", size = 3814417 }, - { url = "https://files.pythonhosted.org/packages/99/f7/b73a431c8500565aa500e99e60b448d305eaf7c0b4c893c7c5a8a69cc595/lxml-5.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c", size = 3925431 }, - { url = "https://files.pythonhosted.org/packages/db/48/4a206623c0d093d0e3b15f415ffb4345b0bdf661a3d0b15a112948c033c7/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a", size = 4216683 }, - { url = "https://files.pythonhosted.org/packages/54/47/577820c45dd954523ae8453b632d91e76da94ca6d9ee40d8c98dd86f916b/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005", size = 4326732 }, - { url = "https://files.pythonhosted.org/packages/68/de/96cb6d3269bc994b4f5ede8ca7bf0840f5de0a278bc6e50cb317ff71cafa/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce", size = 4218377 }, - { url = "https://files.pythonhosted.org/packages/a5/43/19b1ef6cbffa4244a217f95cc5f41a6cb4720fed33510a49670b03c5f1a0/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83", size = 4351237 }, - { url = "https://files.pythonhosted.org/packages/ba/b2/6a22fb5c0885da3b00e116aee81f0b829ec9ac8f736cd414b4a09413fc7d/lxml-5.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba", size = 3487557 }, +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload_time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload_time = "2022-10-25T02:36:20.889Z" }, ] [[package]] -name = "mako" -version = "1.3.5" +name = "coloredlogs" +version = "15.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "markupsafe" }, + { name = "humanfriendly" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/67/03/fb5ba97ff65ce64f6d35b582aacffc26b693a98053fa831ab43a437cbddb/Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc", size = 392738 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520, upload_time = "2021-06-11T10:22:45.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/62/70f5a0c2dd208f9f3f2f9afd103aec42ee4d9ad2401d78342f75e9b8da36/Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", size = 78565 }, + { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018, upload_time = "2021-06-11T10:22:42.561Z" }, ] [[package]] -name = "markdown-it-py" -version = "3.0.0" +name = "confection" +version = "0.1.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "mdurl" }, + { name = "pydantic" }, + { name = "srsly" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +sdist = { url = "https://files.pythonhosted.org/packages/51/d3/57c6631159a1b48d273b40865c315cf51f89df7a9d1101094ef12e3a37c2/confection-0.1.5.tar.gz", hash = "sha256:8e72dd3ca6bd4f48913cd220f10b8275978e740411654b6e8ca6d7008c590f0e", size = 38924, upload_time = "2024-05-31T16:17:01.559Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, + { url = "https://files.pythonhosted.org/packages/0c/00/3106b1854b45bd0474ced037dfe6b73b90fe68a68968cef47c23de3d43d2/confection-0.1.5-py3-none-any.whl", hash = "sha256:e29d3c3f8eac06b3f77eb9dfb4bf2fc6bcc9622a98ca00a698e3d019c6430b14", size = 35451, upload_time = "2024-05-31T16:16:59.075Z" }, ] [[package]] -name = "markupsafe" -version = "2.1.5" +name = "coverage" +version = "7.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/54/ad5eb37bf9d51800010a74e4665425831a9db4e7c4e0fde4352e391e808e/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", size = 18206 }, - { url = "https://files.pythonhosted.org/packages/6a/4a/a4d49415e600bacae038c67f9fecc1d5433b9d3c71a4de6f33537b89654c/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", size = 14079 }, - { url = "https://files.pythonhosted.org/packages/0a/7b/85681ae3c33c385b10ac0f8dd025c30af83c78cec1c37a6aa3b55e67f5ec/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", size = 26620 }, - { url = "https://files.pythonhosted.org/packages/7c/52/2b1b570f6b8b803cef5ac28fdf78c0da318916c7d2fe9402a84d591b394c/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", size = 25818 }, - { url = "https://files.pythonhosted.org/packages/29/fe/a36ba8c7ca55621620b2d7c585313efd10729e63ef81e4e61f52330da781/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", size = 25493 }, - { url = "https://files.pythonhosted.org/packages/60/ae/9c60231cdfda003434e8bd27282b1f4e197ad5a710c14bee8bea8a9ca4f0/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", size = 30630 }, - { url = "https://files.pythonhosted.org/packages/65/dc/1510be4d179869f5dafe071aecb3f1f41b45d37c02329dfba01ff59e5ac5/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", size = 29745 }, - { url = "https://files.pythonhosted.org/packages/30/39/8d845dd7d0b0613d86e0ef89549bfb5f61ed781f59af45fc96496e897f3a/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", size = 30021 }, - { url = "https://files.pythonhosted.org/packages/c7/5c/356a6f62e4f3c5fbf2602b4771376af22a3b16efa74eb8716fb4e328e01e/MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", size = 16659 }, - { url = "https://files.pythonhosted.org/packages/69/48/acbf292615c65f0604a0c6fc402ce6d8c991276e16c80c46a8f758fbd30c/MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", size = 17213 }, - { url = "https://files.pythonhosted.org/packages/11/e7/291e55127bb2ae67c64d66cef01432b5933859dfb7d6949daa721b89d0b3/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", size = 18219 }, - { url = "https://files.pythonhosted.org/packages/6b/cb/aed7a284c00dfa7c0682d14df85ad4955a350a21d2e3b06d8240497359bf/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", size = 14098 }, - { url = "https://files.pythonhosted.org/packages/1c/cf/35fe557e53709e93feb65575c93927942087e9b97213eabc3fe9d5b25a55/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", size = 29014 }, - { url = "https://files.pythonhosted.org/packages/97/18/c30da5e7a0e7f4603abfc6780574131221d9148f323752c2755d48abad30/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", size = 28220 }, - { url = "https://files.pythonhosted.org/packages/0c/40/2e73e7d532d030b1e41180807a80d564eda53babaf04d65e15c1cf897e40/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", size = 27756 }, - { url = "https://files.pythonhosted.org/packages/18/46/5dca760547e8c59c5311b332f70605d24c99d1303dd9a6e1fc3ed0d73561/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", size = 33988 }, - { url = "https://files.pythonhosted.org/packages/6d/c5/27febe918ac36397919cd4a67d5579cbbfa8da027fa1238af6285bb368ea/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", size = 32718 }, - { url = "https://files.pythonhosted.org/packages/f8/81/56e567126a2c2bc2684d6391332e357589a96a76cb9f8e5052d85cb0ead8/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", size = 33317 }, - { url = "https://files.pythonhosted.org/packages/00/0b/23f4b2470accb53285c613a3ab9ec19dc944eaf53592cb6d9e2af8aa24cc/MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", size = 16670 }, - { url = "https://files.pythonhosted.org/packages/b7/a2/c78a06a9ec6d04b3445a949615c4c7ed86a0b2eb68e44e7541b9d57067cc/MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", size = 17224 }, - { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215 }, - { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069 }, - { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452 }, - { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462 }, - { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869 }, - { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906 }, - { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296 }, - { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038 }, - { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572 }, - { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127 }, +sdist = { url = "https://files.pythonhosted.org/packages/f7/08/7e37f82e4d1aead42a7443ff06a1e406aabf7302c4f00a546e4b320b994c/coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", size = 798791, upload_time = "2024-08-04T19:45:30.9Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/61/eb7ce5ed62bacf21beca4937a90fe32545c91a3c8a42a30c6616d48fc70d/coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", size = 206690, upload_time = "2024-08-04T19:43:07.695Z" }, + { url = "https://files.pythonhosted.org/packages/7d/73/041928e434442bd3afde5584bdc3f932fb4562b1597629f537387cec6f3d/coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", size = 207127, upload_time = "2024-08-04T19:43:10.15Z" }, + { url = "https://files.pythonhosted.org/packages/c7/c8/6ca52b5147828e45ad0242388477fdb90df2c6cbb9a441701a12b3c71bc8/coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", size = 235654, upload_time = "2024-08-04T19:43:12.405Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/9ac2b62557f4340270942011d6efeab9833648380109e897d48ab7c1035d/coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc", size = 233598, upload_time = "2024-08-04T19:43:14.078Z" }, + { url = "https://files.pythonhosted.org/packages/53/23/9e2c114d0178abc42b6d8d5281f651a8e6519abfa0ef460a00a91f80879d/coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", size = 234732, upload_time = "2024-08-04T19:43:16.632Z" }, + { url = "https://files.pythonhosted.org/packages/0f/7e/a0230756fb133343a52716e8b855045f13342b70e48e8ad41d8a0d60ab98/coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", size = 233816, upload_time = "2024-08-04T19:43:19.049Z" }, + { url = "https://files.pythonhosted.org/packages/28/7c/3753c8b40d232b1e5eeaed798c875537cf3cb183fb5041017c1fdb7ec14e/coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", size = 232325, upload_time = "2024-08-04T19:43:21.246Z" }, + { url = "https://files.pythonhosted.org/packages/57/e3/818a2b2af5b7573b4b82cf3e9f137ab158c90ea750a8f053716a32f20f06/coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", size = 233418, upload_time = "2024-08-04T19:43:22.945Z" }, + { url = "https://files.pythonhosted.org/packages/c8/fb/4532b0b0cefb3f06d201648715e03b0feb822907edab3935112b61b885e2/coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", size = 209343, upload_time = "2024-08-04T19:43:25.121Z" }, + { url = "https://files.pythonhosted.org/packages/5a/25/af337cc7421eca1c187cc9c315f0a755d48e755d2853715bfe8c418a45fa/coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", size = 210136, upload_time = "2024-08-04T19:43:26.851Z" }, + { url = "https://files.pythonhosted.org/packages/ad/5f/67af7d60d7e8ce61a4e2ddcd1bd5fb787180c8d0ae0fbd073f903b3dd95d/coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", size = 206796, upload_time = "2024-08-04T19:43:29.115Z" }, + { url = "https://files.pythonhosted.org/packages/e1/0e/e52332389e057daa2e03be1fbfef25bb4d626b37d12ed42ae6281d0a274c/coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", size = 207244, upload_time = "2024-08-04T19:43:31.285Z" }, + { url = "https://files.pythonhosted.org/packages/aa/cd/766b45fb6e090f20f8927d9c7cb34237d41c73a939358bc881883fd3a40d/coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", size = 239279, upload_time = "2024-08-04T19:43:33.581Z" }, + { url = "https://files.pythonhosted.org/packages/70/6c/a9ccd6fe50ddaf13442a1e2dd519ca805cbe0f1fcd377fba6d8339b98ccb/coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", size = 236859, upload_time = "2024-08-04T19:43:35.301Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/8351b465febb4dbc1ca9929505202db909c5a635c6fdf33e089bbc3d7d85/coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", size = 238549, upload_time = "2024-08-04T19:43:37.578Z" }, + { url = "https://files.pythonhosted.org/packages/68/3c/289b81fa18ad72138e6d78c4c11a82b5378a312c0e467e2f6b495c260907/coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", size = 237477, upload_time = "2024-08-04T19:43:39.92Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1c/aa1efa6459d822bd72c4abc0b9418cf268de3f60eeccd65dc4988553bd8d/coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", size = 236134, upload_time = "2024-08-04T19:43:41.453Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c8/521c698f2d2796565fe9c789c2ee1ccdae610b3aa20b9b2ef980cc253640/coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", size = 236910, upload_time = "2024-08-04T19:43:43.037Z" }, + { url = "https://files.pythonhosted.org/packages/7d/30/033e663399ff17dca90d793ee8a2ea2890e7fdf085da58d82468b4220bf7/coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", size = 209348, upload_time = "2024-08-04T19:43:44.787Z" }, + { url = "https://files.pythonhosted.org/packages/20/05/0d1ccbb52727ccdadaa3ff37e4d2dc1cd4d47f0c3df9eb58d9ec8508ca88/coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", size = 210230, upload_time = "2024-08-04T19:43:46.707Z" }, + { url = "https://files.pythonhosted.org/packages/7e/d4/300fc921dff243cd518c7db3a4c614b7e4b2431b0d1145c1e274fd99bd70/coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", size = 206983, upload_time = "2024-08-04T19:43:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/e1/ab/6bf00de5327ecb8db205f9ae596885417a31535eeda6e7b99463108782e1/coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", size = 207221, upload_time = "2024-08-04T19:43:52.15Z" }, + { url = "https://files.pythonhosted.org/packages/92/8f/2ead05e735022d1a7f3a0a683ac7f737de14850395a826192f0288703472/coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", size = 240342, upload_time = "2024-08-04T19:43:53.746Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/94043e478201ffa85b8ae2d2c79b4081e5a1b73438aafafccf3e9bafb6b5/coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", size = 237371, upload_time = "2024-08-04T19:43:55.993Z" }, + { url = "https://files.pythonhosted.org/packages/1f/0f/c890339dd605f3ebc269543247bdd43b703cce6825b5ed42ff5f2d6122c7/coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", size = 239455, upload_time = "2024-08-04T19:43:57.618Z" }, + { url = "https://files.pythonhosted.org/packages/d1/04/7fd7b39ec7372a04efb0f70c70e35857a99b6a9188b5205efb4c77d6a57a/coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", size = 238924, upload_time = "2024-08-04T19:44:00.012Z" }, + { url = "https://files.pythonhosted.org/packages/ed/bf/73ce346a9d32a09cf369f14d2a06651329c984e106f5992c89579d25b27e/coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", size = 237252, upload_time = "2024-08-04T19:44:01.713Z" }, + { url = "https://files.pythonhosted.org/packages/86/74/1dc7a20969725e917b1e07fe71a955eb34bc606b938316bcc799f228374b/coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", size = 238897, upload_time = "2024-08-04T19:44:03.898Z" }, + { url = "https://files.pythonhosted.org/packages/b6/e9/d9cc3deceb361c491b81005c668578b0dfa51eed02cd081620e9a62f24ec/coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", size = 209606, upload_time = "2024-08-04T19:44:05.532Z" }, + { url = "https://files.pythonhosted.org/packages/47/c8/5a2e41922ea6740f77d555c4d47544acd7dc3f251fe14199c09c0f5958d3/coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", size = 210373, upload_time = "2024-08-04T19:44:07.079Z" }, + { url = "https://files.pythonhosted.org/packages/8c/f9/9aa4dfb751cb01c949c990d136a0f92027fbcc5781c6e921df1cb1563f20/coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", size = 207007, upload_time = "2024-08-04T19:44:09.453Z" }, + { url = "https://files.pythonhosted.org/packages/b9/67/e1413d5a8591622a46dd04ff80873b04c849268831ed5c304c16433e7e30/coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", size = 207269, upload_time = "2024-08-04T19:44:11.045Z" }, + { url = "https://files.pythonhosted.org/packages/14/5b/9dec847b305e44a5634d0fb8498d135ab1d88330482b74065fcec0622224/coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", size = 239886, upload_time = "2024-08-04T19:44:12.83Z" }, + { url = "https://files.pythonhosted.org/packages/7b/b7/35760a67c168e29f454928f51f970342d23cf75a2bb0323e0f07334c85f3/coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", size = 237037, upload_time = "2024-08-04T19:44:15.393Z" }, + { url = "https://files.pythonhosted.org/packages/f7/95/d2fd31f1d638df806cae59d7daea5abf2b15b5234016a5ebb502c2f3f7ee/coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", size = 239038, upload_time = "2024-08-04T19:44:17.466Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bd/110689ff5752b67924efd5e2aedf5190cbbe245fc81b8dec1abaffba619d/coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", size = 238690, upload_time = "2024-08-04T19:44:19.336Z" }, + { url = "https://files.pythonhosted.org/packages/d3/a8/08d7b38e6ff8df52331c83130d0ab92d9c9a8b5462f9e99c9f051a4ae206/coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", size = 236765, upload_time = "2024-08-04T19:44:20.994Z" }, + { url = "https://files.pythonhosted.org/packages/d6/6a/9cf96839d3147d55ae713eb2d877f4d777e7dc5ba2bce227167d0118dfe8/coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", size = 238611, upload_time = "2024-08-04T19:44:22.616Z" }, + { url = "https://files.pythonhosted.org/packages/74/e4/7ff20d6a0b59eeaab40b3140a71e38cf52547ba21dbcf1d79c5a32bba61b/coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", size = 209671, upload_time = "2024-08-04T19:44:24.418Z" }, + { url = "https://files.pythonhosted.org/packages/35/59/1812f08a85b57c9fdb6d0b383d779e47b6f643bc278ed682859512517e83/coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", size = 210368, upload_time = "2024-08-04T19:44:26.276Z" }, + { url = "https://files.pythonhosted.org/packages/9c/15/08913be1c59d7562a3e39fce20661a98c0a3f59d5754312899acc6cb8a2d/coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", size = 207758, upload_time = "2024-08-04T19:44:29.028Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ae/b5d58dff26cade02ada6ca612a76447acd69dccdbb3a478e9e088eb3d4b9/coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", size = 208035, upload_time = "2024-08-04T19:44:30.673Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d7/62095e355ec0613b08dfb19206ce3033a0eedb6f4a67af5ed267a8800642/coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", size = 250839, upload_time = "2024-08-04T19:44:32.412Z" }, + { url = "https://files.pythonhosted.org/packages/7c/1e/c2967cb7991b112ba3766df0d9c21de46b476d103e32bb401b1b2adf3380/coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", size = 246569, upload_time = "2024-08-04T19:44:34.547Z" }, + { url = "https://files.pythonhosted.org/packages/8b/61/a7a6a55dd266007ed3b1df7a3386a0d760d014542d72f7c2c6938483b7bd/coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", size = 248927, upload_time = "2024-08-04T19:44:36.313Z" }, + { url = "https://files.pythonhosted.org/packages/c8/fa/13a6f56d72b429f56ef612eb3bc5ce1b75b7ee12864b3bd12526ab794847/coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", size = 248401, upload_time = "2024-08-04T19:44:38.155Z" }, + { url = "https://files.pythonhosted.org/packages/75/06/0429c652aa0fb761fc60e8c6b291338c9173c6aa0f4e40e1902345b42830/coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", size = 246301, upload_time = "2024-08-04T19:44:39.883Z" }, + { url = "https://files.pythonhosted.org/packages/52/76/1766bb8b803a88f93c3a2d07e30ffa359467810e5cbc68e375ebe6906efb/coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", size = 247598, upload_time = "2024-08-04T19:44:41.59Z" }, + { url = "https://files.pythonhosted.org/packages/66/8b/f54f8db2ae17188be9566e8166ac6df105c1c611e25da755738025708d54/coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", size = 210307, upload_time = "2024-08-04T19:44:43.301Z" }, + { url = "https://files.pythonhosted.org/packages/9f/b0/e0dca6da9170aefc07515cce067b97178cefafb512d00a87a1c717d2efd5/coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", size = 211453, upload_time = "2024-08-04T19:44:45.677Z" }, + { url = "https://files.pythonhosted.org/packages/a5/2b/0354ed096bca64dc8e32a7cbcae28b34cb5ad0b1fe2125d6d99583313ac0/coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", size = 198926, upload_time = "2024-08-04T19:45:28.875Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, ] [[package]] -name = "mdurl" -version = "0.1.2" +name = "cryptography" +version = "45.0.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/95/1e/49527ac611af559665f71cbb8f92b332b5ec9c6fbc4e88b0f8e92f5e85df/cryptography-45.0.5.tar.gz", hash = "sha256:72e76caa004ab63accdf26023fccd1d087f6d90ec6048ff33ad0445abf7f605a", size = 744903, upload_time = "2025-07-02T13:06:25.941Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, + { url = "https://files.pythonhosted.org/packages/f0/fb/09e28bc0c46d2c547085e60897fea96310574c70fb21cd58a730a45f3403/cryptography-45.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:101ee65078f6dd3e5a028d4f19c07ffa4dd22cce6a20eaa160f8b5219911e7d8", size = 7043092, upload_time = "2025-07-02T13:05:01.514Z" }, + { url = "https://files.pythonhosted.org/packages/b1/05/2194432935e29b91fb649f6149c1a4f9e6d3d9fc880919f4ad1bcc22641e/cryptography-45.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3a264aae5f7fbb089dbc01e0242d3b67dffe3e6292e1f5182122bdf58e65215d", size = 4205926, upload_time = "2025-07-02T13:05:04.741Z" }, + { url = "https://files.pythonhosted.org/packages/07/8b/9ef5da82350175e32de245646b1884fc01124f53eb31164c77f95a08d682/cryptography-45.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e74d30ec9c7cb2f404af331d5b4099a9b322a8a6b25c4632755c8757345baac5", size = 4429235, upload_time = "2025-07-02T13:05:07.084Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e1/c809f398adde1994ee53438912192d92a1d0fc0f2d7582659d9ef4c28b0c/cryptography-45.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3af26738f2db354aafe492fb3869e955b12b2ef2e16908c8b9cb928128d42c57", size = 4209785, upload_time = "2025-07-02T13:05:09.321Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8b/07eb6bd5acff58406c5e806eff34a124936f41a4fb52909ffa4d00815f8c/cryptography-45.0.5-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e6c00130ed423201c5bc5544c23359141660b07999ad82e34e7bb8f882bb78e0", size = 3893050, upload_time = "2025-07-02T13:05:11.069Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ef/3333295ed58d900a13c92806b67e62f27876845a9a908c939f040887cca9/cryptography-45.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d", size = 4457379, upload_time = "2025-07-02T13:05:13.32Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9d/44080674dee514dbb82b21d6fa5d1055368f208304e2ab1828d85c9de8f4/cryptography-45.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d05a38884db2ba215218745f0781775806bde4f32e07b135348355fe8e4991d9", size = 4209355, upload_time = "2025-07-02T13:05:15.017Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d8/0749f7d39f53f8258e5c18a93131919ac465ee1f9dccaf1b3f420235e0b5/cryptography-45.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:ad0caded895a00261a5b4aa9af828baede54638754b51955a0ac75576b831b27", size = 4456087, upload_time = "2025-07-02T13:05:16.945Z" }, + { url = "https://files.pythonhosted.org/packages/09/d7/92acac187387bf08902b0bf0699816f08553927bdd6ba3654da0010289b4/cryptography-45.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9024beb59aca9d31d36fcdc1604dd9bbeed0a55bface9f1908df19178e2f116e", size = 4332873, upload_time = "2025-07-02T13:05:18.743Z" }, + { url = "https://files.pythonhosted.org/packages/03/c2/840e0710da5106a7c3d4153c7215b2736151bba60bf4491bdb421df5056d/cryptography-45.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:91098f02ca81579c85f66df8a588c78f331ca19089763d733e34ad359f474174", size = 4564651, upload_time = "2025-07-02T13:05:21.382Z" }, + { url = "https://files.pythonhosted.org/packages/2e/92/cc723dd6d71e9747a887b94eb3827825c6c24b9e6ce2bb33b847d31d5eaa/cryptography-45.0.5-cp311-abi3-win32.whl", hash = "sha256:926c3ea71a6043921050eaa639137e13dbe7b4ab25800932a8498364fc1abec9", size = 2929050, upload_time = "2025-07-02T13:05:23.39Z" }, + { url = "https://files.pythonhosted.org/packages/1f/10/197da38a5911a48dd5389c043de4aec4b3c94cb836299b01253940788d78/cryptography-45.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:b85980d1e345fe769cfc57c57db2b59cff5464ee0c045d52c0df087e926fbe63", size = 3403224, upload_time = "2025-07-02T13:05:25.202Z" }, + { url = "https://files.pythonhosted.org/packages/fe/2b/160ce8c2765e7a481ce57d55eba1546148583e7b6f85514472b1d151711d/cryptography-45.0.5-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f3562c2f23c612f2e4a6964a61d942f891d29ee320edb62ff48ffb99f3de9ae8", size = 7017143, upload_time = "2025-07-02T13:05:27.229Z" }, + { url = "https://files.pythonhosted.org/packages/c2/e7/2187be2f871c0221a81f55ee3105d3cf3e273c0a0853651d7011eada0d7e/cryptography-45.0.5-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3fcfbefc4a7f332dece7272a88e410f611e79458fab97b5efe14e54fe476f4fd", size = 4197780, upload_time = "2025-07-02T13:05:29.299Z" }, + { url = "https://files.pythonhosted.org/packages/b9/cf/84210c447c06104e6be9122661159ad4ce7a8190011669afceeaea150524/cryptography-45.0.5-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:460f8c39ba66af7db0545a8c6f2eabcbc5a5528fc1cf6c3fa9a1e44cec33385e", size = 4420091, upload_time = "2025-07-02T13:05:31.221Z" }, + { url = "https://files.pythonhosted.org/packages/3e/6a/cb8b5c8bb82fafffa23aeff8d3a39822593cee6e2f16c5ca5c2ecca344f7/cryptography-45.0.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9b4cf6318915dccfe218e69bbec417fdd7c7185aa7aab139a2c0beb7468c89f0", size = 4198711, upload_time = "2025-07-02T13:05:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/04/f7/36d2d69df69c94cbb2473871926daf0f01ad8e00fe3986ac3c1e8c4ca4b3/cryptography-45.0.5-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2089cc8f70a6e454601525e5bf2779e665d7865af002a5dec8d14e561002e135", size = 3883299, upload_time = "2025-07-02T13:05:34.94Z" }, + { url = "https://files.pythonhosted.org/packages/82/c7/f0ea40f016de72f81288e9fe8d1f6748036cb5ba6118774317a3ffc6022d/cryptography-45.0.5-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0027d566d65a38497bc37e0dd7c2f8ceda73597d2ac9ba93810204f56f52ebc7", size = 4450558, upload_time = "2025-07-02T13:05:37.288Z" }, + { url = "https://files.pythonhosted.org/packages/06/ae/94b504dc1a3cdf642d710407c62e86296f7da9e66f27ab12a1ee6fdf005b/cryptography-45.0.5-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:be97d3a19c16a9be00edf79dca949c8fa7eff621763666a145f9f9535a5d7f42", size = 4198020, upload_time = "2025-07-02T13:05:39.102Z" }, + { url = "https://files.pythonhosted.org/packages/05/2b/aaf0adb845d5dabb43480f18f7ca72e94f92c280aa983ddbd0bcd6ecd037/cryptography-45.0.5-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:7760c1c2e1a7084153a0f68fab76e754083b126a47d0117c9ed15e69e2103492", size = 4449759, upload_time = "2025-07-02T13:05:41.398Z" }, + { url = "https://files.pythonhosted.org/packages/91/e4/f17e02066de63e0100a3a01b56f8f1016973a1d67551beaf585157a86b3f/cryptography-45.0.5-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6ff8728d8d890b3dda5765276d1bc6fb099252915a2cd3aff960c4c195745dd0", size = 4319991, upload_time = "2025-07-02T13:05:43.64Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2e/e2dbd629481b499b14516eed933f3276eb3239f7cee2dcfa4ee6b44d4711/cryptography-45.0.5-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7259038202a47fdecee7e62e0fd0b0738b6daa335354396c6ddebdbe1206af2a", size = 4554189, upload_time = "2025-07-02T13:05:46.045Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ea/a78a0c38f4c8736287b71c2ea3799d173d5ce778c7d6e3c163a95a05ad2a/cryptography-45.0.5-cp37-abi3-win32.whl", hash = "sha256:1e1da5accc0c750056c556a93c3e9cb828970206c68867712ca5805e46dc806f", size = 2911769, upload_time = "2025-07-02T13:05:48.329Z" }, + { url = "https://files.pythonhosted.org/packages/79/b3/28ac139109d9005ad3f6b6f8976ffede6706a6478e21c889ce36c840918e/cryptography-45.0.5-cp37-abi3-win_amd64.whl", hash = "sha256:90cb0a7bb35959f37e23303b7eed0a32280510030daba3f7fdfbb65defde6a97", size = 3390016, upload_time = "2025-07-02T13:05:50.811Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8b/34394337abe4566848a2bd49b26bcd4b07fd466afd3e8cce4cb79a390869/cryptography-45.0.5-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:206210d03c1193f4e1ff681d22885181d47efa1ab3018766a7b32a7b3d6e6afd", size = 3575762, upload_time = "2025-07-02T13:05:53.166Z" }, + { url = "https://files.pythonhosted.org/packages/8b/5d/a19441c1e89afb0f173ac13178606ca6fab0d3bd3ebc29e9ed1318b507fc/cryptography-45.0.5-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c648025b6840fe62e57107e0a25f604db740e728bd67da4f6f060f03017d5097", size = 4140906, upload_time = "2025-07-02T13:05:55.914Z" }, + { url = "https://files.pythonhosted.org/packages/4b/db/daceb259982a3c2da4e619f45b5bfdec0e922a23de213b2636e78ef0919b/cryptography-45.0.5-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b8fa8b0a35a9982a3c60ec79905ba5bb090fc0b9addcfd3dc2dd04267e45f25e", size = 4374411, upload_time = "2025-07-02T13:05:57.814Z" }, + { url = "https://files.pythonhosted.org/packages/6a/35/5d06ad06402fc522c8bf7eab73422d05e789b4e38fe3206a85e3d6966c11/cryptography-45.0.5-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:14d96584701a887763384f3c47f0ca7c1cce322aa1c31172680eb596b890ec30", size = 4140942, upload_time = "2025-07-02T13:06:00.137Z" }, + { url = "https://files.pythonhosted.org/packages/65/79/020a5413347e44c382ef1f7f7e7a66817cd6273e3e6b5a72d18177b08b2f/cryptography-45.0.5-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:57c816dfbd1659a367831baca4b775b2a5b43c003daf52e9d57e1d30bc2e1b0e", size = 4374079, upload_time = "2025-07-02T13:06:02.043Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c5/c0e07d84a9a2a8a0ed4f865e58f37c71af3eab7d5e094ff1b21f3f3af3bc/cryptography-45.0.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b9e38e0a83cd51e07f5a48ff9691cae95a79bea28fe4ded168a8e5c6c77e819d", size = 3321362, upload_time = "2025-07-02T13:06:04.463Z" }, + { url = "https://files.pythonhosted.org/packages/c0/71/9bdbcfd58d6ff5084687fe722c58ac718ebedbc98b9f8f93781354e6d286/cryptography-45.0.5-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8c4a6ff8a30e9e3d38ac0539e9a9e02540ab3f827a3394f8852432f6b0ea152e", size = 3587878, upload_time = "2025-07-02T13:06:06.339Z" }, + { url = "https://files.pythonhosted.org/packages/f0/63/83516cfb87f4a8756eaa4203f93b283fda23d210fc14e1e594bd5f20edb6/cryptography-45.0.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bd4c45986472694e5121084c6ebbd112aa919a25e783b87eb95953c9573906d6", size = 4152447, upload_time = "2025-07-02T13:06:08.345Z" }, + { url = "https://files.pythonhosted.org/packages/22/11/d2823d2a5a0bd5802b3565437add16f5c8ce1f0778bf3822f89ad2740a38/cryptography-45.0.5-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:982518cd64c54fcada9d7e5cf28eabd3ee76bd03ab18e08a48cad7e8b6f31b18", size = 4386778, upload_time = "2025-07-02T13:06:10.263Z" }, + { url = "https://files.pythonhosted.org/packages/5f/38/6bf177ca6bce4fe14704ab3e93627c5b0ca05242261a2e43ef3168472540/cryptography-45.0.5-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:12e55281d993a793b0e883066f590c1ae1e802e3acb67f8b442e721e475e6463", size = 4151627, upload_time = "2025-07-02T13:06:13.097Z" }, + { url = "https://files.pythonhosted.org/packages/38/6a/69fc67e5266bff68a91bcb81dff8fb0aba4d79a78521a08812048913e16f/cryptography-45.0.5-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:5aa1e32983d4443e310f726ee4b071ab7569f58eedfdd65e9675484a4eb67bd1", size = 4385593, upload_time = "2025-07-02T13:06:15.689Z" }, + { url = "https://files.pythonhosted.org/packages/f6/34/31a1604c9a9ade0fdab61eb48570e09a796f4d9836121266447b0eaf7feb/cryptography-45.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e357286c1b76403dd384d938f93c46b2b058ed4dfcdce64a770f0537ed3feb6f", size = 3331106, upload_time = "2025-07-02T13:06:18.058Z" }, ] [[package]] -name = "more-itertools" -version = "10.5.0" +name = "cssselect" +version = "1.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/78/65922308c4248e0eb08ebcbe67c95d48615cc6f27854b6f2e57143e9178f/more-itertools-10.5.0.tar.gz", hash = "sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6", size = 121020 } +sdist = { url = "https://files.pythonhosted.org/packages/d1/91/d51202cc41fbfca7fa332f43a5adac4b253962588c7cc5a54824b019081c/cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc", size = 41423, upload_time = "2022-10-27T13:25:41.71Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/7e/3a64597054a70f7c86eb0a7d4fc315b8c1ab932f64883a297bdffeb5f967/more_itertools-10.5.0-py3-none-any.whl", hash = "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", size = 60952 }, + { url = "https://files.pythonhosted.org/packages/06/a9/2da08717a6862c48f1d61ef957a7bba171e7eefa6c0aa0ceb96a140c2a6b/cssselect-1.2.0-py2.py3-none-any.whl", hash = "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e", size = 18687, upload_time = "2022-10-27T13:25:40.153Z" }, ] [[package]] -name = "mypy" -version = "1.11.2" +name = "cssutils" +version = "2.11.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "mypy-extensions" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions" }, + { name = "more-itertools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/86/5d7cbc4974fd564550b80fbb8103c05501ea11aa7835edf3351d90095896/mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79", size = 3078806 } +sdist = { url = "https://files.pythonhosted.org/packages/33/9f/329d26121fe165be44b1dfff21aa0dc348f04633931f1d20ed6cf448a236/cssutils-2.11.1.tar.gz", hash = "sha256:0563a76513b6af6eebbe788c3bf3d01c920e46b3f90c8416738c5cfc773ff8e2", size = 711657, upload_time = "2024-06-04T15:51:39.373Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/cd/815368cd83c3a31873e5e55b317551500b12f2d1d7549720632f32630333/mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a", size = 10939401 }, - { url = "https://files.pythonhosted.org/packages/f1/27/e18c93a195d2fad75eb96e1f1cbc431842c332e8eba2e2b77eaf7313c6b7/mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef", size = 10111697 }, - { url = "https://files.pythonhosted.org/packages/dc/08/cdc1fc6d0d5a67d354741344cc4aa7d53f7128902ebcbe699ddd4f15a61c/mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383", size = 12500508 }, - { url = "https://files.pythonhosted.org/packages/64/12/aad3af008c92c2d5d0720ea3b6674ba94a98cdb86888d389acdb5f218c30/mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8", size = 13020712 }, - { url = "https://files.pythonhosted.org/packages/03/e6/a7d97cc124a565be5e9b7d5c2a6ebf082379ffba99646e4863ed5bbcb3c3/mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7", size = 9567319 }, - { url = "https://files.pythonhosted.org/packages/e2/aa/cc56fb53ebe14c64f1fe91d32d838d6f4db948b9494e200d2f61b820b85d/mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385", size = 10859630 }, - { url = "https://files.pythonhosted.org/packages/04/c8/b19a760fab491c22c51975cf74e3d253b8c8ce2be7afaa2490fbf95a8c59/mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca", size = 10037973 }, - { url = "https://files.pythonhosted.org/packages/88/57/7e7e39f2619c8f74a22efb9a4c4eff32b09d3798335625a124436d121d89/mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104", size = 12416659 }, - { url = "https://files.pythonhosted.org/packages/fc/a6/37f7544666b63a27e46c48f49caeee388bf3ce95f9c570eb5cfba5234405/mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4", size = 12897010 }, - { url = "https://files.pythonhosted.org/packages/84/8b/459a513badc4d34acb31c736a0101c22d2bd0697b969796ad93294165cfb/mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6", size = 9562873 }, - { url = "https://files.pythonhosted.org/packages/35/3a/ed7b12ecc3f6db2f664ccf85cb2e004d3e90bec928e9d7be6aa2f16b7cdf/mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318", size = 10990335 }, - { url = "https://files.pythonhosted.org/packages/04/e4/1a9051e2ef10296d206519f1df13d2cc896aea39e8683302f89bf5792a59/mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36", size = 10007119 }, - { url = "https://files.pythonhosted.org/packages/f3/3c/350a9da895f8a7e87ade0028b962be0252d152e0c2fbaafa6f0658b4d0d4/mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987", size = 12506856 }, - { url = "https://files.pythonhosted.org/packages/b6/49/ee5adf6a49ff13f4202d949544d3d08abb0ea1f3e7f2a6d5b4c10ba0360a/mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca", size = 12952066 }, - { url = "https://files.pythonhosted.org/packages/27/c0/b19d709a42b24004d720db37446a42abadf844d5c46a2c442e2a074d70d9/mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70", size = 9664000 }, - { url = "https://files.pythonhosted.org/packages/42/3a/bdf730640ac523229dd6578e8a581795720a9321399de494374afc437ec5/mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12", size = 2619625 }, + { url = "https://files.pythonhosted.org/packages/a7/ec/bb273b7208c606890dc36540fe667d06ce840a6f62f9fae7e658fcdc90fb/cssutils-2.11.1-py3-none-any.whl", hash = "sha256:a67bfdfdff4f3867fab43698ec4897c1a828eca5973f4073321b3bccaf1199b1", size = 385747, upload_time = "2024-06-04T15:51:37.499Z" }, ] [[package]] -name = "mypy-extensions" -version = "1.0.0" +name = "cymem" +version = "2.0.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +sdist = { url = "https://files.pythonhosted.org/packages/f2/4a/1acd761fb6ac4c560e823ce40536a62f886f2d59b2763b5c3fc7e9d92101/cymem-2.0.11.tar.gz", hash = "sha256:efe49a349d4a518be6b6c6b255d4a80f740a341544bde1a807707c058b88d0bd", size = 10346, upload_time = "2025-01-16T21:50:41.045Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, + { url = "https://files.pythonhosted.org/packages/6d/55/f453f2b2f560e057f20eb2acdaafbf6488d72a6e8a36a4aef30f6053a51c/cymem-2.0.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1b4dd8f8c2475c7c9948eefa89c790d83134600858d8d43b90276efd8df3882e", size = 41886, upload_time = "2025-01-16T21:49:17.183Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9d/03299eff35bd4fd80db33e4fd516661b82bb7b898cb677829acf22391ede/cymem-2.0.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d46ba0d2e0f749195297d16f2286b55af7d7c084db2b853fdfccece2c000c5dc", size = 41696, upload_time = "2025-01-16T21:49:18.788Z" }, + { url = "https://files.pythonhosted.org/packages/d3/0c/90aa41f258a67ea210886c5c73f88dc9f120b7a20e6b5d92c5ce73a68276/cymem-2.0.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:739c4336b9d04ce9761851e9260ef77508d4a86ee3060e41302bfb6fa82c37de", size = 203719, upload_time = "2025-01-16T21:49:23.13Z" }, + { url = "https://files.pythonhosted.org/packages/52/d1/dc4a72aa2049c34a53a220290b1a59fadae61929dff3a6e1a830a22971fe/cymem-2.0.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a69c470c2fb118161f49761f9137384f46723c77078b659bba33858e19e46b49", size = 204763, upload_time = "2025-01-16T21:49:26.164Z" }, + { url = "https://files.pythonhosted.org/packages/69/51/86ed323585530558bcdda1324c570abe032db2c1d5afd1c5e8e3e8fde63a/cymem-2.0.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:40159f6c92627438de970fd761916e745d70dfd84a7dcc28c1627eb49cee00d8", size = 193964, upload_time = "2025-01-16T21:49:28.057Z" }, + { url = "https://files.pythonhosted.org/packages/ed/0c/aee4ad2996a4e24342228ccf44d7835c7784042f0ee0c47ad33be1443f18/cymem-2.0.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f503f98e6aa333fffbe657a6854f13a9c3de68860795ae21171284213b9c5c09", size = 195002, upload_time = "2025-01-16T21:49:31.329Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d5/eda823d639258d2ed1db83403c991a9a57d5a4ddea3bf08e59060809a9aa/cymem-2.0.11-cp310-cp310-win_amd64.whl", hash = "sha256:7f05ed5920cc92d6b958ec5da55bd820d326fe9332b90660e6fa67e3b476ceb1", size = 39079, upload_time = "2025-01-16T21:49:33.777Z" }, + { url = "https://files.pythonhosted.org/packages/03/e3/d98e3976f4ffa99cddebc1ce379d4d62e3eb1da22285267f902c99cc3395/cymem-2.0.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ee54039aad3ef65de82d66c40516bf54586287b46d32c91ea0530c34e8a2745", size = 42005, upload_time = "2025-01-16T21:49:34.977Z" }, + { url = "https://files.pythonhosted.org/packages/41/b4/7546faf2ab63e59befc95972316d62276cec153f7d4d60e7b0d5e08f0602/cymem-2.0.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c05ef75b5db217be820604e43a47ccbbafea98ab6659d07cea92fa3c864ea58", size = 41747, upload_time = "2025-01-16T21:49:36.108Z" }, + { url = "https://files.pythonhosted.org/packages/7d/4e/042f372e5b3eb7f5f3dd7677161771d301de2b6fa3f7c74e1cebcd502552/cymem-2.0.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8d5381e5793ce531bac0dbc00829c8381f18605bb67e4b61d34f8850463da40", size = 217647, upload_time = "2025-01-16T21:49:37.433Z" }, + { url = "https://files.pythonhosted.org/packages/48/cb/2207679e4b92701f78cf141e1ab4f81f55247dbe154eb426b842a0a993de/cymem-2.0.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2b9d3f42d7249ac81802135cad51d707def058001a32f73fc7fbf3de7045ac7", size = 218857, upload_time = "2025-01-16T21:49:40.09Z" }, + { url = "https://files.pythonhosted.org/packages/31/7a/76ae3b7a39ab2531029d281e43fcfcaad728c2341b150a81a3a1f5587cf3/cymem-2.0.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:39b78f2195d20b75c2d465732f6b8e8721c5d4eb012777c2cb89bdb45a043185", size = 206148, upload_time = "2025-01-16T21:49:41.383Z" }, + { url = "https://files.pythonhosted.org/packages/25/f9/d0fc0191ac79f15638ddb59237aa76f234691374d7d7950e10f384bd8a25/cymem-2.0.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2203bd6525a80d8fd0c94654a263af21c0387ae1d5062cceaebb652bf9bad7bc", size = 207112, upload_time = "2025-01-16T21:49:43.986Z" }, + { url = "https://files.pythonhosted.org/packages/56/c8/75f75889401b20f4c3a7c5965dda09df42913e904ddc2ffe7ef3bdf25061/cymem-2.0.11-cp311-cp311-win_amd64.whl", hash = "sha256:aa54af7314de400634448da1f935b61323da80a49484074688d344fb2036681b", size = 39360, upload_time = "2025-01-16T21:49:45.479Z" }, + { url = "https://files.pythonhosted.org/packages/71/67/0d74f7e9d79f934368a78fb1d1466b94bebdbff14f8ae94dd3e4ea8738bb/cymem-2.0.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a0fbe19ce653cd688842d81e5819dc63f911a26e192ef30b0b89f0ab2b192ff2", size = 42621, upload_time = "2025-01-16T21:49:46.585Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d6/f7a19c63b48efc3f00a3ee8d69070ac90202e1e378f6cf81b8671f0cf762/cymem-2.0.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de72101dc0e6326f6a2f73e05a438d1f3c6110d41044236d0fbe62925091267d", size = 42249, upload_time = "2025-01-16T21:49:48.973Z" }, + { url = "https://files.pythonhosted.org/packages/d7/60/cdc434239813eef547fb99b6d0bafe31178501702df9b77c4108c9a216f6/cymem-2.0.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee4395917f6588b8ac1699499128842768b391fe8896e8626950b4da5f9a406", size = 224758, upload_time = "2025-01-16T21:49:51.382Z" }, + { url = "https://files.pythonhosted.org/packages/1d/68/8fa6efae17cd3b2ba9a2f83b824867c5b65b06f7aec3f8a0d0cabdeffb9b/cymem-2.0.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b02f2b17d760dc3fe5812737b1ce4f684641cdd751d67761d333a3b5ea97b83", size = 227995, upload_time = "2025-01-16T21:49:54.538Z" }, + { url = "https://files.pythonhosted.org/packages/e4/f3/ceda70bf6447880140602285b7c6fa171cb7c78b623d35345cc32505cd06/cymem-2.0.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:04ee6b4041ddec24512d6e969ed6445e57917f01e73b9dabbe17b7e6b27fef05", size = 215325, upload_time = "2025-01-16T21:49:57.229Z" }, + { url = "https://files.pythonhosted.org/packages/d3/47/6915eaa521e1ce7a0ba480eecb6870cb4f681bcd64ced88c2f0ed7a744b4/cymem-2.0.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1048dae7e627ee25f22c87bb670b13e06bc0aecc114b89b959a798d487d1bf4", size = 216447, upload_time = "2025-01-16T21:50:00.432Z" }, + { url = "https://files.pythonhosted.org/packages/7b/be/8e02bdd31e557f642741a06c8e886782ef78f0b00daffd681922dc9bbc88/cymem-2.0.11-cp312-cp312-win_amd64.whl", hash = "sha256:0c269c7a867d74adeb9db65fa1d226342aacf44d64b7931282f0b0eb22eb6275", size = 39283, upload_time = "2025-01-16T21:50:03.384Z" }, + { url = "https://files.pythonhosted.org/packages/bd/90/b064e2677e27a35cf3605146abc3285d4f599cc1b6c18fc445ae876dd1e3/cymem-2.0.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4a311c82f743275c84f708df89ac5bf60ddefe4713d532000c887931e22941f", size = 42389, upload_time = "2025-01-16T21:50:05.925Z" }, + { url = "https://files.pythonhosted.org/packages/fd/60/7aa0561a6c1f0d42643b02c4fdeb2a16181b0ff4e85d73d2d80c6689e92a/cymem-2.0.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:02ed92bead896cca36abad00502b14fa651bdf5d8319461126a2d5ac8c9674c5", size = 41948, upload_time = "2025-01-16T21:50:08.375Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4e/88a29cc5575374982e527b4ebcab3781bdc826ce693c6418a0f836544246/cymem-2.0.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44ddd3588379f8f376116384af99e3fb5f90091d90f520c341942618bf22f05e", size = 219382, upload_time = "2025-01-16T21:50:13.089Z" }, + { url = "https://files.pythonhosted.org/packages/9b/3a/8f96e167e93b7f7ec105ed7b25c77bbf215d15bcbf4a24082cdc12234cd6/cymem-2.0.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87ec985623624bbd298762d8163fc194a096cb13282731a017e09ff8a60bb8b1", size = 222974, upload_time = "2025-01-16T21:50:17.969Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fc/ce016bb0c66a4776345fac7508fddec3b739b9dd4363094ac89cce048832/cymem-2.0.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3385a47285435848e0ed66cfd29b35f3ed8703218e2b17bd7a0c053822f26bf", size = 213426, upload_time = "2025-01-16T21:50:19.349Z" }, + { url = "https://files.pythonhosted.org/packages/5c/c8/accf7cc768f751447a5050b14a195af46798bc22767ac25f49b02861b1eb/cymem-2.0.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5461e65340d6572eb64deadce79242a446a1d39cb7bf70fe7b7e007eb0d799b0", size = 219195, upload_time = "2025-01-16T21:50:21.407Z" }, + { url = "https://files.pythonhosted.org/packages/74/65/c162fbac63e867a055240b6600b92ef96c0eb7a1895312ac53c4be93d056/cymem-2.0.11-cp313-cp313-win_amd64.whl", hash = "sha256:25da111adf425c29af0cfd9fecfec1c71c8d82e2244a85166830a0817a66ada7", size = 39090, upload_time = "2025-01-16T21:50:24.239Z" }, ] [[package]] -name = "nodeenv" -version = "1.9.1" +name = "distlib" +version = "0.3.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +sdist = { url = "https://files.pythonhosted.org/packages/c4/91/e2df406fb4efacdf46871c25cde65d3c6ee5e173b7e5a4547a47bae91920/distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64", size = 609931, upload_time = "2023-12-12T07:14:03.091Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, + { url = "https://files.pythonhosted.org/packages/8e/41/9307e4f5f9976bc8b7fea0b66367734e8faf3ec84bc0d412d8cfabbb66cd/distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784", size = 468850, upload_time = "2023-12-12T07:13:59.966Z" }, ] [[package]] -name = "packaging" -version = "24.1" +name = "distro" +version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788 } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload_time = "2023-12-24T09:54:32.31Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload_time = "2023-12-24T09:54:30.421Z" }, ] [[package]] -name = "passlib" -version = "1.7.4" +name = "dnspython" +version = "2.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b6/06/9da9ee59a67fae7761aab3ccc84fa4f3f33f125b370f1ccdb915bf967c11/passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04", size = 689844 } +sdist = { url = "https://files.pythonhosted.org/packages/37/7d/c871f55054e403fdfd6b8f65fd6d1c4e147ed100d3e9f9ba1fe695403939/dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc", size = 332727, upload_time = "2024-02-18T18:48:48.952Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/a4/ab6b7589382ca3df236e03faa71deac88cae040af60c071a78d254a62172/passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1", size = 525554 }, -] - -[package.optional-dependencies] -bcrypt = [ - { name = "bcrypt" }, + { url = "https://files.pythonhosted.org/packages/87/a1/8c5287991ddb8d3e4662f71356d9656d91ab3a36618c3dd11b280df0d255/dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", size = 307696, upload_time = "2024-02-18T18:48:46.786Z" }, ] [[package]] -name = "platformdirs" -version = "4.3.6" +name = "durationpy" +version = "0.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +sdist = { url = "https://files.pythonhosted.org/packages/9d/a4/e44218c2b394e31a6dd0d6b095c4e1f32d0be54c2a4b250032d717647bab/durationpy-0.10.tar.gz", hash = "sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba", size = 3335, upload_time = "2025-05-17T13:52:37.26Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, + { url = "https://files.pythonhosted.org/packages/b0/0d/9feae160378a3553fa9a339b0e9c1a048e147a4127210e286ef18b730f03/durationpy-0.10-py3-none-any.whl", hash = "sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286", size = 3922, upload_time = "2025-05-17T13:52:36.463Z" }, ] [[package]] -name = "pluggy" -version = "1.5.0" +name = "ecdsa" +version = "0.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/1f/924e3caae75f471eae4b26bd13b698f6af2c44279f67af317439c2f4c46a/ecdsa-0.19.1.tar.gz", hash = "sha256:478cba7b62555866fcb3bb3fe985e06decbdb68ef55713c4e5ab98c57d508e61", size = 201793, upload_time = "2025-03-13T11:52:43.25Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, + { url = "https://files.pythonhosted.org/packages/cb/a3/460c57f094a4a165c84a1341c373b0a4f5ec6ac244b998d5021aade89b77/ecdsa-0.19.1-py2.py3-none-any.whl", hash = "sha256:30638e27cf77b7e15c4c4cc1973720149e1033827cfd00661ca5c8cc0cdb24c3", size = 150607, upload_time = "2025-03-13T11:52:41.757Z" }, ] [[package]] -name = "pre-commit" -version = "3.8.0" +name = "email-validator" +version = "2.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cfgv" }, - { name = "identify" }, - { name = "nodeenv" }, - { name = "pyyaml" }, - { name = "virtualenv" }, + { name = "dnspython" }, + { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/64/10/97ee2fa54dff1e9da9badbc5e35d0bbaef0776271ea5907eccf64140f72f/pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af", size = 177815 } +sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967, upload_time = "2024-06-20T11:30:30.034Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/92/caae8c86e94681b42c246f0bca35c059a2f0529e5b92619f6aba4cf7e7b6/pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f", size = 204643 }, + { url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521, upload_time = "2024-06-20T11:30:28.248Z" }, ] [[package]] -name = "premailer" -version = "3.10.0" +name = "emails" +version = "0.6" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cachetools" }, - { name = "cssselect" }, + { name = "chardet" }, { name = "cssutils" }, { name = "lxml" }, + { name = "premailer" }, + { name = "python-dateutil" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/6f/e49bd31941eff2987076383fa6d811eb785a28f498f5bb131e981bd71e13/premailer-3.10.0.tar.gz", hash = "sha256:d1875a8411f5dc92b53ef9f193db6c0f879dc378d618e0ad292723e388bfe4c2", size = 24342 } +sdist = { url = "https://files.pythonhosted.org/packages/d3/f9/c1e315aa82ed9f037186c30109200fb4b4c51b5483b8065daa0ca836a336/emails-0.6.tar.gz", hash = "sha256:a4c2d67ea8b8831967a750d8edc6e77040d7693143fe280e6d2a367d9c36ff88", size = 44066, upload_time = "2020-06-19T11:20:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/07/4e8d94f94c7d41ca5ddf8a9695ad87b888104e2fd41a35546c1dc9ca74ac/premailer-3.10.0-py2.py3-none-any.whl", hash = "sha256:021b8196364d7df96d04f9ade51b794d0b77bcc19e998321c515633a2273be1a", size = 19544 }, + { url = "https://files.pythonhosted.org/packages/55/7e/b648d640d88d31de49e566832aca9cce025c52d6349b0a0fc65e9df1f4c5/emails-0.6-py2.py3-none-any.whl", hash = "sha256:72c1e3198075709cc35f67e1b49e2da1a2bc087e9b444073db61a379adfb7f3c", size = 56250, upload_time = "2020-06-19T11:20:40.466Z" }, +] + +[[package]] +name = "et-xmlfile" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload_time = "2024-10-25T17:25:40.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload_time = "2024-10-25T17:25:39.051Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883, upload_time = "2024-07-12T22:26:00.161Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453, upload_time = "2024-07-12T22:25:58.476Z" }, +] + +[[package]] +name = "fastapi" +version = "0.115.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7b/5e/bf0471f14bf6ebfbee8208148a3396d1a23298531a6cc10776c59f4c0f87/fastapi-0.115.0.tar.gz", hash = "sha256:f93b4ca3529a8ebc6fc3fcf710e5efa8de3df9b41570958abf1d97d843138004", size = 302295, upload_time = "2024-09-17T19:18:12.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/ab/a1f7eed031aeb1c406a6e9d45ca04bff401c8a25a30dd0e4fd2caae767c3/fastapi-0.115.0-py3-none-any.whl", hash = "sha256:17ea427674467486e997206a5ab25760f6b09e069f099b96f5b55a32fb6f1631", size = 94625, upload_time = "2024-09-17T19:18:10.962Z" }, +] + +[[package]] +name = "filelock" +version = "3.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037, upload_time = "2024-09-17T19:02:01.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163, upload_time = "2024-09-17T19:02:00.268Z" }, +] + +[[package]] +name = "flake8" +version = "7.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mccabe" }, + { name = "pycodestyle" }, + { name = "pyflakes" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9b/af/fbfe3c4b5a657d79e5c47a2827a362f9e1b763336a52f926126aa6dc7123/flake8-7.3.0.tar.gz", hash = "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872", size = 48326, upload_time = "2025-06-20T19:31:35.838Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e", size = 57922, upload_time = "2025-06-20T19:31:34.425Z" }, +] + +[[package]] +name = "flatbuffers" +version = "25.2.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/30/eb5dce7994fc71a2f685d98ec33cc660c0a5887db5610137e60d8cbc4489/flatbuffers-25.2.10.tar.gz", hash = "sha256:97e451377a41262f8d9bd4295cc836133415cc03d8cb966410a4af92eb00d26e", size = 22170, upload_time = "2025-02-11T04:26:46.257Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/25/155f9f080d5e4bc0082edfda032ea2bc2b8fab3f4d25d46c1e9dd22a1a89/flatbuffers-25.2.10-py2.py3-none-any.whl", hash = "sha256:ebba5f4d5ea615af3f7fd70fc310636fbb2bbd1f566ac0a23d98dd412de50051", size = 30953, upload_time = "2025-02-11T04:26:44.484Z" }, +] + +[[package]] +name = "flower" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "celery" }, + { name = "humanize" }, + { name = "prometheus-client" }, + { name = "pytz" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/a1/357f1b5d8946deafdcfdd604f51baae9de10aafa2908d0b7322597155f92/flower-2.0.1.tar.gz", hash = "sha256:5ab717b979530770c16afb48b50d2a98d23c3e9fe39851dcf6bc4d01845a02a0", size = 3220408, upload_time = "2023-08-13T14:37:46.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/ff/ee2f67c0ff146ec98b5df1df637b2bc2d17beeb05df9f427a67bd7a7d79c/flower-2.0.1-py2.py3-none-any.whl", hash = "sha256:9db2c621eeefbc844c8dd88be64aef61e84e2deb29b271e02ab2b5b9f01068e2", size = 383553, upload_time = "2023-08-13T14:37:41.552Z" }, +] + +[[package]] +name = "fsspec" +version = "2025.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/f7/27f15d41f0ed38e8fcc488584b57e902b331da7f7c6dcda53721b15838fc/fsspec-2025.5.1.tar.gz", hash = "sha256:2e55e47a540b91843b755e83ded97c6e897fa0942b11490113f09e9c443c2475", size = 303033, upload_time = "2025-05-24T12:03:23.792Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/61/78c7b3851add1481b048b5fdc29067397a1784e2910592bc81bb3f608635/fsspec-2025.5.1-py3-none-any.whl", hash = "sha256:24d3a2e663d5fc735ab256263c4075f374a174c3410c0b25e5bd1970bceaa462", size = 199052, upload_time = "2025-05-24T12:03:21.66Z" }, +] + +[[package]] +name = "google-auth" +version = "2.40.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cachetools" }, + { name = "pyasn1-modules" }, + { name = "rsa" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/9b/e92ef23b84fa10a64ce4831390b7a4c2e53c0132568d99d4ae61d04c8855/google_auth-2.40.3.tar.gz", hash = "sha256:500c3a29adedeb36ea9cf24b8d10858e152f2412e3ca37829b3fa18e33d63b77", size = 281029, upload_time = "2025-06-04T18:04:57.577Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/63/b19553b658a1692443c62bd07e5868adaa0ad746a0751ba62c59568cd45b/google_auth-2.40.3-py2.py3-none-any.whl", hash = "sha256:1370d4593e86213563547f97a92752fc658456fe4514c809544f330fed45a7ca", size = 216137, upload_time = "2025-06-04T18:04:55.573Z" }, +] + +[[package]] +name = "googleapis-common-protos" +version = "1.70.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/39/24/33db22342cf4a2ea27c9955e6713140fedd51e8b141b5ce5260897020f1a/googleapis_common_protos-1.70.0.tar.gz", hash = "sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257", size = 145903, upload_time = "2025-04-14T10:17:02.924Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/f1/62a193f0227cf15a920390abe675f386dec35f7ae3ffe6da582d3ade42c7/googleapis_common_protos-1.70.0-py3-none-any.whl", hash = "sha256:b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8", size = 294530, upload_time = "2025-04-14T10:17:01.271Z" }, +] + +[[package]] +name = "greenlet" +version = "3.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/92/bb85bd6e80148a4d2e0c59f7c0c2891029f8fd510183afc7d8d2feeed9b6/greenlet-3.2.3.tar.gz", hash = "sha256:8b0dd8ae4c0d6f5e54ee55ba935eeb3d735a9b58a8a1e5b5cbab64e01a39f365", size = 185752, upload_time = "2025-06-05T16:16:09.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/db/b4c12cff13ebac2786f4f217f06588bccd8b53d260453404ef22b121fc3a/greenlet-3.2.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:1afd685acd5597349ee6d7a88a8bec83ce13c106ac78c196ee9dde7c04fe87be", size = 268977, upload_time = "2025-06-05T16:10:24.001Z" }, + { url = "https://files.pythonhosted.org/packages/52/61/75b4abd8147f13f70986df2801bf93735c1bd87ea780d70e3b3ecda8c165/greenlet-3.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:761917cac215c61e9dc7324b2606107b3b292a8349bdebb31503ab4de3f559ac", size = 627351, upload_time = "2025-06-05T16:38:50.685Z" }, + { url = "https://files.pythonhosted.org/packages/35/aa/6894ae299d059d26254779a5088632874b80ee8cf89a88bca00b0709d22f/greenlet-3.2.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:a433dbc54e4a37e4fff90ef34f25a8c00aed99b06856f0119dcf09fbafa16392", size = 638599, upload_time = "2025-06-05T16:41:34.057Z" }, + { url = "https://files.pythonhosted.org/packages/30/64/e01a8261d13c47f3c082519a5e9dbf9e143cc0498ed20c911d04e54d526c/greenlet-3.2.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:72e77ed69312bab0434d7292316d5afd6896192ac4327d44f3d613ecb85b037c", size = 634482, upload_time = "2025-06-05T16:48:16.26Z" }, + { url = "https://files.pythonhosted.org/packages/47/48/ff9ca8ba9772d083a4f5221f7b4f0ebe8978131a9ae0909cf202f94cd879/greenlet-3.2.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:68671180e3849b963649254a882cd544a3c75bfcd2c527346ad8bb53494444db", size = 633284, upload_time = "2025-06-05T16:13:01.599Z" }, + { url = "https://files.pythonhosted.org/packages/e9/45/626e974948713bc15775b696adb3eb0bd708bec267d6d2d5c47bb47a6119/greenlet-3.2.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49c8cfb18fb419b3d08e011228ef8a25882397f3a859b9fe1436946140b6756b", size = 582206, upload_time = "2025-06-05T16:12:48.51Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/8b6f42c67d5df7db35b8c55c9a850ea045219741bb14416255616808c690/greenlet-3.2.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:efc6dc8a792243c31f2f5674b670b3a95d46fa1c6a912b8e310d6f542e7b0712", size = 1111412, upload_time = "2025-06-05T16:36:45.479Z" }, + { url = "https://files.pythonhosted.org/packages/05/46/ab58828217349500a7ebb81159d52ca357da747ff1797c29c6023d79d798/greenlet-3.2.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:731e154aba8e757aedd0781d4b240f1225b075b4409f1bb83b05ff410582cf00", size = 1135054, upload_time = "2025-06-05T16:12:36.478Z" }, + { url = "https://files.pythonhosted.org/packages/68/7f/d1b537be5080721c0f0089a8447d4ef72839039cdb743bdd8ffd23046e9a/greenlet-3.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:96c20252c2f792defe9a115d3287e14811036d51e78b3aaddbee23b69b216302", size = 296573, upload_time = "2025-06-05T16:34:26.521Z" }, + { url = "https://files.pythonhosted.org/packages/fc/2e/d4fcb2978f826358b673f779f78fa8a32ee37df11920dc2bb5589cbeecef/greenlet-3.2.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:784ae58bba89fa1fa5733d170d42486580cab9decda3484779f4759345b29822", size = 270219, upload_time = "2025-06-05T16:10:10.414Z" }, + { url = "https://files.pythonhosted.org/packages/16/24/929f853e0202130e4fe163bc1d05a671ce8dcd604f790e14896adac43a52/greenlet-3.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0921ac4ea42a5315d3446120ad48f90c3a6b9bb93dd9b3cf4e4d84a66e42de83", size = 630383, upload_time = "2025-06-05T16:38:51.785Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b2/0320715eb61ae70c25ceca2f1d5ae620477d246692d9cc284c13242ec31c/greenlet-3.2.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:d2971d93bb99e05f8c2c0c2f4aa9484a18d98c4c3bd3c62b65b7e6ae33dfcfaf", size = 642422, upload_time = "2025-06-05T16:41:35.259Z" }, + { url = "https://files.pythonhosted.org/packages/bd/49/445fd1a210f4747fedf77615d941444349c6a3a4a1135bba9701337cd966/greenlet-3.2.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c667c0bf9d406b77a15c924ef3285e1e05250948001220368e039b6aa5b5034b", size = 638375, upload_time = "2025-06-05T16:48:18.235Z" }, + { url = "https://files.pythonhosted.org/packages/7e/c8/ca19760cf6eae75fa8dc32b487e963d863b3ee04a7637da77b616703bc37/greenlet-3.2.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:592c12fb1165be74592f5de0d70f82bc5ba552ac44800d632214b76089945147", size = 637627, upload_time = "2025-06-05T16:13:02.858Z" }, + { url = "https://files.pythonhosted.org/packages/65/89/77acf9e3da38e9bcfca881e43b02ed467c1dedc387021fc4d9bd9928afb8/greenlet-3.2.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29e184536ba333003540790ba29829ac14bb645514fbd7e32af331e8202a62a5", size = 585502, upload_time = "2025-06-05T16:12:49.642Z" }, + { url = "https://files.pythonhosted.org/packages/97/c6/ae244d7c95b23b7130136e07a9cc5aadd60d59b5951180dc7dc7e8edaba7/greenlet-3.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:93c0bb79844a367782ec4f429d07589417052e621aa39a5ac1fb99c5aa308edc", size = 1114498, upload_time = "2025-06-05T16:36:46.598Z" }, + { url = "https://files.pythonhosted.org/packages/89/5f/b16dec0cbfd3070658e0d744487919740c6d45eb90946f6787689a7efbce/greenlet-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:751261fc5ad7b6705f5f76726567375bb2104a059454e0226e1eef6c756748ba", size = 1139977, upload_time = "2025-06-05T16:12:38.262Z" }, + { url = "https://files.pythonhosted.org/packages/66/77/d48fb441b5a71125bcac042fc5b1494c806ccb9a1432ecaa421e72157f77/greenlet-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:83a8761c75312361aa2b5b903b79da97f13f556164a7dd2d5448655425bd4c34", size = 297017, upload_time = "2025-06-05T16:25:05.225Z" }, + { url = "https://files.pythonhosted.org/packages/f3/94/ad0d435f7c48debe960c53b8f60fb41c2026b1d0fa4a99a1cb17c3461e09/greenlet-3.2.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:25ad29caed5783d4bd7a85c9251c651696164622494c00802a139c00d639242d", size = 271992, upload_time = "2025-06-05T16:11:23.467Z" }, + { url = "https://files.pythonhosted.org/packages/93/5d/7c27cf4d003d6e77749d299c7c8f5fd50b4f251647b5c2e97e1f20da0ab5/greenlet-3.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88cd97bf37fe24a6710ec6a3a7799f3f81d9cd33317dcf565ff9950c83f55e0b", size = 638820, upload_time = "2025-06-05T16:38:52.882Z" }, + { url = "https://files.pythonhosted.org/packages/c6/7e/807e1e9be07a125bb4c169144937910bf59b9d2f6d931578e57f0bce0ae2/greenlet-3.2.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:baeedccca94880d2f5666b4fa16fc20ef50ba1ee353ee2d7092b383a243b0b0d", size = 653046, upload_time = "2025-06-05T16:41:36.343Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ab/158c1a4ea1068bdbc78dba5a3de57e4c7aeb4e7fa034320ea94c688bfb61/greenlet-3.2.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:be52af4b6292baecfa0f397f3edb3c6092ce071b499dd6fe292c9ac9f2c8f264", size = 647701, upload_time = "2025-06-05T16:48:19.604Z" }, + { url = "https://files.pythonhosted.org/packages/cc/0d/93729068259b550d6a0288da4ff72b86ed05626eaf1eb7c0d3466a2571de/greenlet-3.2.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0cc73378150b8b78b0c9fe2ce56e166695e67478550769536a6742dca3651688", size = 649747, upload_time = "2025-06-05T16:13:04.628Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f6/c82ac1851c60851302d8581680573245c8fc300253fc1ff741ae74a6c24d/greenlet-3.2.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:706d016a03e78df129f68c4c9b4c4f963f7d73534e48a24f5f5a7101ed13dbbb", size = 605461, upload_time = "2025-06-05T16:12:50.792Z" }, + { url = "https://files.pythonhosted.org/packages/98/82/d022cf25ca39cf1200650fc58c52af32c90f80479c25d1cbf57980ec3065/greenlet-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:419e60f80709510c343c57b4bb5a339d8767bf9aef9b8ce43f4f143240f88b7c", size = 1121190, upload_time = "2025-06-05T16:36:48.59Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e1/25297f70717abe8104c20ecf7af0a5b82d2f5a980eb1ac79f65654799f9f/greenlet-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:93d48533fade144203816783373f27a97e4193177ebaaf0fc396db19e5d61163", size = 1149055, upload_time = "2025-06-05T16:12:40.457Z" }, + { url = "https://files.pythonhosted.org/packages/1f/8f/8f9e56c5e82eb2c26e8cde787962e66494312dc8cb261c460e1f3a9c88bc/greenlet-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:7454d37c740bb27bdeddfc3f358f26956a07d5220818ceb467a483197d84f849", size = 297817, upload_time = "2025-06-05T16:29:49.244Z" }, + { url = "https://files.pythonhosted.org/packages/b1/cf/f5c0b23309070ae93de75c90d29300751a5aacefc0a3ed1b1d8edb28f08b/greenlet-3.2.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:500b8689aa9dd1ab26872a34084503aeddefcb438e2e7317b89b11eaea1901ad", size = 270732, upload_time = "2025-06-05T16:10:08.26Z" }, + { url = "https://files.pythonhosted.org/packages/48/ae/91a957ba60482d3fecf9be49bc3948f341d706b52ddb9d83a70d42abd498/greenlet-3.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a07d3472c2a93117af3b0136f246b2833fdc0b542d4a9799ae5f41c28323faef", size = 639033, upload_time = "2025-06-05T16:38:53.983Z" }, + { url = "https://files.pythonhosted.org/packages/6f/df/20ffa66dd5a7a7beffa6451bdb7400d66251374ab40b99981478c69a67a8/greenlet-3.2.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:8704b3768d2f51150626962f4b9a9e4a17d2e37c8a8d9867bbd9fa4eb938d3b3", size = 652999, upload_time = "2025-06-05T16:41:37.89Z" }, + { url = "https://files.pythonhosted.org/packages/51/b4/ebb2c8cb41e521f1d72bf0465f2f9a2fd803f674a88db228887e6847077e/greenlet-3.2.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5035d77a27b7c62db6cf41cf786cfe2242644a7a337a0e155c80960598baab95", size = 647368, upload_time = "2025-06-05T16:48:21.467Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6a/1e1b5aa10dced4ae876a322155705257748108b7fd2e4fae3f2a091fe81a/greenlet-3.2.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2d8aa5423cd4a396792f6d4580f88bdc6efcb9205891c9d40d20f6e670992efb", size = 650037, upload_time = "2025-06-05T16:13:06.402Z" }, + { url = "https://files.pythonhosted.org/packages/26/f2/ad51331a157c7015c675702e2d5230c243695c788f8f75feba1af32b3617/greenlet-3.2.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c724620a101f8170065d7dded3f962a2aea7a7dae133a009cada42847e04a7b", size = 608402, upload_time = "2025-06-05T16:12:51.91Z" }, + { url = "https://files.pythonhosted.org/packages/26/bc/862bd2083e6b3aff23300900a956f4ea9a4059de337f5c8734346b9b34fc/greenlet-3.2.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:873abe55f134c48e1f2a6f53f7d1419192a3d1a4e873bace00499a4e45ea6af0", size = 1119577, upload_time = "2025-06-05T16:36:49.787Z" }, + { url = "https://files.pythonhosted.org/packages/86/94/1fc0cc068cfde885170e01de40a619b00eaa8f2916bf3541744730ffb4c3/greenlet-3.2.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:024571bbce5f2c1cfff08bf3fbaa43bbc7444f580ae13b0099e95d0e6e67ed36", size = 1147121, upload_time = "2025-06-05T16:12:42.527Z" }, + { url = "https://files.pythonhosted.org/packages/27/1a/199f9587e8cb08a0658f9c30f3799244307614148ffe8b1e3aa22f324dea/greenlet-3.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:5195fb1e75e592dd04ce79881c8a22becdfa3e6f500e7feb059b1e6fdd54d3e3", size = 297603, upload_time = "2025-06-05T16:20:12.651Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ca/accd7aa5280eb92b70ed9e8f7fd79dc50a2c21d8c73b9a0856f5b564e222/greenlet-3.2.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:3d04332dddb10b4a211b68111dabaee2e1a073663d117dc10247b5b1642bac86", size = 271479, upload_time = "2025-06-05T16:10:47.525Z" }, + { url = "https://files.pythonhosted.org/packages/55/71/01ed9895d9eb49223280ecc98a557585edfa56b3d0e965b9fa9f7f06b6d9/greenlet-3.2.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8186162dffde068a465deab08fc72c767196895c39db26ab1c17c0b77a6d8b97", size = 683952, upload_time = "2025-06-05T16:38:55.125Z" }, + { url = "https://files.pythonhosted.org/packages/ea/61/638c4bdf460c3c678a0a1ef4c200f347dff80719597e53b5edb2fb27ab54/greenlet-3.2.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f4bfbaa6096b1b7a200024784217defedf46a07c2eee1a498e94a1b5f8ec5728", size = 696917, upload_time = "2025-06-05T16:41:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/22/cc/0bd1a7eb759d1f3e3cc2d1bc0f0b487ad3cc9f34d74da4b80f226fde4ec3/greenlet-3.2.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:ed6cfa9200484d234d8394c70f5492f144b20d4533f69262d530a1a082f6ee9a", size = 692443, upload_time = "2025-06-05T16:48:23.113Z" }, + { url = "https://files.pythonhosted.org/packages/67/10/b2a4b63d3f08362662e89c103f7fe28894a51ae0bc890fabf37d1d780e52/greenlet-3.2.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:02b0df6f63cd15012bed5401b47829cfd2e97052dc89da3cfaf2c779124eb892", size = 692995, upload_time = "2025-06-05T16:13:07.972Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c6/ad82f148a4e3ce9564056453a71529732baf5448ad53fc323e37efe34f66/greenlet-3.2.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86c2d68e87107c1792e2e8d5399acec2487a4e993ab76c792408e59394d52141", size = 655320, upload_time = "2025-06-05T16:12:53.453Z" }, + { url = "https://files.pythonhosted.org/packages/5c/4f/aab73ecaa6b3086a4c89863d94cf26fa84cbff63f52ce9bc4342b3087a06/greenlet-3.2.3-cp314-cp314-win_amd64.whl", hash = "sha256:8c47aae8fbbfcf82cc13327ae802ba13c9c36753b67e760023fd116bc124a62a", size = 301236, upload_time = "2025-06-05T16:15:20.111Z" }, +] + +[[package]] +name = "grpcio" +version = "1.73.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/e8/b43b851537da2e2f03fa8be1aef207e5cbfb1a2e014fbb6b40d24c177cd3/grpcio-1.73.1.tar.gz", hash = "sha256:7fce2cd1c0c1116cf3850564ebfc3264fba75d3c74a7414373f1238ea365ef87", size = 12730355, upload_time = "2025-06-26T01:53:24.622Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/51/a5748ab2773d893d099b92653039672f7e26dd35741020972b84d604066f/grpcio-1.73.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:2d70f4ddd0a823436c2624640570ed6097e40935c9194482475fe8e3d9754d55", size = 5365087, upload_time = "2025-06-26T01:51:44.541Z" }, + { url = "https://files.pythonhosted.org/packages/ae/12/c5ee1a5dfe93dbc2eaa42a219e2bf887250b52e2e2ee5c036c4695f2769c/grpcio-1.73.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:3841a8a5a66830261ab6a3c2a3dc539ed84e4ab019165f77b3eeb9f0ba621f26", size = 10608921, upload_time = "2025-06-26T01:51:48.111Z" }, + { url = "https://files.pythonhosted.org/packages/c4/6d/b0c6a8120f02b7d15c5accda6bfc43bc92be70ada3af3ba6d8e077c00374/grpcio-1.73.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:628c30f8e77e0258ab788750ec92059fc3d6628590fb4b7cea8c102503623ed7", size = 5803221, upload_time = "2025-06-26T01:51:50.486Z" }, + { url = "https://files.pythonhosted.org/packages/a6/7a/3c886d9f1c1e416ae81f7f9c7d1995ae72cd64712d29dab74a6bafacb2d2/grpcio-1.73.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67a0468256c9db6d5ecb1fde4bf409d016f42cef649323f0a08a72f352d1358b", size = 6444603, upload_time = "2025-06-26T01:51:52.203Z" }, + { url = "https://files.pythonhosted.org/packages/42/07/f143a2ff534982c9caa1febcad1c1073cdec732f6ac7545d85555a900a7e/grpcio-1.73.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68b84d65bbdebd5926eb5c53b0b9ec3b3f83408a30e4c20c373c5337b4219ec5", size = 6040969, upload_time = "2025-06-26T01:51:55.028Z" }, + { url = "https://files.pythonhosted.org/packages/fb/0f/523131b7c9196d0718e7b2dac0310eb307b4117bdbfef62382e760f7e8bb/grpcio-1.73.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c54796ca22b8349cc594d18b01099e39f2b7ffb586ad83217655781a350ce4da", size = 6132201, upload_time = "2025-06-26T01:51:56.867Z" }, + { url = "https://files.pythonhosted.org/packages/ad/18/010a055410eef1d3a7a1e477ec9d93b091ac664ad93e9c5f56d6cc04bdee/grpcio-1.73.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:75fc8e543962ece2f7ecd32ada2d44c0c8570ae73ec92869f9af8b944863116d", size = 6774718, upload_time = "2025-06-26T01:51:58.338Z" }, + { url = "https://files.pythonhosted.org/packages/16/11/452bfc1ab39d8ee748837ab8ee56beeae0290861052948785c2c445fb44b/grpcio-1.73.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6a6037891cd2b1dd1406b388660522e1565ed340b1fea2955b0234bdd941a862", size = 6304362, upload_time = "2025-06-26T01:51:59.802Z" }, + { url = "https://files.pythonhosted.org/packages/1e/1c/c75ceee626465721e5cb040cf4b271eff817aa97388948660884cb7adffa/grpcio-1.73.1-cp310-cp310-win32.whl", hash = "sha256:cce7265b9617168c2d08ae570fcc2af4eaf72e84f8c710ca657cc546115263af", size = 3679036, upload_time = "2025-06-26T01:52:01.817Z" }, + { url = "https://files.pythonhosted.org/packages/62/2e/42cb31b6cbd671a7b3dbd97ef33f59088cf60e3cf2141368282e26fafe79/grpcio-1.73.1-cp310-cp310-win_amd64.whl", hash = "sha256:6a2b372e65fad38842050943f42ce8fee00c6f2e8ea4f7754ba7478d26a356ee", size = 4340208, upload_time = "2025-06-26T01:52:03.674Z" }, + { url = "https://files.pythonhosted.org/packages/e4/41/921565815e871d84043e73e2c0e748f0318dab6fa9be872cd042778f14a9/grpcio-1.73.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:ba2cea9f7ae4bc21f42015f0ec98f69ae4179848ad744b210e7685112fa507a1", size = 5363853, upload_time = "2025-06-26T01:52:05.5Z" }, + { url = "https://files.pythonhosted.org/packages/b0/cc/9c51109c71d068e4d474becf5f5d43c9d63038cec1b74112978000fa72f4/grpcio-1.73.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:d74c3f4f37b79e746271aa6cdb3a1d7e4432aea38735542b23adcabaaee0c097", size = 10621476, upload_time = "2025-06-26T01:52:07.211Z" }, + { url = "https://files.pythonhosted.org/packages/8f/d3/33d738a06f6dbd4943f4d377468f8299941a7c8c6ac8a385e4cef4dd3c93/grpcio-1.73.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:5b9b1805a7d61c9e90541cbe8dfe0a593dfc8c5c3a43fe623701b6a01b01d710", size = 5807903, upload_time = "2025-06-26T01:52:09.466Z" }, + { url = "https://files.pythonhosted.org/packages/5d/47/36deacd3c967b74e0265f4c608983e897d8bb3254b920f8eafdf60e4ad7e/grpcio-1.73.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3215f69a0670a8cfa2ab53236d9e8026bfb7ead5d4baabe7d7dc11d30fda967", size = 6448172, upload_time = "2025-06-26T01:52:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/0e/64/12d6dc446021684ee1428ea56a3f3712048a18beeadbdefa06e6f8814a6e/grpcio-1.73.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc5eccfd9577a5dc7d5612b2ba90cca4ad14c6d949216c68585fdec9848befb1", size = 6044226, upload_time = "2025-06-26T01:52:12.987Z" }, + { url = "https://files.pythonhosted.org/packages/72/4b/6bae2d88a006000f1152d2c9c10ffd41d0131ca1198e0b661101c2e30ab9/grpcio-1.73.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dc7d7fd520614fce2e6455ba89791458020a39716951c7c07694f9dbae28e9c0", size = 6135690, upload_time = "2025-06-26T01:52:14.92Z" }, + { url = "https://files.pythonhosted.org/packages/38/64/02c83b5076510784d1305025e93e0d78f53bb6a0213c8c84cfe8a00c5c48/grpcio-1.73.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:105492124828911f85127e4825d1c1234b032cb9d238567876b5515d01151379", size = 6775867, upload_time = "2025-06-26T01:52:16.446Z" }, + { url = "https://files.pythonhosted.org/packages/42/72/a13ff7ba6c68ccffa35dacdc06373a76c0008fd75777cba84d7491956620/grpcio-1.73.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:610e19b04f452ba6f402ac9aa94eb3d21fbc94553368008af634812c4a85a99e", size = 6308380, upload_time = "2025-06-26T01:52:18.417Z" }, + { url = "https://files.pythonhosted.org/packages/65/ae/d29d948021faa0070ec33245c1ae354e2aefabd97e6a9a7b6dcf0fb8ef6b/grpcio-1.73.1-cp311-cp311-win32.whl", hash = "sha256:d60588ab6ba0ac753761ee0e5b30a29398306401bfbceffe7d68ebb21193f9d4", size = 3679139, upload_time = "2025-06-26T01:52:20.171Z" }, + { url = "https://files.pythonhosted.org/packages/af/66/e1bbb0c95ea222947f0829b3db7692c59b59bcc531df84442e413fa983d9/grpcio-1.73.1-cp311-cp311-win_amd64.whl", hash = "sha256:6957025a4608bb0a5ff42abd75bfbb2ed99eda29d5992ef31d691ab54b753643", size = 4342558, upload_time = "2025-06-26T01:52:22.137Z" }, + { url = "https://files.pythonhosted.org/packages/b8/41/456caf570c55d5ac26f4c1f2db1f2ac1467d5bf3bcd660cba3e0a25b195f/grpcio-1.73.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:921b25618b084e75d424a9f8e6403bfeb7abef074bb6c3174701e0f2542debcf", size = 5334621, upload_time = "2025-06-26T01:52:23.602Z" }, + { url = "https://files.pythonhosted.org/packages/2a/c2/9a15e179e49f235bb5e63b01590658c03747a43c9775e20c4e13ca04f4c4/grpcio-1.73.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:277b426a0ed341e8447fbf6c1d6b68c952adddf585ea4685aa563de0f03df887", size = 10601131, upload_time = "2025-06-26T01:52:25.691Z" }, + { url = "https://files.pythonhosted.org/packages/0c/1d/1d39e90ef6348a0964caa7c5c4d05f3bae2c51ab429eb7d2e21198ac9b6d/grpcio-1.73.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:96c112333309493c10e118d92f04594f9055774757f5d101b39f8150f8c25582", size = 5759268, upload_time = "2025-06-26T01:52:27.631Z" }, + { url = "https://files.pythonhosted.org/packages/8a/2b/2dfe9ae43de75616177bc576df4c36d6401e0959833b2e5b2d58d50c1f6b/grpcio-1.73.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f48e862aed925ae987eb7084409a80985de75243389dc9d9c271dd711e589918", size = 6409791, upload_time = "2025-06-26T01:52:29.711Z" }, + { url = "https://files.pythonhosted.org/packages/6e/66/e8fe779b23b5a26d1b6949e5c70bc0a5fd08f61a6ec5ac7760d589229511/grpcio-1.73.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83a6c2cce218e28f5040429835fa34a29319071079e3169f9543c3fbeff166d2", size = 6003728, upload_time = "2025-06-26T01:52:31.352Z" }, + { url = "https://files.pythonhosted.org/packages/a9/39/57a18fcef567784108c4fc3f5441cb9938ae5a51378505aafe81e8e15ecc/grpcio-1.73.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:65b0458a10b100d815a8426b1442bd17001fdb77ea13665b2f7dc9e8587fdc6b", size = 6103364, upload_time = "2025-06-26T01:52:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/c5/46/28919d2aa038712fc399d02fa83e998abd8c1f46c2680c5689deca06d1b2/grpcio-1.73.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0a9f3ea8dce9eae9d7cb36827200133a72b37a63896e0e61a9d5ec7d61a59ab1", size = 6749194, upload_time = "2025-06-26T01:52:34.734Z" }, + { url = "https://files.pythonhosted.org/packages/3d/56/3898526f1fad588c5d19a29ea0a3a4996fb4fa7d7c02dc1be0c9fd188b62/grpcio-1.73.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:de18769aea47f18e782bf6819a37c1c528914bfd5683b8782b9da356506190c8", size = 6283902, upload_time = "2025-06-26T01:52:36.503Z" }, + { url = "https://files.pythonhosted.org/packages/dc/64/18b77b89c5870d8ea91818feb0c3ffb5b31b48d1b0ee3e0f0d539730fea3/grpcio-1.73.1-cp312-cp312-win32.whl", hash = "sha256:24e06a5319e33041e322d32c62b1e728f18ab8c9dbc91729a3d9f9e3ed336642", size = 3668687, upload_time = "2025-06-26T01:52:38.678Z" }, + { url = "https://files.pythonhosted.org/packages/3c/52/302448ca6e52f2a77166b2e2ed75f5d08feca4f2145faf75cb768cccb25b/grpcio-1.73.1-cp312-cp312-win_amd64.whl", hash = "sha256:303c8135d8ab176f8038c14cc10d698ae1db9c480f2b2823f7a987aa2a4c5646", size = 4334887, upload_time = "2025-06-26T01:52:40.743Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/4ca20d1acbefabcaba633ab17f4244cbbe8eca877df01517207bd6655914/grpcio-1.73.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:b310824ab5092cf74750ebd8a8a8981c1810cb2b363210e70d06ef37ad80d4f9", size = 5335615, upload_time = "2025-06-26T01:52:42.896Z" }, + { url = "https://files.pythonhosted.org/packages/75/ed/45c345f284abec5d4f6d77cbca9c52c39b554397eb7de7d2fcf440bcd049/grpcio-1.73.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:8f5a6df3fba31a3485096ac85b2e34b9666ffb0590df0cd044f58694e6a1f6b5", size = 10595497, upload_time = "2025-06-26T01:52:44.695Z" }, + { url = "https://files.pythonhosted.org/packages/a4/75/bff2c2728018f546d812b755455014bc718f8cdcbf5c84f1f6e5494443a8/grpcio-1.73.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:052e28fe9c41357da42250a91926a3e2f74c046575c070b69659467ca5aa976b", size = 5765321, upload_time = "2025-06-26T01:52:46.871Z" }, + { url = "https://files.pythonhosted.org/packages/70/3b/14e43158d3b81a38251b1d231dfb45a9b492d872102a919fbf7ba4ac20cd/grpcio-1.73.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c0bf15f629b1497436596b1cbddddfa3234273490229ca29561209778ebe182", size = 6415436, upload_time = "2025-06-26T01:52:49.134Z" }, + { url = "https://files.pythonhosted.org/packages/e5/3f/81d9650ca40b54338336fd360f36773be8cb6c07c036e751d8996eb96598/grpcio-1.73.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ab860d5bfa788c5a021fba264802e2593688cd965d1374d31d2b1a34cacd854", size = 6007012, upload_time = "2025-06-26T01:52:51.076Z" }, + { url = "https://files.pythonhosted.org/packages/55/f4/59edf5af68d684d0f4f7ad9462a418ac517201c238551529098c9aa28cb0/grpcio-1.73.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:ad1d958c31cc91ab050bd8a91355480b8e0683e21176522bacea225ce51163f2", size = 6105209, upload_time = "2025-06-26T01:52:52.773Z" }, + { url = "https://files.pythonhosted.org/packages/e4/a8/700d034d5d0786a5ba14bfa9ce974ed4c976936c2748c2bd87aa50f69b36/grpcio-1.73.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f43ffb3bd415c57224c7427bfb9e6c46a0b6e998754bfa0d00f408e1873dcbb5", size = 6753655, upload_time = "2025-06-26T01:52:55.064Z" }, + { url = "https://files.pythonhosted.org/packages/1f/29/efbd4ac837c23bc48e34bbaf32bd429f0dc9ad7f80721cdb4622144c118c/grpcio-1.73.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:686231cdd03a8a8055f798b2b54b19428cdf18fa1549bee92249b43607c42668", size = 6287288, upload_time = "2025-06-26T01:52:57.33Z" }, + { url = "https://files.pythonhosted.org/packages/d8/61/c6045d2ce16624bbe18b5d169c1a5ce4d6c3a47bc9d0e5c4fa6a50ed1239/grpcio-1.73.1-cp313-cp313-win32.whl", hash = "sha256:89018866a096e2ce21e05eabed1567479713ebe57b1db7cbb0f1e3b896793ba4", size = 3668151, upload_time = "2025-06-26T01:52:59.405Z" }, + { url = "https://files.pythonhosted.org/packages/c2/d7/77ac689216daee10de318db5aa1b88d159432dc76a130948a56b3aa671a2/grpcio-1.73.1-cp313-cp313-win_amd64.whl", hash = "sha256:4a68f8c9966b94dff693670a5cf2b54888a48a5011c5d9ce2295a1a1465ee84f", size = 4335747, upload_time = "2025-06-26T01:53:01.233Z" }, +] + +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload_time = "2022-09-25T15:40:01.519Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload_time = "2022-09-25T15:39:59.68Z" }, +] + +[[package]] +name = "h2" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "hpack" }, + { name = "hyperframe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1b/38/d7f80fd13e6582fb8e0df8c9a653dcc02b03ca34f4d72f34869298c5baf8/h2-4.2.0.tar.gz", hash = "sha256:c8a52129695e88b1a0578d8d2cc6842bbd79128ac685463b887ee278126ad01f", size = 2150682, upload_time = "2025-02-02T07:43:51.815Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/9e/984486f2d0a0bd2b024bf4bc1c62688fcafa9e61991f041fb0e2def4a982/h2-4.2.0-py3-none-any.whl", hash = "sha256:479a53ad425bb29af087f3458a61d30780bc818e4ebcf01f0b536ba916462ed0", size = 60957, upload_time = "2025-02-01T11:02:26.481Z" }, +] + +[[package]] +name = "hf-xet" +version = "1.1.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ed/d4/7685999e85945ed0d7f0762b686ae7015035390de1161dcea9d5276c134c/hf_xet-1.1.5.tar.gz", hash = "sha256:69ebbcfd9ec44fdc2af73441619eeb06b94ee34511bbcf57cd423820090f5694", size = 495969, upload_time = "2025-06-20T21:48:38.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/89/a1119eebe2836cb25758e7661d6410d3eae982e2b5e974bcc4d250be9012/hf_xet-1.1.5-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:f52c2fa3635b8c37c7764d8796dfa72706cc4eded19d638331161e82b0792e23", size = 2687929, upload_time = "2025-06-20T21:48:32.284Z" }, + { url = "https://files.pythonhosted.org/packages/de/5f/2c78e28f309396e71ec8e4e9304a6483dcbc36172b5cea8f291994163425/hf_xet-1.1.5-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:9fa6e3ee5d61912c4a113e0708eaaef987047616465ac7aa30f7121a48fc1af8", size = 2556338, upload_time = "2025-06-20T21:48:30.079Z" }, + { url = "https://files.pythonhosted.org/packages/6d/2f/6cad7b5fe86b7652579346cb7f85156c11761df26435651cbba89376cd2c/hf_xet-1.1.5-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc874b5c843e642f45fd85cda1ce599e123308ad2901ead23d3510a47ff506d1", size = 3102894, upload_time = "2025-06-20T21:48:28.114Z" }, + { url = "https://files.pythonhosted.org/packages/d0/54/0fcf2b619720a26fbb6cc941e89f2472a522cd963a776c089b189559447f/hf_xet-1.1.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dbba1660e5d810bd0ea77c511a99e9242d920790d0e63c0e4673ed36c4022d18", size = 3002134, upload_time = "2025-06-20T21:48:25.906Z" }, + { url = "https://files.pythonhosted.org/packages/f3/92/1d351ac6cef7c4ba8c85744d37ffbfac2d53d0a6c04d2cabeba614640a78/hf_xet-1.1.5-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ab34c4c3104133c495785d5d8bba3b1efc99de52c02e759cf711a91fd39d3a14", size = 3171009, upload_time = "2025-06-20T21:48:33.987Z" }, + { url = "https://files.pythonhosted.org/packages/c9/65/4b2ddb0e3e983f2508528eb4501288ae2f84963586fbdfae596836d5e57a/hf_xet-1.1.5-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:83088ecea236d5113de478acb2339f92c95b4fb0462acaa30621fac02f5a534a", size = 3279245, upload_time = "2025-06-20T21:48:36.051Z" }, + { url = "https://files.pythonhosted.org/packages/f0/55/ef77a85ee443ae05a9e9cba1c9f0dd9241eb42da2aeba1dc50f51154c81a/hf_xet-1.1.5-cp37-abi3-win_amd64.whl", hash = "sha256:73e167d9807d166596b4b2f0b585c6d5bd84a26dea32843665a8b58f6edba245", size = 2738931, upload_time = "2025-06-20T21:48:39.482Z" }, +] + +[[package]] +name = "hpack" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/48/71de9ed269fdae9c8057e5a4c0aa7402e8bb16f2c6e90b3aa53327b113f8/hpack-4.1.0.tar.gz", hash = "sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca", size = 51276, upload_time = "2025-01-22T21:44:58.347Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/c6/80c95b1b2b94682a72cbdbfb85b81ae2daffa4291fbfa1b1464502ede10d/hpack-4.1.0-py3-none-any.whl", hash = "sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496", size = 34357, upload_time = "2025-01-22T21:44:56.92Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/17/b0/5e8b8674f8d203335a62fdfcfa0d11ebe09e23613c3391033cbba35f7926/httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", size = 83234, upload_time = "2024-03-27T18:29:07.397Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/d4/e5d7e4f2174f8a4d63c8897d79eb8fe2503f7ecc03282fee1fa2719c2704/httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5", size = 77926, upload_time = "2024-03-27T18:29:04.098Z" }, +] + +[[package]] +name = "httptools" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/67/1d/d77686502fced061b3ead1c35a2d70f6b281b5f723c4eff7a2277c04e4a2/httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a", size = 191228, upload_time = "2023-10-16T17:42:36.003Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/6a/80bce0216b63babf51cdc34814c3f0f10489e13ab89fb6bc91202736a8a2/httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f", size = 149778, upload_time = "2023-10-16T17:41:35.97Z" }, + { url = "https://files.pythonhosted.org/packages/bd/7d/4cd75356dfe0ed0b40ca6873646bf9ff7b5138236c72338dc569dc57d509/httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563", size = 77604, upload_time = "2023-10-16T17:41:38.361Z" }, + { url = "https://files.pythonhosted.org/packages/4e/74/6348ce41fb5c1484f35184c172efb8854a288e6090bb54e2210598268369/httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58", size = 346717, upload_time = "2023-10-16T17:41:40.447Z" }, + { url = "https://files.pythonhosted.org/packages/65/e7/dd5ba95c84047118a363f0755ad78e639e0529be92424bb020496578aa3b/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", size = 341442, upload_time = "2023-10-16T17:41:42.492Z" }, + { url = "https://files.pythonhosted.org/packages/d8/97/b37d596bc32be291477a8912bf9d1508d7e8553aa11a30cd871fd89cbae4/httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142", size = 354531, upload_time = "2023-10-16T17:41:44.488Z" }, + { url = "https://files.pythonhosted.org/packages/99/c9/53ed7176583ec4b4364d941a08624288f2ae55b4ff58b392cdb68db1e1ed/httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658", size = 347754, upload_time = "2023-10-16T17:41:46.567Z" }, + { url = "https://files.pythonhosted.org/packages/1e/fc/8a26c2adcd3f141e4729897633f03832b71ebea6f4c31cce67a92ded1961/httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b", size = 58165, upload_time = "2023-10-16T17:41:48.859Z" }, + { url = "https://files.pythonhosted.org/packages/f5/d1/53283b96ed823d5e4d89ee9aa0f29df5a1bdf67f148e061549a595d534e4/httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1", size = 145855, upload_time = "2023-10-16T17:41:50.407Z" }, + { url = "https://files.pythonhosted.org/packages/80/dd/cebc9d4b1d4b70e9f3d40d1db0829a28d57ca139d0b04197713816a11996/httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0", size = 75604, upload_time = "2023-10-16T17:41:52.204Z" }, + { url = "https://files.pythonhosted.org/packages/76/7a/45c5a9a2e9d21f7381866eb7b6ead5a84d8fe7e54e35208eeb18320a29b4/httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc", size = 324784, upload_time = "2023-10-16T17:41:53.617Z" }, + { url = "https://files.pythonhosted.org/packages/59/23/047a89e66045232fb82c50ae57699e40f70e073ae5ccd53f54e532fbd2a2/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", size = 318547, upload_time = "2023-10-16T17:41:55.847Z" }, + { url = "https://files.pythonhosted.org/packages/82/f5/50708abc7965d7d93c0ee14a148ccc6d078a508f47fe9357c79d5360f252/httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837", size = 330211, upload_time = "2023-10-16T17:41:57.576Z" }, + { url = "https://files.pythonhosted.org/packages/e3/1e/9823ca7aab323c0e0e9dd82ce835a6e93b69f69aedffbc94d31e327f4283/httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d", size = 322174, upload_time = "2023-10-16T17:41:59.369Z" }, + { url = "https://files.pythonhosted.org/packages/14/e4/20d28dfe7f5b5603b6b04c33bb88662ad749de51f0c539a561f235f42666/httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3", size = 55434, upload_time = "2023-10-16T17:42:01.414Z" }, + { url = "https://files.pythonhosted.org/packages/60/13/b62e086b650752adf9094b7e62dab97f4cb7701005664544494b7956a51e/httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0", size = 146354, upload_time = "2023-10-16T17:42:03.324Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5d/9ad32b79b6c24524087e78aa3f0a2dfcf58c11c90e090e4593b35def8a86/httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2", size = 75785, upload_time = "2023-10-16T17:42:04.731Z" }, + { url = "https://files.pythonhosted.org/packages/d0/a4/b503851c40f20bcbd453db24ed35d961f62abdae0dccc8f672cd5d350d87/httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90", size = 345396, upload_time = "2023-10-16T17:42:06.65Z" }, + { url = "https://files.pythonhosted.org/packages/a2/9a/aa406864f3108e06f7320425a528ff8267124dead1fd72a3e9da2067f893/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", size = 344741, upload_time = "2023-10-16T17:42:08.543Z" }, + { url = "https://files.pythonhosted.org/packages/cf/3a/3fd8dfb987c4247651baf2ac6f28e8e9f889d484ca1a41a9ad0f04dfe300/httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84", size = 345096, upload_time = "2023-10-16T17:42:10.081Z" }, + { url = "https://files.pythonhosted.org/packages/80/01/379f6466d8e2edb861c1f44ccac255ed1f8a0d4c5c666a1ceb34caad7555/httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb", size = 343535, upload_time = "2023-10-16T17:42:12.232Z" }, + { url = "https://files.pythonhosted.org/packages/d3/97/60860e9ee87a7d4712b98f7e1411730520053b9d69e9e42b0b9751809c17/httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949", size = 55660, upload_time = "2023-10-16T17:42:13.711Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload_time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload_time = "2024-12-06T15:37:21.509Z" }, +] + +[package.optional-dependencies] +http2 = [ + { name = "h2" }, +] + +[[package]] +name = "huggingface-hub" +version = "0.33.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "fsspec" }, + { name = "hf-xet", marker = "platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/42/8a95c5632080ae312c0498744b2b852195e10b05a20b1be11c5141092f4c/huggingface_hub-0.33.2.tar.gz", hash = "sha256:84221defaec8fa09c090390cd68c78b88e3c4c2b7befba68d3dc5aacbc3c2c5f", size = 426637, upload_time = "2025-07-02T06:26:05.156Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/f4/5f3f22e762ad1965f01122b42dae5bf0e009286e2dba601ce1d0dba72424/huggingface_hub-0.33.2-py3-none-any.whl", hash = "sha256:3749498bfa91e8cde2ddc2c1db92c79981f40e66434c20133b39e5928ac9bcc5", size = 515373, upload_time = "2025-07-02T06:26:03.072Z" }, +] + +[[package]] +name = "humanfriendly" +version = "10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyreadline3", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload_time = "2021-09-17T21:40:43.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794, upload_time = "2021-09-17T21:40:39.897Z" }, +] + +[[package]] +name = "humanize" +version = "4.12.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/d1/bbc4d251187a43f69844f7fd8941426549bbe4723e8ff0a7441796b0789f/humanize-4.12.3.tar.gz", hash = "sha256:8430be3a615106fdfceb0b2c1b41c4c98c6b0fc5cc59663a5539b111dd325fb0", size = 80514, upload_time = "2025-04-30T11:51:07.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/1e/62a2ec3104394a2975a2629eec89276ede9dbe717092f6966fcf963e1bf0/humanize-4.12.3-py3-none-any.whl", hash = "sha256:2cbf6370af06568fa6d2da77c86edb7886f3160ecd19ee1ffef07979efc597f6", size = 128487, upload_time = "2025-04-30T11:51:06.468Z" }, +] + +[[package]] +name = "hyperframe" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/e7/94f8232d4a74cc99514c13a9f995811485a6903d48e5d952771ef6322e30/hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08", size = 26566, upload_time = "2025-01-22T21:41:49.302Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/30/47d0bf6072f7252e6521f3447ccfa40b421b6824517f82854703d0f5a98b/hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5", size = 13007, upload_time = "2025-01-22T21:41:47.295Z" }, +] + +[[package]] +name = "identify" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/29/bb/25024dbcc93516c492b75919e76f389bac754a3e4248682fba32b250c880/identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98", size = 99097, upload_time = "2024-09-14T23:50:32.513Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/0c/4ef72754c050979fdcc06c744715ae70ea37e734816bb6514f79df77a42f/identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0", size = 98972, upload_time = "2024-09-14T23:50:30.747Z" }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload_time = "2024-09-15T18:07:39.745Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload_time = "2024-09-15T18:07:37.964Z" }, +] + +[[package]] +name = "importlib-metadata" +version = "8.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload_time = "2025-04-27T15:29:01.736Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload_time = "2025-04-27T15:29:00.214Z" }, +] + +[[package]] +name = "importlib-resources" +version = "6.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/8c/f834fbf984f691b4f7ff60f50b514cc3de5cc08abfc3295564dd89c5e2e7/importlib_resources-6.5.2.tar.gz", hash = "sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c", size = 44693, upload_time = "2025-01-03T18:51:56.698Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl", hash = "sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec", size = 37461, upload_time = "2025-01-03T18:51:54.306Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload_time = "2023-01-07T11:08:11.254Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload_time = "2023-01-07T11:08:09.864Z" }, +] + +[[package]] +name = "isort" +version = "6.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b8/21/1e2a441f74a653a144224d7d21afe8f4169e6c7c20bb13aec3a2dc3815e0/isort-6.0.1.tar.gz", hash = "sha256:1cb5df28dfbc742e490c5e41bad6da41b805b0a8be7bc93cd0fb2a8a890ac450", size = 821955, upload_time = "2025-02-26T21:13:16.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/11/114d0a5f4dabbdcedc1125dee0888514c3c3b16d3e9facad87ed96fad97c/isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615", size = 94186, upload_time = "2025-02-26T21:13:14.911Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload_time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload_time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jiter" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/9d/ae7ddb4b8ab3fb1b51faf4deb36cb48a4fbbd7cb36bad6a5fca4741306f7/jiter-0.10.0.tar.gz", hash = "sha256:07a7142c38aacc85194391108dc91b5b57093c978a9932bd86a36862759d9500", size = 162759, upload_time = "2025-05-18T19:04:59.73Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/7e/4011b5c77bec97cb2b572f566220364e3e21b51c48c5bd9c4a9c26b41b67/jiter-0.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cd2fb72b02478f06a900a5782de2ef47e0396b3e1f7d5aba30daeb1fce66f303", size = 317215, upload_time = "2025-05-18T19:03:04.303Z" }, + { url = "https://files.pythonhosted.org/packages/8a/4f/144c1b57c39692efc7ea7d8e247acf28e47d0912800b34d0ad815f6b2824/jiter-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:32bb468e3af278f095d3fa5b90314728a6916d89ba3d0ffb726dd9bf7367285e", size = 322814, upload_time = "2025-05-18T19:03:06.433Z" }, + { url = "https://files.pythonhosted.org/packages/63/1f/db977336d332a9406c0b1f0b82be6f71f72526a806cbb2281baf201d38e3/jiter-0.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8b3e0068c26ddedc7abc6fac37da2d0af16b921e288a5a613f4b86f050354f", size = 345237, upload_time = "2025-05-18T19:03:07.833Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1c/aa30a4a775e8a672ad7f21532bdbfb269f0706b39c6ff14e1f86bdd9e5ff/jiter-0.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:286299b74cc49e25cd42eea19b72aa82c515d2f2ee12d11392c56d8701f52224", size = 370999, upload_time = "2025-05-18T19:03:09.338Z" }, + { url = "https://files.pythonhosted.org/packages/35/df/f8257abc4207830cb18880781b5f5b716bad5b2a22fb4330cfd357407c5b/jiter-0.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ed5649ceeaeffc28d87fb012d25a4cd356dcd53eff5acff1f0466b831dda2a7", size = 491109, upload_time = "2025-05-18T19:03:11.13Z" }, + { url = "https://files.pythonhosted.org/packages/06/76/9e1516fd7b4278aa13a2cc7f159e56befbea9aa65c71586305e7afa8b0b3/jiter-0.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ab0051160cb758a70716448908ef14ad476c3774bd03ddce075f3c1f90a3d6", size = 388608, upload_time = "2025-05-18T19:03:12.911Z" }, + { url = "https://files.pythonhosted.org/packages/6d/64/67750672b4354ca20ca18d3d1ccf2c62a072e8a2d452ac3cf8ced73571ef/jiter-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03997d2f37f6b67d2f5c475da4412be584e1cec273c1cfc03d642c46db43f8cf", size = 352454, upload_time = "2025-05-18T19:03:14.741Z" }, + { url = "https://files.pythonhosted.org/packages/96/4d/5c4e36d48f169a54b53a305114be3efa2bbffd33b648cd1478a688f639c1/jiter-0.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c404a99352d839fed80d6afd6c1d66071f3bacaaa5c4268983fc10f769112e90", size = 391833, upload_time = "2025-05-18T19:03:16.426Z" }, + { url = "https://files.pythonhosted.org/packages/0b/de/ce4a6166a78810bd83763d2fa13f85f73cbd3743a325469a4a9289af6dae/jiter-0.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66e989410b6666d3ddb27a74c7e50d0829704ede652fd4c858e91f8d64b403d0", size = 523646, upload_time = "2025-05-18T19:03:17.704Z" }, + { url = "https://files.pythonhosted.org/packages/a2/a6/3bc9acce53466972964cf4ad85efecb94f9244539ab6da1107f7aed82934/jiter-0.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b532d3af9ef4f6374609a3bcb5e05a1951d3bf6190dc6b176fdb277c9bbf15ee", size = 514735, upload_time = "2025-05-18T19:03:19.44Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d8/243c2ab8426a2a4dea85ba2a2ba43df379ccece2145320dfd4799b9633c5/jiter-0.10.0-cp310-cp310-win32.whl", hash = "sha256:da9be20b333970e28b72edc4dff63d4fec3398e05770fb3205f7fb460eb48dd4", size = 210747, upload_time = "2025-05-18T19:03:21.184Z" }, + { url = "https://files.pythonhosted.org/packages/37/7a/8021bd615ef7788b98fc76ff533eaac846322c170e93cbffa01979197a45/jiter-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:f59e533afed0c5b0ac3eba20d2548c4a550336d8282ee69eb07b37ea526ee4e5", size = 207484, upload_time = "2025-05-18T19:03:23.046Z" }, + { url = "https://files.pythonhosted.org/packages/1b/dd/6cefc6bd68b1c3c979cecfa7029ab582b57690a31cd2f346c4d0ce7951b6/jiter-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3bebe0c558e19902c96e99217e0b8e8b17d570906e72ed8a87170bc290b1e978", size = 317473, upload_time = "2025-05-18T19:03:25.942Z" }, + { url = "https://files.pythonhosted.org/packages/be/cf/fc33f5159ce132be1d8dd57251a1ec7a631c7df4bd11e1cd198308c6ae32/jiter-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:558cc7e44fd8e507a236bee6a02fa17199ba752874400a0ca6cd6e2196cdb7dc", size = 321971, upload_time = "2025-05-18T19:03:27.255Z" }, + { url = "https://files.pythonhosted.org/packages/68/a4/da3f150cf1d51f6c472616fb7650429c7ce053e0c962b41b68557fdf6379/jiter-0.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d613e4b379a07d7c8453c5712ce7014e86c6ac93d990a0b8e7377e18505e98d", size = 345574, upload_time = "2025-05-18T19:03:28.63Z" }, + { url = "https://files.pythonhosted.org/packages/84/34/6e8d412e60ff06b186040e77da5f83bc158e9735759fcae65b37d681f28b/jiter-0.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f62cf8ba0618eda841b9bf61797f21c5ebd15a7a1e19daab76e4e4b498d515b2", size = 371028, upload_time = "2025-05-18T19:03:30.292Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d9/9ee86173aae4576c35a2f50ae930d2ccb4c4c236f6cb9353267aa1d626b7/jiter-0.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:919d139cdfa8ae8945112398511cb7fca58a77382617d279556b344867a37e61", size = 491083, upload_time = "2025-05-18T19:03:31.654Z" }, + { url = "https://files.pythonhosted.org/packages/d9/2c/f955de55e74771493ac9e188b0f731524c6a995dffdcb8c255b89c6fb74b/jiter-0.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ddbc6ae311175a3b03bd8994881bc4635c923754932918e18da841632349db", size = 388821, upload_time = "2025-05-18T19:03:33.184Z" }, + { url = "https://files.pythonhosted.org/packages/81/5a/0e73541b6edd3f4aada586c24e50626c7815c561a7ba337d6a7eb0a915b4/jiter-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c440ea003ad10927a30521a9062ce10b5479592e8a70da27f21eeb457b4a9c5", size = 352174, upload_time = "2025-05-18T19:03:34.965Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c0/61eeec33b8c75b31cae42be14d44f9e6fe3ac15a4e58010256ac3abf3638/jiter-0.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dc347c87944983481e138dea467c0551080c86b9d21de6ea9306efb12ca8f606", size = 391869, upload_time = "2025-05-18T19:03:36.436Z" }, + { url = "https://files.pythonhosted.org/packages/41/22/5beb5ee4ad4ef7d86f5ea5b4509f680a20706c4a7659e74344777efb7739/jiter-0.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:13252b58c1f4d8c5b63ab103c03d909e8e1e7842d302473f482915d95fefd605", size = 523741, upload_time = "2025-05-18T19:03:38.168Z" }, + { url = "https://files.pythonhosted.org/packages/ea/10/768e8818538e5817c637b0df52e54366ec4cebc3346108a4457ea7a98f32/jiter-0.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d1bbf3c465de4a24ab12fb7766a0003f6f9bce48b8b6a886158c4d569452dc5", size = 514527, upload_time = "2025-05-18T19:03:39.577Z" }, + { url = "https://files.pythonhosted.org/packages/73/6d/29b7c2dc76ce93cbedabfd842fc9096d01a0550c52692dfc33d3cc889815/jiter-0.10.0-cp311-cp311-win32.whl", hash = "sha256:db16e4848b7e826edca4ccdd5b145939758dadf0dc06e7007ad0e9cfb5928ae7", size = 210765, upload_time = "2025-05-18T19:03:41.271Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c9/d394706deb4c660137caf13e33d05a031d734eb99c051142e039d8ceb794/jiter-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c9c1d5f10e18909e993f9641f12fe1c77b3e9b533ee94ffa970acc14ded3812", size = 209234, upload_time = "2025-05-18T19:03:42.918Z" }, + { url = "https://files.pythonhosted.org/packages/6d/b5/348b3313c58f5fbfb2194eb4d07e46a35748ba6e5b3b3046143f3040bafa/jiter-0.10.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1e274728e4a5345a6dde2d343c8da018b9d4bd4350f5a472fa91f66fda44911b", size = 312262, upload_time = "2025-05-18T19:03:44.637Z" }, + { url = "https://files.pythonhosted.org/packages/9c/4a/6a2397096162b21645162825f058d1709a02965606e537e3304b02742e9b/jiter-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7202ae396446c988cb2a5feb33a543ab2165b786ac97f53b59aafb803fef0744", size = 320124, upload_time = "2025-05-18T19:03:46.341Z" }, + { url = "https://files.pythonhosted.org/packages/2a/85/1ce02cade7516b726dd88f59a4ee46914bf79d1676d1228ef2002ed2f1c9/jiter-0.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23ba7722d6748b6920ed02a8f1726fb4b33e0fd2f3f621816a8b486c66410ab2", size = 345330, upload_time = "2025-05-18T19:03:47.596Z" }, + { url = "https://files.pythonhosted.org/packages/75/d0/bb6b4f209a77190ce10ea8d7e50bf3725fc16d3372d0a9f11985a2b23eff/jiter-0.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:371eab43c0a288537d30e1f0b193bc4eca90439fc08a022dd83e5e07500ed026", size = 369670, upload_time = "2025-05-18T19:03:49.334Z" }, + { url = "https://files.pythonhosted.org/packages/a0/f5/a61787da9b8847a601e6827fbc42ecb12be2c925ced3252c8ffcb56afcaf/jiter-0.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c675736059020365cebc845a820214765162728b51ab1e03a1b7b3abb70f74c", size = 489057, upload_time = "2025-05-18T19:03:50.66Z" }, + { url = "https://files.pythonhosted.org/packages/12/e4/6f906272810a7b21406c760a53aadbe52e99ee070fc5c0cb191e316de30b/jiter-0.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c5867d40ab716e4684858e4887489685968a47e3ba222e44cde6e4a2154f959", size = 389372, upload_time = "2025-05-18T19:03:51.98Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ba/77013b0b8ba904bf3762f11e0129b8928bff7f978a81838dfcc958ad5728/jiter-0.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395bb9a26111b60141757d874d27fdea01b17e8fac958b91c20128ba8f4acc8a", size = 352038, upload_time = "2025-05-18T19:03:53.703Z" }, + { url = "https://files.pythonhosted.org/packages/67/27/c62568e3ccb03368dbcc44a1ef3a423cb86778a4389e995125d3d1aaa0a4/jiter-0.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6842184aed5cdb07e0c7e20e5bdcfafe33515ee1741a6835353bb45fe5d1bd95", size = 391538, upload_time = "2025-05-18T19:03:55.046Z" }, + { url = "https://files.pythonhosted.org/packages/c0/72/0d6b7e31fc17a8fdce76164884edef0698ba556b8eb0af9546ae1a06b91d/jiter-0.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:62755d1bcea9876770d4df713d82606c8c1a3dca88ff39046b85a048566d56ea", size = 523557, upload_time = "2025-05-18T19:03:56.386Z" }, + { url = "https://files.pythonhosted.org/packages/2f/09/bc1661fbbcbeb6244bd2904ff3a06f340aa77a2b94e5a7373fd165960ea3/jiter-0.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533efbce2cacec78d5ba73a41756beff8431dfa1694b6346ce7af3a12c42202b", size = 514202, upload_time = "2025-05-18T19:03:57.675Z" }, + { url = "https://files.pythonhosted.org/packages/1b/84/5a5d5400e9d4d54b8004c9673bbe4403928a00d28529ff35b19e9d176b19/jiter-0.10.0-cp312-cp312-win32.whl", hash = "sha256:8be921f0cadd245e981b964dfbcd6fd4bc4e254cdc069490416dd7a2632ecc01", size = 211781, upload_time = "2025-05-18T19:03:59.025Z" }, + { url = "https://files.pythonhosted.org/packages/9b/52/7ec47455e26f2d6e5f2ea4951a0652c06e5b995c291f723973ae9e724a65/jiter-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7c7d785ae9dda68c2678532a5a1581347e9c15362ae9f6e68f3fdbfb64f2e49", size = 206176, upload_time = "2025-05-18T19:04:00.305Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b0/279597e7a270e8d22623fea6c5d4eeac328e7d95c236ed51a2b884c54f70/jiter-0.10.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e0588107ec8e11b6f5ef0e0d656fb2803ac6cf94a96b2b9fc675c0e3ab5e8644", size = 311617, upload_time = "2025-05-18T19:04:02.078Z" }, + { url = "https://files.pythonhosted.org/packages/91/e3/0916334936f356d605f54cc164af4060e3e7094364add445a3bc79335d46/jiter-0.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cafc4628b616dc32530c20ee53d71589816cf385dd9449633e910d596b1f5c8a", size = 318947, upload_time = "2025-05-18T19:04:03.347Z" }, + { url = "https://files.pythonhosted.org/packages/6a/8e/fd94e8c02d0e94539b7d669a7ebbd2776e51f329bb2c84d4385e8063a2ad/jiter-0.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:520ef6d981172693786a49ff5b09eda72a42e539f14788124a07530f785c3ad6", size = 344618, upload_time = "2025-05-18T19:04:04.709Z" }, + { url = "https://files.pythonhosted.org/packages/6f/b0/f9f0a2ec42c6e9c2e61c327824687f1e2415b767e1089c1d9135f43816bd/jiter-0.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:554dedfd05937f8fc45d17ebdf298fe7e0c77458232bcb73d9fbbf4c6455f5b3", size = 368829, upload_time = "2025-05-18T19:04:06.912Z" }, + { url = "https://files.pythonhosted.org/packages/e8/57/5bbcd5331910595ad53b9fd0c610392ac68692176f05ae48d6ce5c852967/jiter-0.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5bc299da7789deacf95f64052d97f75c16d4fc8c4c214a22bf8d859a4288a1c2", size = 491034, upload_time = "2025-05-18T19:04:08.222Z" }, + { url = "https://files.pythonhosted.org/packages/9b/be/c393df00e6e6e9e623a73551774449f2f23b6ec6a502a3297aeeece2c65a/jiter-0.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5161e201172de298a8a1baad95eb85db4fb90e902353b1f6a41d64ea64644e25", size = 388529, upload_time = "2025-05-18T19:04:09.566Z" }, + { url = "https://files.pythonhosted.org/packages/42/3e/df2235c54d365434c7f150b986a6e35f41ebdc2f95acea3036d99613025d/jiter-0.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2227db6ba93cb3e2bf67c87e594adde0609f146344e8207e8730364db27041", size = 350671, upload_time = "2025-05-18T19:04:10.98Z" }, + { url = "https://files.pythonhosted.org/packages/c6/77/71b0b24cbcc28f55ab4dbfe029f9a5b73aeadaba677843fc6dc9ed2b1d0a/jiter-0.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15acb267ea5e2c64515574b06a8bf393fbfee6a50eb1673614aa45f4613c0cca", size = 390864, upload_time = "2025-05-18T19:04:12.722Z" }, + { url = "https://files.pythonhosted.org/packages/6a/d3/ef774b6969b9b6178e1d1e7a89a3bd37d241f3d3ec5f8deb37bbd203714a/jiter-0.10.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:901b92f2e2947dc6dfcb52fd624453862e16665ea909a08398dde19c0731b7f4", size = 522989, upload_time = "2025-05-18T19:04:14.261Z" }, + { url = "https://files.pythonhosted.org/packages/0c/41/9becdb1d8dd5d854142f45a9d71949ed7e87a8e312b0bede2de849388cb9/jiter-0.10.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d0cb9a125d5a3ec971a094a845eadde2db0de85b33c9f13eb94a0c63d463879e", size = 513495, upload_time = "2025-05-18T19:04:15.603Z" }, + { url = "https://files.pythonhosted.org/packages/9c/36/3468e5a18238bdedae7c4d19461265b5e9b8e288d3f86cd89d00cbb48686/jiter-0.10.0-cp313-cp313-win32.whl", hash = "sha256:48a403277ad1ee208fb930bdf91745e4d2d6e47253eedc96e2559d1e6527006d", size = 211289, upload_time = "2025-05-18T19:04:17.541Z" }, + { url = "https://files.pythonhosted.org/packages/7e/07/1c96b623128bcb913706e294adb5f768fb7baf8db5e1338ce7b4ee8c78ef/jiter-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:75f9eb72ecb640619c29bf714e78c9c46c9c4eaafd644bf78577ede459f330d4", size = 205074, upload_time = "2025-05-18T19:04:19.21Z" }, + { url = "https://files.pythonhosted.org/packages/54/46/caa2c1342655f57d8f0f2519774c6d67132205909c65e9aa8255e1d7b4f4/jiter-0.10.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:28ed2a4c05a1f32ef0e1d24c2611330219fed727dae01789f4a335617634b1ca", size = 318225, upload_time = "2025-05-18T19:04:20.583Z" }, + { url = "https://files.pythonhosted.org/packages/43/84/c7d44c75767e18946219ba2d703a5a32ab37b0bc21886a97bc6062e4da42/jiter-0.10.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a4c418b1ec86a195f1ca69da8b23e8926c752b685af665ce30777233dfe070", size = 350235, upload_time = "2025-05-18T19:04:22.363Z" }, + { url = "https://files.pythonhosted.org/packages/01/16/f5a0135ccd968b480daad0e6ab34b0c7c5ba3bc447e5088152696140dcb3/jiter-0.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d7bfed2fe1fe0e4dda6ef682cee888ba444b21e7a6553e03252e4feb6cf0adca", size = 207278, upload_time = "2025-05-18T19:04:23.627Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9b/1d646da42c3de6c2188fdaa15bce8ecb22b635904fc68be025e21249ba44/jiter-0.10.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:5e9251a5e83fab8d87799d3e1a46cb4b7f2919b895c6f4483629ed2446f66522", size = 310866, upload_time = "2025-05-18T19:04:24.891Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0e/26538b158e8a7c7987e94e7aeb2999e2e82b1f9d2e1f6e9874ddf71ebda0/jiter-0.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:023aa0204126fe5b87ccbcd75c8a0d0261b9abdbbf46d55e7ae9f8e22424eeb8", size = 318772, upload_time = "2025-05-18T19:04:26.161Z" }, + { url = "https://files.pythonhosted.org/packages/7b/fb/d302893151caa1c2636d6574d213e4b34e31fd077af6050a9c5cbb42f6fb/jiter-0.10.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c189c4f1779c05f75fc17c0c1267594ed918996a231593a21a5ca5438445216", size = 344534, upload_time = "2025-05-18T19:04:27.495Z" }, + { url = "https://files.pythonhosted.org/packages/01/d8/5780b64a149d74e347c5128d82176eb1e3241b1391ac07935693466d6219/jiter-0.10.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:15720084d90d1098ca0229352607cd68256c76991f6b374af96f36920eae13c4", size = 369087, upload_time = "2025-05-18T19:04:28.896Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5b/f235a1437445160e777544f3ade57544daf96ba7e96c1a5b24a6f7ac7004/jiter-0.10.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f2fb68e5f1cfee30e2b2a09549a00683e0fde4c6a2ab88c94072fc33cb7426", size = 490694, upload_time = "2025-05-18T19:04:30.183Z" }, + { url = "https://files.pythonhosted.org/packages/85/a9/9c3d4617caa2ff89cf61b41e83820c27ebb3f7b5fae8a72901e8cd6ff9be/jiter-0.10.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce541693355fc6da424c08b7edf39a2895f58d6ea17d92cc2b168d20907dee12", size = 388992, upload_time = "2025-05-18T19:04:32.028Z" }, + { url = "https://files.pythonhosted.org/packages/68/b1/344fd14049ba5c94526540af7eb661871f9c54d5f5601ff41a959b9a0bbd/jiter-0.10.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31c50c40272e189d50006ad5c73883caabb73d4e9748a688b216e85a9a9ca3b9", size = 351723, upload_time = "2025-05-18T19:04:33.467Z" }, + { url = "https://files.pythonhosted.org/packages/41/89/4c0e345041186f82a31aee7b9d4219a910df672b9fef26f129f0cda07a29/jiter-0.10.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fa3402a2ff9815960e0372a47b75c76979d74402448509ccd49a275fa983ef8a", size = 392215, upload_time = "2025-05-18T19:04:34.827Z" }, + { url = "https://files.pythonhosted.org/packages/55/58/ee607863e18d3f895feb802154a2177d7e823a7103f000df182e0f718b38/jiter-0.10.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:1956f934dca32d7bb647ea21d06d93ca40868b505c228556d3373cbd255ce853", size = 522762, upload_time = "2025-05-18T19:04:36.19Z" }, + { url = "https://files.pythonhosted.org/packages/15/d0/9123fb41825490d16929e73c212de9a42913d68324a8ce3c8476cae7ac9d/jiter-0.10.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:fcedb049bdfc555e261d6f65a6abe1d5ad68825b7202ccb9692636c70fcced86", size = 513427, upload_time = "2025-05-18T19:04:37.544Z" }, + { url = "https://files.pythonhosted.org/packages/d8/b3/2bd02071c5a2430d0b70403a34411fc519c2f227da7b03da9ba6a956f931/jiter-0.10.0-cp314-cp314-win32.whl", hash = "sha256:ac509f7eccca54b2a29daeb516fb95b6f0bd0d0d8084efaf8ed5dfc7b9f0b357", size = 210127, upload_time = "2025-05-18T19:04:38.837Z" }, + { url = "https://files.pythonhosted.org/packages/03/0c/5fe86614ea050c3ecd728ab4035534387cd41e7c1855ef6c031f1ca93e3f/jiter-0.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5ed975b83a2b8639356151cef5c0d597c68376fc4922b45d0eb384ac058cfa00", size = 318527, upload_time = "2025-05-18T19:04:40.612Z" }, + { url = "https://files.pythonhosted.org/packages/b3/4a/4175a563579e884192ba6e81725fc0448b042024419be8d83aa8a80a3f44/jiter-0.10.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa96f2abba33dc77f79b4cf791840230375f9534e5fac927ccceb58c5e604a5", size = 354213, upload_time = "2025-05-18T19:04:41.894Z" }, +] + +[[package]] +name = "joblib" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/fe/0f5a938c54105553436dbff7a61dc4fed4b1b2c98852f8833beaf4d5968f/joblib-1.5.1.tar.gz", hash = "sha256:f4f86e351f39fe3d0d32a9f2c3d8af1ee4cec285aafcb27003dda5205576b444", size = 330475, upload_time = "2025-05-23T12:04:37.097Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/4f/1195bbac8e0c2acc5f740661631d8d750dc38d4a32b23ee5df3cde6f4e0d/joblib-1.5.1-py3-none-any.whl", hash = "sha256:4719a31f054c7d766948dcd83e9613686b27114f190f717cec7eaa2084f8a74a", size = 307746, upload_time = "2025-05-23T12:04:35.124Z" }, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonpointer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/78/18813351fe5d63acad16aec57f94ec2b70a09e53ca98145589e185423873/jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c", size = 21699, upload_time = "2023-06-26T12:07:29.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/07/02e16ed01e04a374e644b575638ec7987ae846d25ad97bcc9945a3ee4b0e/jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade", size = 12898, upload_time = "2023-06-16T21:01:28.466Z" }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload_time = "2024-06-10T19:24:42.462Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload_time = "2024-06-10T19:24:40.698Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.24.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bf/d3/1cf5326b923a53515d8f3a2cd442e6d7e94fcc444716e879ea70a0ce3177/jsonschema-4.24.0.tar.gz", hash = "sha256:0b4e8069eb12aedfa881333004bccaec24ecef5a8a6a4b6df142b2cc9599d196", size = 353480, upload_time = "2025-05-26T18:48:10.459Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/3d/023389198f69c722d039351050738d6755376c8fd343e91dc493ea485905/jsonschema-4.24.0-py3-none-any.whl", hash = "sha256:a462455f19f5faf404a7902952b6f0e3ce868f3ee09a359b05eca6673bd8412d", size = 88709, upload_time = "2025-05-26T18:48:08.417Z" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload_time = "2025-04-23T12:34:07.418Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload_time = "2025-04-23T12:34:05.422Z" }, +] + +[[package]] +name = "kombu" +version = "5.5.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "amqp" }, + { name = "packaging" }, + { name = "tzdata" }, + { name = "vine" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/d3/5ff936d8319ac86b9c409f1501b07c426e6ad41966fedace9ef1b966e23f/kombu-5.5.4.tar.gz", hash = "sha256:886600168275ebeada93b888e831352fe578168342f0d1d5833d88ba0d847363", size = 461992, upload_time = "2025-06-01T10:19:22.281Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/70/a07dcf4f62598c8ad579df241af55ced65bed76e42e45d3c368a6d82dbc1/kombu-5.5.4-py3-none-any.whl", hash = "sha256:a12ed0557c238897d8e518f1d1fdf84bd1516c5e305af2dacd85c2015115feb8", size = 210034, upload_time = "2025-06-01T10:19:20.436Z" }, +] + +[[package]] +name = "kubernetes" +version = "33.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "durationpy" }, + { name = "google-auth" }, + { name = "oauthlib" }, + { name = "python-dateutil" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "requests-oauthlib" }, + { name = "six" }, + { name = "urllib3" }, + { name = "websocket-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/52/19ebe8004c243fdfa78268a96727c71e08f00ff6fe69a301d0b7fcbce3c2/kubernetes-33.1.0.tar.gz", hash = "sha256:f64d829843a54c251061a8e7a14523b521f2dc5c896cf6d65ccf348648a88993", size = 1036779, upload_time = "2025-06-09T21:57:58.521Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/43/d9bebfc3db7dea6ec80df5cb2aad8d274dd18ec2edd6c4f21f32c237cbbb/kubernetes-33.1.0-py2.py3-none-any.whl", hash = "sha256:544de42b24b64287f7e0aa9513c93cb503f7f40eea39b20f66810011a86eabc5", size = 1941335, upload_time = "2025-06-09T21:57:56.327Z" }, +] + +[[package]] +name = "langchain" +version = "0.3.26" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-timeout", marker = "python_full_version < '3.11'" }, + { name = "langchain-core" }, + { name = "langchain-text-splitters" }, + { name = "langsmith" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "sqlalchemy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7f/13/a9931800ee42bbe0f8850dd540de14e80dda4945e7ee36e20b5d5964286e/langchain-0.3.26.tar.gz", hash = "sha256:8ff034ee0556d3e45eff1f1e96d0d745ced57858414dba7171c8ebdbeb5580c9", size = 10226808, upload_time = "2025-06-20T22:23:01.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/f2/c09a2e383283e3af1db669ab037ac05a45814f4b9c472c48dc24c0cef039/langchain-0.3.26-py3-none-any.whl", hash = "sha256:361bb2e61371024a8c473da9f9c55f4ee50f269c5ab43afdb2b1309cb7ac36cf", size = 1012336, upload_time = "2025-06-20T22:22:58.874Z" }, +] + +[[package]] +name = "langchain-core" +version = "0.3.68" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonpatch" }, + { name = "langsmith" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "tenacity" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/23/20/f5b18a17bfbe3416177e702ab2fd230b7d168abb17be31fb48f43f0bb772/langchain_core-0.3.68.tar.gz", hash = "sha256:312e1932ac9aa2eaf111b70fdc171776fa571d1a86c1f873dcac88a094b19c6f", size = 563041, upload_time = "2025-07-03T17:02:28.704Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/da/c89be0a272993bfcb762b2a356b9f55de507784c2755ad63caec25d183bf/langchain_core-0.3.68-py3-none-any.whl", hash = "sha256:5e5c1fbef419590537c91b8c2d86af896fbcbaf0d5ed7fdcdd77f7d8f3467ba0", size = 441405, upload_time = "2025-07-03T17:02:27.115Z" }, +] + +[[package]] +name = "langchain-openai" +version = "0.3.27" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "openai" }, + { name = "tiktoken" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6f/7b/e65261a08a03dd43f0ef8a539930b56548ac8136e71258c220d3589d1d07/langchain_openai-0.3.27.tar.gz", hash = "sha256:5d5a55adbff739274dfc3a4102925771736f893758f63679b64ae62fed79ca30", size = 753326, upload_time = "2025-06-27T17:56:29.904Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/31/1f0baf6490b082bf4d06f355c5e9c28728931dbf321f3ca03137617a692e/langchain_openai-0.3.27-py3-none-any.whl", hash = "sha256:efe636c3523978c44adc41cf55c8b3766c05c77547982465884d1258afe705df", size = 70368, upload_time = "2025-06-27T17:56:28.726Z" }, +] + +[[package]] +name = "langchain-text-splitters" +version = "0.3.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/ac/b4a25c5716bb0103b1515f1f52cc69ffb1035a5a225ee5afe3aed28bf57b/langchain_text_splitters-0.3.8.tar.gz", hash = "sha256:116d4b9f2a22dda357d0b79e30acf005c5518177971c66a9f1ab0edfdb0f912e", size = 42128, upload_time = "2025-04-04T14:03:51.521Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/a3/3696ff2444658053c01b6b7443e761f28bb71217d82bb89137a978c5f66f/langchain_text_splitters-0.3.8-py3-none-any.whl", hash = "sha256:e75cc0f4ae58dcf07d9f18776400cf8ade27fadd4ff6d264df6278bb302f6f02", size = 32440, upload_time = "2025-04-04T14:03:50.6Z" }, +] + +[[package]] +name = "langcodes" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "language-data" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/7a/5a97e327063409a5caa21541e6d08ae4a0f2da328447e9f2c7b39e179226/langcodes-3.5.0.tar.gz", hash = "sha256:1eef8168d07e51e131a2497ffecad4b663f6208e7c3ae3b8dc15c51734a6f801", size = 191030, upload_time = "2024-11-19T10:23:45.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/6b/068c2ea7a712bf805c62445bd9e9c06d7340358ef2824150eceac027444b/langcodes-3.5.0-py3-none-any.whl", hash = "sha256:853c69d1a35e0e13da2f427bb68fb2fa4a8f4fb899e0c62ad8df8d073dcfed33", size = 182974, upload_time = "2024-11-19T10:23:42.824Z" }, +] + +[[package]] +name = "langdetect" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/72/a3add0e4eec4eb9e2569554f7c70f4a3c27712f40e3284d483e88094cc0e/langdetect-1.0.9.tar.gz", hash = "sha256:cbc1fef89f8d062739774bd51eda3da3274006b3661d199c2655f6b3f6d605a0", size = 981474, upload_time = "2021-05-07T07:54:13.562Z" } + +[[package]] +name = "langsmith" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "orjson", marker = "platform_python_implementation != 'PyPy'" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "requests-toolbelt" }, + { name = "zstandard" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/c8/8d2e0fc438d2d3d8d4300f7684ea30a754344ed00d7ba9cc2705241d2a5f/langsmith-0.4.4.tar.gz", hash = "sha256:70c53bbff24a7872e88e6fa0af98270f4986a6e364f9e85db1cc5636defa4d66", size = 352105, upload_time = "2025-06-27T19:20:36.207Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/33/a3337eb70d795495a299a1640d7a75f17fb917155a64309b96106e7b9452/langsmith-0.4.4-py3-none-any.whl", hash = "sha256:014c68329bd085bd6c770a6405c61bb6881f82eb554ce8c4d1984b0035fd1716", size = 367687, upload_time = "2025-06-27T19:20:33.839Z" }, +] + +[[package]] +name = "language-data" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "marisa-trie" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dd/ce/3f144716a9f2cbf42aa86ebc8b085a184be25c80aa453eea17c294d239c1/language_data-1.3.0.tar.gz", hash = "sha256:7600ef8aa39555145d06c89f0c324bf7dab834ea0b0a439d8243762e3ebad7ec", size = 5129310, upload_time = "2024-11-19T10:21:37.912Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/e9/5a5ffd9b286db82be70d677d0a91e4d58f7912bb8dd026ddeeb4abe70679/language_data-1.3.0-py3-none-any.whl", hash = "sha256:e2ee943551b5ae5f89cd0e801d1fc3835bb0ef5b7e9c3a4e8e17b2b214548fbf", size = 5385760, upload_time = "2024-11-19T10:21:36.005Z" }, +] + +[[package]] +name = "lxml" +version = "5.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/6b/20c3a4b24751377aaa6307eb230b66701024012c29dd374999cc92983269/lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f", size = 3679318, upload_time = "2024-08-10T18:17:29.668Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/ce/2789e39eddf2b13fac29878bfa465f0910eb6b0096e29090e5176bc8cf43/lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656", size = 8124570, upload_time = "2024-08-10T18:09:04.096Z" }, + { url = "https://files.pythonhosted.org/packages/24/a8/f4010166a25d41715527129af2675981a50d3bbf7df09c5d9ab8ca24fbf9/lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d", size = 4413042, upload_time = "2024-08-10T18:09:08.841Z" }, + { url = "https://files.pythonhosted.org/packages/41/a4/7e45756cecdd7577ddf67a68b69c1db0f5ddbf0c9f65021ee769165ffc5a/lxml-5.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a", size = 5139213, upload_time = "2024-08-10T18:09:12.622Z" }, + { url = "https://files.pythonhosted.org/packages/02/e2/ecf845b12323c92748077e1818b64e8b4dba509a4cb12920b3762ebe7552/lxml-5.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8", size = 4838814, upload_time = "2024-08-10T18:09:16.222Z" }, + { url = "https://files.pythonhosted.org/packages/12/91/619f9fb72cf75e9ceb8700706f7276f23995f6ad757e6d400fbe35ca4990/lxml-5.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330", size = 5425084, upload_time = "2024-08-10T18:09:19.795Z" }, + { url = "https://files.pythonhosted.org/packages/25/3b/162a85a8f0fd2a3032ec3f936636911c6e9523a8e263fffcfd581ce98b54/lxml-5.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965", size = 4875993, upload_time = "2024-08-10T18:09:23.776Z" }, + { url = "https://files.pythonhosted.org/packages/43/af/dd3f58cc7d946da6ae42909629a2b1d5dd2d1b583334d4af9396697d6863/lxml-5.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22", size = 5012462, upload_time = "2024-08-10T18:09:27.642Z" }, + { url = "https://files.pythonhosted.org/packages/69/c1/5ea46b2d4c98f5bf5c83fffab8a0ad293c9bc74df9ecfbafef10f77f7201/lxml-5.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b", size = 4815288, upload_time = "2024-08-10T18:09:31.633Z" }, + { url = "https://files.pythonhosted.org/packages/1d/51/a0acca077ad35da458f4d3f729ef98effd2b90f003440d35fc36323f8ae6/lxml-5.3.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7", size = 5472435, upload_time = "2024-08-10T18:09:35.758Z" }, + { url = "https://files.pythonhosted.org/packages/4d/6b/0989c9368986961a6b0f55b46c80404c4b758417acdb6d87bfc3bd5f4967/lxml-5.3.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8", size = 4976354, upload_time = "2024-08-10T18:09:39.51Z" }, + { url = "https://files.pythonhosted.org/packages/05/9e/87492d03ff604fbf656ed2bf3e2e8d28f5d58ea1f00ff27ac27b06509079/lxml-5.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32", size = 5029973, upload_time = "2024-08-10T18:09:42.978Z" }, + { url = "https://files.pythonhosted.org/packages/f9/cc/9ae1baf5472af88e19e2c454b3710c1be9ecafb20eb474eeabcd88a055d2/lxml-5.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86", size = 4888837, upload_time = "2024-08-10T18:09:46.185Z" }, + { url = "https://files.pythonhosted.org/packages/d2/10/5594ffaec8c120d75b17e3ad23439b740a51549a9b5fd7484b2179adfe8f/lxml-5.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5", size = 5530555, upload_time = "2024-08-10T18:09:50.366Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9b/de17f05377c8833343b629905571fb06cff2028f15a6f58ae2267662e341/lxml-5.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03", size = 5405314, upload_time = "2024-08-10T18:09:54.58Z" }, + { url = "https://files.pythonhosted.org/packages/8a/b4/227be0f1f3cca8255925985164c3838b8b36e441ff0cc10c1d3c6bdba031/lxml-5.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7", size = 5079303, upload_time = "2024-08-10T18:09:58.032Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ee/19abcebb7fc40319bb71cd6adefa1ad94d09b5660228715854d6cc420713/lxml-5.3.0-cp310-cp310-win32.whl", hash = "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80", size = 3475126, upload_time = "2024-08-10T18:10:01.43Z" }, + { url = "https://files.pythonhosted.org/packages/a1/35/183d32551447e280032b2331738cd850da435a42f850b71ebeaab42c1313/lxml-5.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3", size = 3805065, upload_time = "2024-08-10T18:10:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/5c/a8/449faa2a3cbe6a99f8d38dcd51a3ee8844c17862841a6f769ea7c2a9cd0f/lxml-5.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b", size = 8141056, upload_time = "2024-08-10T18:10:09.455Z" }, + { url = "https://files.pythonhosted.org/packages/ac/8a/ae6325e994e2052de92f894363b038351c50ee38749d30cc6b6d96aaf90f/lxml-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18", size = 4425238, upload_time = "2024-08-10T18:10:13.348Z" }, + { url = "https://files.pythonhosted.org/packages/f8/fb/128dddb7f9086236bce0eeae2bfb316d138b49b159f50bc681d56c1bdd19/lxml-5.3.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442", size = 5095197, upload_time = "2024-08-10T18:10:16.825Z" }, + { url = "https://files.pythonhosted.org/packages/b4/f9/a181a8ef106e41e3086629c8bdb2d21a942f14c84a0e77452c22d6b22091/lxml-5.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4", size = 4809809, upload_time = "2024-08-10T18:10:20.046Z" }, + { url = "https://files.pythonhosted.org/packages/25/2f/b20565e808f7f6868aacea48ddcdd7e9e9fb4c799287f21f1a6c7c2e8b71/lxml-5.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f", size = 5407593, upload_time = "2024-08-10T18:10:23.641Z" }, + { url = "https://files.pythonhosted.org/packages/23/0e/caac672ec246d3189a16c4d364ed4f7d6bf856c080215382c06764058c08/lxml-5.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e", size = 4866657, upload_time = "2024-08-10T18:10:26.528Z" }, + { url = "https://files.pythonhosted.org/packages/67/a4/1f5fbd3f58d4069000522196b0b776a014f3feec1796da03e495cf23532d/lxml-5.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c", size = 4967017, upload_time = "2024-08-10T18:10:29.639Z" }, + { url = "https://files.pythonhosted.org/packages/ee/73/623ecea6ca3c530dd0a4ed0d00d9702e0e85cd5624e2d5b93b005fe00abd/lxml-5.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16", size = 4810730, upload_time = "2024-08-10T18:10:33.387Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ce/fb84fb8e3c298f3a245ae3ea6221c2426f1bbaa82d10a88787412a498145/lxml-5.3.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79", size = 5455154, upload_time = "2024-08-10T18:10:36.897Z" }, + { url = "https://files.pythonhosted.org/packages/b1/72/4d1ad363748a72c7c0411c28be2b0dc7150d91e823eadad3b91a4514cbea/lxml-5.3.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080", size = 4969416, upload_time = "2024-08-10T18:10:40.331Z" }, + { url = "https://files.pythonhosted.org/packages/42/07/b29571a58a3a80681722ea8ed0ba569211d9bb8531ad49b5cacf6d409185/lxml-5.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654", size = 5013672, upload_time = "2024-08-10T18:10:43.768Z" }, + { url = "https://files.pythonhosted.org/packages/b9/93/bde740d5a58cf04cbd38e3dd93ad1e36c2f95553bbf7d57807bc6815d926/lxml-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d", size = 4878644, upload_time = "2024-08-10T18:10:47.901Z" }, + { url = "https://files.pythonhosted.org/packages/56/b5/645c8c02721d49927c93181de4017164ec0e141413577687c3df8ff0800f/lxml-5.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763", size = 5511531, upload_time = "2024-08-10T18:10:51.581Z" }, + { url = "https://files.pythonhosted.org/packages/85/3f/6a99a12d9438316f4fc86ef88c5d4c8fb674247b17f3173ecadd8346b671/lxml-5.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec", size = 5402065, upload_time = "2024-08-10T18:10:54.841Z" }, + { url = "https://files.pythonhosted.org/packages/80/8a/df47bff6ad5ac57335bf552babfb2408f9eb680c074ec1ba412a1a6af2c5/lxml-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be", size = 5069775, upload_time = "2024-08-10T18:10:57.808Z" }, + { url = "https://files.pythonhosted.org/packages/08/ae/e7ad0f0fbe4b6368c5ee1e3ef0c3365098d806d42379c46c1ba2802a52f7/lxml-5.3.0-cp311-cp311-win32.whl", hash = "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9", size = 3474226, upload_time = "2024-08-10T18:11:00.73Z" }, + { url = "https://files.pythonhosted.org/packages/c3/b5/91c2249bfac02ee514ab135e9304b89d55967be7e53e94a879b74eec7a5c/lxml-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1", size = 3814971, upload_time = "2024-08-10T18:11:03.743Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/d1f1c5e40c64bf62afd7a3f9b34ce18a586a1cccbf71e783cd0a6d8e8971/lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859", size = 8171753, upload_time = "2024-08-10T18:11:07.859Z" }, + { url = "https://files.pythonhosted.org/packages/bd/83/26b1864921869784355459f374896dcf8b44d4af3b15d7697e9156cb2de9/lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e", size = 4441955, upload_time = "2024-08-10T18:11:12.251Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d2/e9bff9fb359226c25cda3538f664f54f2804f4b37b0d7c944639e1a51f69/lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f", size = 5050778, upload_time = "2024-08-10T18:11:16.233Z" }, + { url = "https://files.pythonhosted.org/packages/88/69/6972bfafa8cd3ddc8562b126dd607011e218e17be313a8b1b9cc5a0ee876/lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e", size = 4748628, upload_time = "2024-08-10T18:11:19.507Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ea/a6523c7c7f6dc755a6eed3d2f6d6646617cad4d3d6d8ce4ed71bfd2362c8/lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179", size = 5322215, upload_time = "2024-08-10T18:11:23.708Z" }, + { url = "https://files.pythonhosted.org/packages/99/37/396fbd24a70f62b31d988e4500f2068c7f3fd399d2fd45257d13eab51a6f/lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a", size = 4813963, upload_time = "2024-08-10T18:11:26.997Z" }, + { url = "https://files.pythonhosted.org/packages/09/91/e6136f17459a11ce1757df864b213efbeab7adcb2efa63efb1b846ab6723/lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3", size = 4923353, upload_time = "2024-08-10T18:11:30.478Z" }, + { url = "https://files.pythonhosted.org/packages/1d/7c/2eeecf87c9a1fca4f84f991067c693e67340f2b7127fc3eca8fa29d75ee3/lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1", size = 4740541, upload_time = "2024-08-10T18:11:34.344Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ed/4c38ba58defca84f5f0d0ac2480fdcd99fc7ae4b28fc417c93640a6949ae/lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d", size = 5346504, upload_time = "2024-08-10T18:11:37.595Z" }, + { url = "https://files.pythonhosted.org/packages/a5/22/bbd3995437e5745cb4c2b5d89088d70ab19d4feabf8a27a24cecb9745464/lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c", size = 4898077, upload_time = "2024-08-10T18:11:40.867Z" }, + { url = "https://files.pythonhosted.org/packages/0a/6e/94537acfb5b8f18235d13186d247bca478fea5e87d224644e0fe907df976/lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99", size = 4946543, upload_time = "2024-08-10T18:11:44.954Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e8/4b15df533fe8e8d53363b23a41df9be907330e1fa28c7ca36893fad338ee/lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff", size = 4816841, upload_time = "2024-08-10T18:11:49.046Z" }, + { url = "https://files.pythonhosted.org/packages/1a/e7/03f390ea37d1acda50bc538feb5b2bda6745b25731e4e76ab48fae7106bf/lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a", size = 5417341, upload_time = "2024-08-10T18:11:52.295Z" }, + { url = "https://files.pythonhosted.org/packages/ea/99/d1133ab4c250da85a883c3b60249d3d3e7c64f24faff494cf0fd23f91e80/lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8", size = 5327539, upload_time = "2024-08-10T18:11:55.98Z" }, + { url = "https://files.pythonhosted.org/packages/7d/ed/e6276c8d9668028213df01f598f385b05b55a4e1b4662ee12ef05dab35aa/lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d", size = 5012542, upload_time = "2024-08-10T18:11:59.351Z" }, + { url = "https://files.pythonhosted.org/packages/36/88/684d4e800f5aa28df2a991a6a622783fb73cf0e46235cfa690f9776f032e/lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30", size = 3486454, upload_time = "2024-08-10T18:12:02.696Z" }, + { url = "https://files.pythonhosted.org/packages/fc/82/ace5a5676051e60355bd8fb945df7b1ba4f4fb8447f2010fb816bfd57724/lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f", size = 3816857, upload_time = "2024-08-10T18:12:06.456Z" }, + { url = "https://files.pythonhosted.org/packages/94/6a/42141e4d373903bfea6f8e94b2f554d05506dfda522ada5343c651410dc8/lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a", size = 8156284, upload_time = "2024-08-10T18:12:10.439Z" }, + { url = "https://files.pythonhosted.org/packages/91/5e/fa097f0f7d8b3d113fb7312c6308af702f2667f22644441715be961f2c7e/lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd", size = 4432407, upload_time = "2024-08-10T18:12:13.917Z" }, + { url = "https://files.pythonhosted.org/packages/2d/a1/b901988aa6d4ff937f2e5cfc114e4ec561901ff00660c3e56713642728da/lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51", size = 5048331, upload_time = "2024-08-10T18:12:17.204Z" }, + { url = "https://files.pythonhosted.org/packages/30/0f/b2a54f48e52de578b71bbe2a2f8160672a8a5e103df3a78da53907e8c7ed/lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b", size = 4744835, upload_time = "2024-08-10T18:12:21.172Z" }, + { url = "https://files.pythonhosted.org/packages/82/9d/b000c15538b60934589e83826ecbc437a1586488d7c13f8ee5ff1f79a9b8/lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002", size = 5316649, upload_time = "2024-08-10T18:12:24.897Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ee/ffbb9eaff5e541922611d2c56b175c45893d1c0b8b11e5a497708a6a3b3b/lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4", size = 4812046, upload_time = "2024-08-10T18:12:29.028Z" }, + { url = "https://files.pythonhosted.org/packages/15/ff/7ff89d567485c7b943cdac316087f16b2399a8b997007ed352a1248397e5/lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492", size = 4918597, upload_time = "2024-08-10T18:12:32.278Z" }, + { url = "https://files.pythonhosted.org/packages/c6/a3/535b6ed8c048412ff51268bdf4bf1cf052a37aa7e31d2e6518038a883b29/lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3", size = 4738071, upload_time = "2024-08-10T18:12:35.407Z" }, + { url = "https://files.pythonhosted.org/packages/7a/8f/cbbfa59cb4d4fd677fe183725a76d8c956495d7a3c7f111ab8f5e13d2e83/lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4", size = 5342213, upload_time = "2024-08-10T18:12:38.73Z" }, + { url = "https://files.pythonhosted.org/packages/5c/fb/db4c10dd9958d4b52e34d1d1f7c1f434422aeaf6ae2bbaaff2264351d944/lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367", size = 4893749, upload_time = "2024-08-10T18:12:42.606Z" }, + { url = "https://files.pythonhosted.org/packages/f2/38/bb4581c143957c47740de18a3281a0cab7722390a77cc6e610e8ebf2d736/lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832", size = 4945901, upload_time = "2024-08-10T18:12:45.944Z" }, + { url = "https://files.pythonhosted.org/packages/fc/d5/18b7de4960c731e98037bd48fa9f8e6e8f2558e6fbca4303d9b14d21ef3b/lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff", size = 4815447, upload_time = "2024-08-10T18:12:49.051Z" }, + { url = "https://files.pythonhosted.org/packages/97/a8/cd51ceaad6eb849246559a8ef60ae55065a3df550fc5fcd27014361c1bab/lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd", size = 5411186, upload_time = "2024-08-10T18:12:52.388Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/1e3dabab519481ed7b1fdcba21dcfb8832f57000733ef0e71cf6d09a5e03/lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb", size = 5324481, upload_time = "2024-08-10T18:12:56.021Z" }, + { url = "https://files.pythonhosted.org/packages/b6/17/71e9984cf0570cd202ac0a1c9ed5c1b8889b0fc8dc736f5ef0ffb181c284/lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b", size = 5011053, upload_time = "2024-08-10T18:12:59.714Z" }, + { url = "https://files.pythonhosted.org/packages/69/68/9f7e6d3312a91e30829368c2b3217e750adef12a6f8eb10498249f4e8d72/lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957", size = 3485634, upload_time = "2024-08-10T18:13:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/7d/db/214290d58ad68c587bd5d6af3d34e56830438733d0d0856c0275fde43652/lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d", size = 3814417, upload_time = "2024-08-10T18:13:05.791Z" }, + { url = "https://files.pythonhosted.org/packages/99/f7/b73a431c8500565aa500e99e60b448d305eaf7c0b4c893c7c5a8a69cc595/lxml-5.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c", size = 3925431, upload_time = "2024-08-10T18:15:59.002Z" }, + { url = "https://files.pythonhosted.org/packages/db/48/4a206623c0d093d0e3b15f415ffb4345b0bdf661a3d0b15a112948c033c7/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a", size = 4216683, upload_time = "2024-08-10T18:16:03.004Z" }, + { url = "https://files.pythonhosted.org/packages/54/47/577820c45dd954523ae8453b632d91e76da94ca6d9ee40d8c98dd86f916b/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005", size = 4326732, upload_time = "2024-08-10T18:16:06.973Z" }, + { url = "https://files.pythonhosted.org/packages/68/de/96cb6d3269bc994b4f5ede8ca7bf0840f5de0a278bc6e50cb317ff71cafa/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce", size = 4218377, upload_time = "2024-08-10T18:16:10.836Z" }, + { url = "https://files.pythonhosted.org/packages/a5/43/19b1ef6cbffa4244a217f95cc5f41a6cb4720fed33510a49670b03c5f1a0/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83", size = 4351237, upload_time = "2024-08-10T18:16:14.652Z" }, + { url = "https://files.pythonhosted.org/packages/ba/b2/6a22fb5c0885da3b00e116aee81f0b829ec9ac8f736cd414b4a09413fc7d/lxml-5.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba", size = 3487557, upload_time = "2024-08-10T18:16:18.255Z" }, +] + +[[package]] +name = "mako" +version = "1.3.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/03/fb5ba97ff65ce64f6d35b582aacffc26b693a98053fa831ab43a437cbddb/Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc", size = 392738, upload_time = "2024-05-14T12:22:05.966Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/62/70f5a0c2dd208f9f3f2f9afd103aec42ee4d9ad2401d78342f75e9b8da36/Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", size = 78565, upload_time = "2024-05-14T12:22:08.522Z" }, +] + +[[package]] +name = "marisa-trie" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/15/9d9743897e4450b2de199ee673b50cb018980c4ced477d41cf91304a85e3/marisa_trie-1.2.1.tar.gz", hash = "sha256:3a27c408e2aefc03e0f1d25b2ff2afb85aac3568f6fa2ae2a53b57a2e87ce29d", size = 416124, upload_time = "2024-10-12T11:30:15.989Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/83/ccf5b33f2123f3110705c608f8e0caa82002626511aafafc58f82e50d322/marisa_trie-1.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a2eb41d2f9114d8b7bd66772c237111e00d2bae2260824560eaa0a1e291ce9e8", size = 362200, upload_time = "2024-10-12T11:28:25.418Z" }, + { url = "https://files.pythonhosted.org/packages/9d/74/f7ce1fc2ee480c7f8ceadd9b992caceaba442a97e5e99d6aea00d3635a0b/marisa_trie-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9e956e6a46f604b17d570901e66f5214fb6f658c21e5e7665deace236793cef6", size = 192309, upload_time = "2024-10-12T11:28:27.348Z" }, + { url = "https://files.pythonhosted.org/packages/e4/52/5dbbc13e57ce54c2ef0d04962d7d8f66edc69ed34310c734a2913199a581/marisa_trie-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bd45142501300e7538b2e544905580918b67b1c82abed1275fe4c682c95635fa", size = 174713, upload_time = "2024-10-12T11:28:28.912Z" }, + { url = "https://files.pythonhosted.org/packages/57/49/2580372f3f980aea95c23d05b2c1d3bbb9ee1ab8cfd441545153e44f1be7/marisa_trie-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8443d116c612cfd1961fbf76769faf0561a46d8e317315dd13f9d9639ad500c", size = 1314808, upload_time = "2024-10-12T11:28:30.705Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ba/e12a4d450f265414cc68df6a116a78beece72b95f774f04d29cd48e08d19/marisa_trie-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:875a6248e60fbb48d947b574ffa4170f34981f9e579bde960d0f9a49ea393ecc", size = 1346678, upload_time = "2024-10-12T11:28:33.106Z" }, + { url = "https://files.pythonhosted.org/packages/b2/81/8e130cb1eea741fd17694d821096f7ec9841f0e3d3c69b740257f5eeafa8/marisa_trie-1.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:746a7c60a17fccd3cfcfd4326926f02ea4fcdfc25d513411a0c4fc8e4a1ca51f", size = 1307254, upload_time = "2024-10-12T11:28:35.053Z" }, + { url = "https://files.pythonhosted.org/packages/d7/d0/3deb5ea2bf7e4d845339875dbb31f3c3f66c8d6568723db1d137fb08a91c/marisa_trie-1.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e70869737cc0e5bd903f620667da6c330d6737048d1f44db792a6af68a1d35be", size = 2194712, upload_time = "2024-10-12T11:28:36.87Z" }, + { url = "https://files.pythonhosted.org/packages/9c/5f/b38d728dd30954816497b53425cfaddaf7b93ac0912db5911888f191b07a/marisa_trie-1.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06b099dd743676dbcd8abd8465ceac8f6d97d8bfaabe2c83b965495523b4cef2", size = 2355625, upload_time = "2024-10-12T11:28:38.206Z" }, + { url = "https://files.pythonhosted.org/packages/7e/4f/61c0faa9ae9e53600a1b7a0c367bc9db1a4fdc625402ec232c755a05e094/marisa_trie-1.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d2a82eb21afdaf22b50d9b996472305c05ca67fc4ff5a026a220320c9c961db6", size = 2290290, upload_time = "2024-10-12T11:28:40.148Z" }, + { url = "https://files.pythonhosted.org/packages/7c/7d/713b970fb3043248881ed776dbf4d54918398aa5dde843a38711d0d62c8f/marisa_trie-1.2.1-cp310-cp310-win32.whl", hash = "sha256:8951e7ce5d3167fbd085703b4cbb3f47948ed66826bef9a2173c379508776cf5", size = 130743, upload_time = "2024-10-12T11:28:41.31Z" }, + { url = "https://files.pythonhosted.org/packages/cc/94/3d619cc82c30daeacd18a88674f4e6540ebfb7b4b7752ca0552793be80cf/marisa_trie-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:5685a14b3099b1422c4f59fa38b0bf4b5342ee6cc38ae57df9666a0b28eeaad3", size = 151891, upload_time = "2024-10-12T11:28:42.279Z" }, + { url = "https://files.pythonhosted.org/packages/4a/93/ffb01dfa22b6eee918e798e0bc3487427036c608aa4c065725f31aaf4104/marisa_trie-1.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed3fb4ed7f2084597e862bcd56c56c5529e773729a426c083238682dba540e98", size = 362823, upload_time = "2024-10-12T11:28:43.983Z" }, + { url = "https://files.pythonhosted.org/packages/6d/1d/5c36500ac350c278c9bdfd88e17fa846fa4136d75597c167141ed973cdf2/marisa_trie-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fe69fb9ffb2767746181f7b3b29bbd3454d1d24717b5958e030494f3d3cddf3", size = 192741, upload_time = "2024-10-12T11:28:45.536Z" }, + { url = "https://files.pythonhosted.org/packages/e8/04/87dd0840f3f720e511eba56193c02bf64d7d96df1ca9f6d19994f55154be/marisa_trie-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4728ed3ae372d1ea2cdbd5eaa27b8f20a10e415d1f9d153314831e67d963f281", size = 174995, upload_time = "2024-10-12T11:28:46.544Z" }, + { url = "https://files.pythonhosted.org/packages/c9/51/9e903a7e13b7593e2e675d0ec4c390ca076dc5df1c1a0d5e85a513b886a3/marisa_trie-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cf4f25cf895692b232f49aa5397af6aba78bb679fb917a05fce8d3cb1ee446d", size = 1384728, upload_time = "2024-10-12T11:28:48.28Z" }, + { url = "https://files.pythonhosted.org/packages/e8/3f/7362a5ac60c2b0aad0f52cd57e7bd0c708f20d2660d8df85360f3d8f1c4b/marisa_trie-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cca7f96236ffdbf49be4b2e42c132e3df05968ac424544034767650913524de", size = 1412620, upload_time = "2024-10-12T11:28:50.427Z" }, + { url = "https://files.pythonhosted.org/packages/1f/bc/aaa3eaf6875f78a204a8da9692d56e3a36f89997dad2c388628385614576/marisa_trie-1.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d7eb20bf0e8b55a58d2a9b518aabc4c18278787bdba476c551dd1c1ed109e509", size = 1361555, upload_time = "2024-10-12T11:28:51.603Z" }, + { url = "https://files.pythonhosted.org/packages/18/98/e11b5a6206c5d110f32adab37fa84a85410d684e9c731acdd5c9250e2ce4/marisa_trie-1.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b1ec93f0d1ee6d7ab680a6d8ea1a08bf264636358e92692072170032dda652ba", size = 2257717, upload_time = "2024-10-12T11:28:52.881Z" }, + { url = "https://files.pythonhosted.org/packages/d2/9d/6b4a40867875e738a67c5b29f83e2e490a66bd9067ace3dd9a5c497e2b7f/marisa_trie-1.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e2699255d7ac610dee26d4ae7bda5951d05c7d9123a22e1f7c6a6f1964e0a4e4", size = 2417044, upload_time = "2024-10-12T11:28:54.115Z" }, + { url = "https://files.pythonhosted.org/packages/fe/61/e25613c72f2931757334b8bcf6b501569ef713f5ee9c6c7688ec460bd720/marisa_trie-1.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c484410911182457a8a1a0249d0c09c01e2071b78a0a8538cd5f7fa45589b13a", size = 2351960, upload_time = "2024-10-12T11:28:55.417Z" }, + { url = "https://files.pythonhosted.org/packages/19/0a/a90ccaf3eb476d13ec261f80c6c52defaf10ebc7f35eb2bcd7dfb533aef7/marisa_trie-1.2.1-cp311-cp311-win32.whl", hash = "sha256:ad548117744b2bcf0e3d97374608be0a92d18c2af13d98b728d37cd06248e571", size = 130446, upload_time = "2024-10-12T11:28:57.294Z" }, + { url = "https://files.pythonhosted.org/packages/fc/98/574b4e143e0a2f5f71af8716b6c4a8a46220f75a6e0847ce7d11ee0ba4aa/marisa_trie-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:436f62d27714970b9cdd3b3c41bdad046f260e62ebb0daa38125ef70536fc73b", size = 152037, upload_time = "2024-10-12T11:28:58.399Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bf/8bd4ac8436b33fd46c9e1ffe3c2a131cd9744cc1649dbbe13308f744ef2b/marisa_trie-1.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:638506eacf20ca503fff72221a7e66a6eadbf28d6a4a6f949fcf5b1701bb05ec", size = 360041, upload_time = "2024-10-12T11:28:59.436Z" }, + { url = "https://files.pythonhosted.org/packages/ab/dd/4d3151e302e66ae387885f6ec265bd189e096b0c43c1379bfd9a3b9d2543/marisa_trie-1.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de1665eaafefa48a308e4753786519888021740501a15461c77bdfd57638e6b4", size = 190520, upload_time = "2024-10-12T11:29:01.07Z" }, + { url = "https://files.pythonhosted.org/packages/00/28/ae5991c74fb90b173167a366a634c83445f948ad044d37287b478d6b457e/marisa_trie-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f713af9b8aa66a34cd3a78c7d150a560a75734713abe818a69021fd269e927fa", size = 174175, upload_time = "2024-10-12T11:29:02.516Z" }, + { url = "https://files.pythonhosted.org/packages/5a/6a/fbfa89a8680eaabc6847a6c421e65427c43182db0c4bdb60e1516c81c822/marisa_trie-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2a7d00f53f4945320b551bccb826b3fb26948bde1a10d50bb9802fabb611b10", size = 1354995, upload_time = "2024-10-12T11:29:04.294Z" }, + { url = "https://files.pythonhosted.org/packages/9e/4c/2ba0b385e5f64ca4ddb0c10ec52ddf881bc4521f135948786fc339d1d6c8/marisa_trie-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98042040d1d6085792e8d0f74004fc0f5f9ca6091c298f593dd81a22a4643854", size = 1390989, upload_time = "2024-10-12T11:29:05.576Z" }, + { url = "https://files.pythonhosted.org/packages/6b/22/0791ed3045c91d0938345a86be472fc7c188b894f16c5dfad2ef31e7f882/marisa_trie-1.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6532615111eec2c79e711965ece0bc95adac1ff547a7fff5ffca525463116deb", size = 1328810, upload_time = "2024-10-12T11:29:07.522Z" }, + { url = "https://files.pythonhosted.org/packages/9d/7d/3f566e563abae6efce7fc311c63282a447c611739b3cd66c0e36077c86f8/marisa_trie-1.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:20948e40ab2038e62b7000ca6b4a913bc16c91a2c2e6da501bd1f917eeb28d51", size = 2230222, upload_time = "2024-10-12T11:29:09.374Z" }, + { url = "https://files.pythonhosted.org/packages/a5/0b/38fbb4611b5d1030242ddc2aa62e524438c8076e26f87395dbbf222dc62d/marisa_trie-1.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:66b23e5b35dd547f85bf98db7c749bc0ffc57916ade2534a6bbc32db9a4abc44", size = 2383620, upload_time = "2024-10-12T11:29:10.904Z" }, + { url = "https://files.pythonhosted.org/packages/ae/17/4553c63de29904d5d2521a24cad817bc7883cfa90506ab702ec4dae59a7b/marisa_trie-1.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6704adf0247d2dda42e876b793be40775dff46624309ad99bc7537098bee106d", size = 2329202, upload_time = "2024-10-12T11:29:12.266Z" }, + { url = "https://files.pythonhosted.org/packages/45/08/6307a630e63cd763fe77ac56516faa67fa9cd342060691e40fabc84be6b0/marisa_trie-1.2.1-cp312-cp312-win32.whl", hash = "sha256:3ad356442c2fea4c2a6f514738ddf213d23930f942299a2b2c05df464a00848a", size = 129652, upload_time = "2024-10-12T11:29:13.454Z" }, + { url = "https://files.pythonhosted.org/packages/a1/fe/67c357bfd92710d95a16b86e1453c663d565415d7f7838781c79ff7e1a7e/marisa_trie-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:f2806f75817392cedcacb24ac5d80b0350dde8d3861d67d045c1d9b109764114", size = 150845, upload_time = "2024-10-12T11:29:15.092Z" }, + { url = "https://files.pythonhosted.org/packages/2a/a4/a110cd9952f0e72da7bafea1f0084b18b9e03952110d9083bfda52279f5c/marisa_trie-1.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:b5ea16e69bfda0ac028c921b58de1a4aaf83d43934892977368579cd3c0a2554", size = 354439, upload_time = "2024-10-12T11:29:16.831Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a5/a6099eb1c3fd8d7e93408c45501e1d08536ac57dfef02ec331f78e1ace18/marisa_trie-1.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9f627f4e41be710b6cb6ed54b0128b229ac9d50e2054d9cde3af0fef277c23cf", size = 188187, upload_time = "2024-10-12T11:29:18.558Z" }, + { url = "https://files.pythonhosted.org/packages/7c/cc/f637127e2beffa920d21f7fc45b4029575bcd1b28a90c0d90cb2b08c2205/marisa_trie-1.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5e649f3dc8ab5476732094f2828cc90cac3be7c79bc0c8318b6fda0c1d248db4", size = 171484, upload_time = "2024-10-12T11:29:19.596Z" }, + { url = "https://files.pythonhosted.org/packages/6d/0f/29f2ad7260b956570f69f25a542efa51ba76eb76ecd53c63ee9d21987c3d/marisa_trie-1.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46e528ee71808c961baf8c3ce1c46a8337ec7a96cc55389d11baafe5b632f8e9", size = 1319770, upload_time = "2024-10-12T11:29:20.661Z" }, + { url = "https://files.pythonhosted.org/packages/f2/12/0b69ed61fba59551a5f3d569af367afae614db7214ce1da12946ba9a433a/marisa_trie-1.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36aa4401a1180615f74d575571a6550081d84fc6461e9aefc0bb7b2427af098e", size = 1356488, upload_time = "2024-10-12T11:29:21.95Z" }, + { url = "https://files.pythonhosted.org/packages/33/23/483b110db7ffe8729d6ebea2bf74258aef51f10fef5775f99e4bac7aef69/marisa_trie-1.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce59bcd2cda9bb52b0e90cc7f36413cd86c3d0ce7224143447424aafb9f4aa48", size = 1302334, upload_time = "2024-10-12T11:29:24.217Z" }, + { url = "https://files.pythonhosted.org/packages/1c/6f/46c2be99ce925985127fdf78900f1673bce8cb72debfebee6dccd11032c6/marisa_trie-1.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f4cd800704a5fc57e53c39c3a6b0c9b1519ebdbcb644ede3ee67a06eb542697d", size = 2202624, upload_time = "2024-10-12T11:29:25.499Z" }, + { url = "https://files.pythonhosted.org/packages/fd/b6/ef642327dbd4ec35be55d5682520b8f70fca98a54024f441ef2732f6b305/marisa_trie-1.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2428b495003c189695fb91ceeb499f9fcced3a2dce853e17fa475519433c67ff", size = 2364206, upload_time = "2024-10-12T11:29:26.771Z" }, + { url = "https://files.pythonhosted.org/packages/69/04/ef8197a79d0ab5043b781cc9b457bd11b81d4204fe78adf7625a67f48c21/marisa_trie-1.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:735c363d9aaac82eaf516a28f7c6b95084c2e176d8231c87328dc80e112a9afa", size = 2304801, upload_time = "2024-10-12T11:29:28.095Z" }, + { url = "https://files.pythonhosted.org/packages/03/72/f87564d653daf31d8f33d9bf0121e99ccc21f18f5c485fb404ba06abc10e/marisa_trie-1.2.1-cp313-cp313-win32.whl", hash = "sha256:eba6ca45500ca1a042466a0684aacc9838e7f20fe2605521ee19f2853062798f", size = 128799, upload_time = "2024-10-12T11:29:30.28Z" }, + { url = "https://files.pythonhosted.org/packages/27/40/5f9eb8b73030cc4b0d6817176e66079a62a2ddd9d5530da54f8011473428/marisa_trie-1.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:aa7cd17e1c690ce96c538b2f4aae003d9a498e65067dd433c52dd069009951d4", size = 149035, upload_time = "2024-10-12T11:29:31.332Z" }, +] + +[[package]] +name = "markdown" +version = "3.8.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/c2/4ab49206c17f75cb08d6311171f2d65798988db4360c4d1485bd0eedd67c/markdown-3.8.2.tar.gz", hash = "sha256:247b9a70dd12e27f67431ce62523e675b866d254f900c4fe75ce3dda62237c45", size = 362071, upload_time = "2025-06-19T17:12:44.483Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/2b/34cc11786bc00d0f04d0f5fdc3a2b1ae0b6239eef72d3d345805f9ad92a1/markdown-3.8.2-py3-none-any.whl", hash = "sha256:5c83764dbd4e00bdd94d85a19b8d55ccca20fe35b2e678a1422b380324dd5f24", size = 106827, upload_time = "2025-06-19T17:12:42.994Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload_time = "2023-06-03T06:41:14.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload_time = "2023-06-03T06:41:11.019Z" }, +] + +[[package]] +name = "markupsafe" +version = "2.1.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384, upload_time = "2024-02-02T16:31:22.863Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/54/ad5eb37bf9d51800010a74e4665425831a9db4e7c4e0fde4352e391e808e/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", size = 18206, upload_time = "2024-02-02T16:30:04.105Z" }, + { url = "https://files.pythonhosted.org/packages/6a/4a/a4d49415e600bacae038c67f9fecc1d5433b9d3c71a4de6f33537b89654c/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", size = 14079, upload_time = "2024-02-02T16:30:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/0a/7b/85681ae3c33c385b10ac0f8dd025c30af83c78cec1c37a6aa3b55e67f5ec/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", size = 26620, upload_time = "2024-02-02T16:30:08.31Z" }, + { url = "https://files.pythonhosted.org/packages/7c/52/2b1b570f6b8b803cef5ac28fdf78c0da318916c7d2fe9402a84d591b394c/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", size = 25818, upload_time = "2024-02-02T16:30:09.577Z" }, + { url = "https://files.pythonhosted.org/packages/29/fe/a36ba8c7ca55621620b2d7c585313efd10729e63ef81e4e61f52330da781/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", size = 25493, upload_time = "2024-02-02T16:30:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/60/ae/9c60231cdfda003434e8bd27282b1f4e197ad5a710c14bee8bea8a9ca4f0/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", size = 30630, upload_time = "2024-02-02T16:30:13.144Z" }, + { url = "https://files.pythonhosted.org/packages/65/dc/1510be4d179869f5dafe071aecb3f1f41b45d37c02329dfba01ff59e5ac5/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", size = 29745, upload_time = "2024-02-02T16:30:14.222Z" }, + { url = "https://files.pythonhosted.org/packages/30/39/8d845dd7d0b0613d86e0ef89549bfb5f61ed781f59af45fc96496e897f3a/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", size = 30021, upload_time = "2024-02-02T16:30:16.032Z" }, + { url = "https://files.pythonhosted.org/packages/c7/5c/356a6f62e4f3c5fbf2602b4771376af22a3b16efa74eb8716fb4e328e01e/MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", size = 16659, upload_time = "2024-02-02T16:30:17.079Z" }, + { url = "https://files.pythonhosted.org/packages/69/48/acbf292615c65f0604a0c6fc402ce6d8c991276e16c80c46a8f758fbd30c/MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", size = 17213, upload_time = "2024-02-02T16:30:18.251Z" }, + { url = "https://files.pythonhosted.org/packages/11/e7/291e55127bb2ae67c64d66cef01432b5933859dfb7d6949daa721b89d0b3/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", size = 18219, upload_time = "2024-02-02T16:30:19.988Z" }, + { url = "https://files.pythonhosted.org/packages/6b/cb/aed7a284c00dfa7c0682d14df85ad4955a350a21d2e3b06d8240497359bf/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", size = 14098, upload_time = "2024-02-02T16:30:21.063Z" }, + { url = "https://files.pythonhosted.org/packages/1c/cf/35fe557e53709e93feb65575c93927942087e9b97213eabc3fe9d5b25a55/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", size = 29014, upload_time = "2024-02-02T16:30:22.926Z" }, + { url = "https://files.pythonhosted.org/packages/97/18/c30da5e7a0e7f4603abfc6780574131221d9148f323752c2755d48abad30/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", size = 28220, upload_time = "2024-02-02T16:30:24.76Z" }, + { url = "https://files.pythonhosted.org/packages/0c/40/2e73e7d532d030b1e41180807a80d564eda53babaf04d65e15c1cf897e40/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", size = 27756, upload_time = "2024-02-02T16:30:25.877Z" }, + { url = "https://files.pythonhosted.org/packages/18/46/5dca760547e8c59c5311b332f70605d24c99d1303dd9a6e1fc3ed0d73561/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", size = 33988, upload_time = "2024-02-02T16:30:26.935Z" }, + { url = "https://files.pythonhosted.org/packages/6d/c5/27febe918ac36397919cd4a67d5579cbbfa8da027fa1238af6285bb368ea/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", size = 32718, upload_time = "2024-02-02T16:30:28.111Z" }, + { url = "https://files.pythonhosted.org/packages/f8/81/56e567126a2c2bc2684d6391332e357589a96a76cb9f8e5052d85cb0ead8/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", size = 33317, upload_time = "2024-02-02T16:30:29.214Z" }, + { url = "https://files.pythonhosted.org/packages/00/0b/23f4b2470accb53285c613a3ab9ec19dc944eaf53592cb6d9e2af8aa24cc/MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", size = 16670, upload_time = "2024-02-02T16:30:30.915Z" }, + { url = "https://files.pythonhosted.org/packages/b7/a2/c78a06a9ec6d04b3445a949615c4c7ed86a0b2eb68e44e7541b9d57067cc/MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", size = 17224, upload_time = "2024-02-02T16:30:32.09Z" }, + { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215, upload_time = "2024-02-02T16:30:33.081Z" }, + { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069, upload_time = "2024-02-02T16:30:34.148Z" }, + { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452, upload_time = "2024-02-02T16:30:35.149Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462, upload_time = "2024-02-02T16:30:36.166Z" }, + { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869, upload_time = "2024-02-02T16:30:37.834Z" }, + { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906, upload_time = "2024-02-02T16:30:39.366Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296, upload_time = "2024-02-02T16:30:40.413Z" }, + { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038, upload_time = "2024-02-02T16:30:42.243Z" }, + { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572, upload_time = "2024-02-02T16:30:43.326Z" }, + { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127, upload_time = "2024-02-02T16:30:44.418Z" }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload_time = "2022-01-24T01:14:51.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload_time = "2022-01-24T01:14:49.62Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload_time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload_time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mmh3" +version = "5.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/47/1b/1fc6888c74cbd8abad1292dde2ddfcf8fc059e114c97dd6bf16d12f36293/mmh3-5.1.0.tar.gz", hash = "sha256:136e1e670500f177f49ec106a4ebf0adf20d18d96990cc36ea492c651d2b406c", size = 33728, upload_time = "2025-01-25T08:39:43.386Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/01/9d06468928661765c0fc248a29580c760a4a53a9c6c52cf72528bae3582e/mmh3-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eaf4ac5c6ee18ca9232238364d7f2a213278ae5ca97897cafaa123fcc7bb8bec", size = 56095, upload_time = "2025-01-25T08:37:53.621Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/7b39307fc9db867b2a9a20c58b0de33b778dd6c55e116af8ea031f1433ba/mmh3-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:48f9aa8ccb9ad1d577a16104834ac44ff640d8de8c0caed09a2300df7ce8460a", size = 40512, upload_time = "2025-01-25T08:37:54.972Z" }, + { url = "https://files.pythonhosted.org/packages/4f/85/728ca68280d8ccc60c113ad119df70ff1748fbd44c89911fed0501faf0b8/mmh3-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d4ba8cac21e1f2d4e436ce03a82a7f87cda80378691f760e9ea55045ec480a3d", size = 40110, upload_time = "2025-01-25T08:37:57.86Z" }, + { url = "https://files.pythonhosted.org/packages/e4/96/beaf0e301472ffa00358bbbf771fe2d9c4d709a2fe30b1d929e569f8cbdf/mmh3-5.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d69281c281cb01994f054d862a6bb02a2e7acfe64917795c58934b0872b9ece4", size = 100151, upload_time = "2025-01-25T08:37:59.609Z" }, + { url = "https://files.pythonhosted.org/packages/c3/ee/9381f825c4e09ffafeffa213c3865c4bf7d39771640de33ab16f6faeb854/mmh3-5.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d05ed3962312fbda2a1589b97359d2467f677166952f6bd410d8c916a55febf", size = 106312, upload_time = "2025-01-25T08:38:02.102Z" }, + { url = "https://files.pythonhosted.org/packages/67/dc/350a54bea5cf397d357534198ab8119cfd0d8e8bad623b520f9c290af985/mmh3-5.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78ae6a03f4cff4aa92ddd690611168856f8c33a141bd3e5a1e0a85521dc21ea0", size = 104232, upload_time = "2025-01-25T08:38:03.852Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5d/2c6eb4a4ec2f7293b98a9c07cb8c64668330b46ff2b6511244339e69a7af/mmh3-5.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95f983535b39795d9fb7336438faae117424c6798f763d67c6624f6caf2c4c01", size = 91663, upload_time = "2025-01-25T08:38:06.24Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ac/17030d24196f73ecbab8b5033591e5e0e2beca103181a843a135c78f4fee/mmh3-5.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d46fdd80d4c7ecadd9faa6181e92ccc6fe91c50991c9af0e371fdf8b8a7a6150", size = 99166, upload_time = "2025-01-25T08:38:07.988Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ed/54ddc56603561a10b33da9b12e95a48a271d126f4a4951841bbd13145ebf/mmh3-5.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0f16e976af7365ea3b5c425124b2a7f0147eed97fdbb36d99857f173c8d8e096", size = 101555, upload_time = "2025-01-25T08:38:09.821Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c3/33fb3a940c9b70908a5cc9fcc26534aff8698180f9f63ab6b7cc74da8bcd/mmh3-5.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6fa97f7d1e1f74ad1565127229d510f3fd65d931fdedd707c1e15100bc9e5ebb", size = 94813, upload_time = "2025-01-25T08:38:11.682Z" }, + { url = "https://files.pythonhosted.org/packages/61/88/c9ff76a23abe34db8eee1a6fa4e449462a16c7eb547546fc5594b0860a72/mmh3-5.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4052fa4a8561bd62648e9eb993c8f3af3bdedadf3d9687aa4770d10e3709a80c", size = 109611, upload_time = "2025-01-25T08:38:12.602Z" }, + { url = "https://files.pythonhosted.org/packages/0b/8e/27d04f40e95554ebe782cac7bddda2d158cf3862387298c9c7b254fa7beb/mmh3-5.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3f0e8ae9f961037f812afe3cce7da57abf734285961fffbeff9a4c011b737732", size = 100515, upload_time = "2025-01-25T08:38:16.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/00/504ca8f462f01048f3c87cd93f2e1f60b93dac2f930cd4ed73532a9337f5/mmh3-5.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:99297f207db967814f1f02135bb7fe7628b9eacb046134a34e1015b26b06edce", size = 100177, upload_time = "2025-01-25T08:38:18.186Z" }, + { url = "https://files.pythonhosted.org/packages/6f/1d/2efc3525fe6fdf8865972fcbb884bd1f4b0f923c19b80891cecf7e239fa5/mmh3-5.1.0-cp310-cp310-win32.whl", hash = "sha256:2e6c8dc3631a5e22007fbdb55e993b2dbce7985c14b25b572dd78403c2e79182", size = 40815, upload_time = "2025-01-25T08:38:19.176Z" }, + { url = "https://files.pythonhosted.org/packages/38/b5/c8fbe707cb0fea77a6d2d58d497bc9b67aff80deb84d20feb34d8fdd8671/mmh3-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:e4e8c7ad5a4dddcfde35fd28ef96744c1ee0f9d9570108aa5f7e77cf9cfdf0bf", size = 41479, upload_time = "2025-01-25T08:38:21.098Z" }, + { url = "https://files.pythonhosted.org/packages/a1/f1/663e16134f913fccfbcea5b300fb7dc1860d8f63dc71867b013eebc10aec/mmh3-5.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:45da549269883208912868a07d0364e1418d8292c4259ca11699ba1b2475bd26", size = 38883, upload_time = "2025-01-25T08:38:22.013Z" }, + { url = "https://files.pythonhosted.org/packages/56/09/fda7af7fe65928262098382e3bf55950cfbf67d30bf9e47731bf862161e9/mmh3-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b529dcda3f951ff363a51d5866bc6d63cf57f1e73e8961f864ae5010647079d", size = 56098, upload_time = "2025-01-25T08:38:22.917Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ab/84c7bc3f366d6f3bd8b5d9325a10c367685bc17c26dac4c068e2001a4671/mmh3-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db1079b3ace965e562cdfc95847312f9273eb2ad3ebea983435c8423e06acd7", size = 40513, upload_time = "2025-01-25T08:38:25.079Z" }, + { url = "https://files.pythonhosted.org/packages/4f/21/25ea58ca4a652bdc83d1528bec31745cce35802381fb4fe3c097905462d2/mmh3-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:22d31e3a0ff89b8eb3b826d6fc8e19532998b2aa6b9143698043a1268da413e1", size = 40112, upload_time = "2025-01-25T08:38:25.947Z" }, + { url = "https://files.pythonhosted.org/packages/bd/78/4f12f16ae074ddda6f06745254fdb50f8cf3c85b0bbf7eaca58bed84bf58/mmh3-5.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2139bfbd354cd6cb0afed51c4b504f29bcd687a3b1460b7e89498329cc28a894", size = 102632, upload_time = "2025-01-25T08:38:26.939Z" }, + { url = "https://files.pythonhosted.org/packages/48/11/8f09dc999cf2a09b6138d8d7fc734efb7b7bfdd9adb9383380941caadff0/mmh3-5.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c8105c6a435bc2cd6ea2ef59558ab1a2976fd4a4437026f562856d08996673a", size = 108884, upload_time = "2025-01-25T08:38:29.159Z" }, + { url = "https://files.pythonhosted.org/packages/bd/91/e59a66538a3364176f6c3f7620eee0ab195bfe26f89a95cbcc7a1fb04b28/mmh3-5.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57730067174a7f36fcd6ce012fe359bd5510fdaa5fe067bc94ed03e65dafb769", size = 106835, upload_time = "2025-01-25T08:38:33.04Z" }, + { url = "https://files.pythonhosted.org/packages/25/14/b85836e21ab90e5cddb85fe79c494ebd8f81d96a87a664c488cc9277668b/mmh3-5.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bde80eb196d7fdc765a318604ded74a4378f02c5b46c17aa48a27d742edaded2", size = 93688, upload_time = "2025-01-25T08:38:34.987Z" }, + { url = "https://files.pythonhosted.org/packages/ac/aa/8bc964067df9262740c95e4cde2d19f149f2224f426654e14199a9e47df6/mmh3-5.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9c8eddcb441abddeb419c16c56fd74b3e2df9e57f7aa2903221996718435c7a", size = 101569, upload_time = "2025-01-25T08:38:35.983Z" }, + { url = "https://files.pythonhosted.org/packages/70/b6/1fb163cbf919046a64717466c00edabebece3f95c013853fec76dbf2df92/mmh3-5.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:99e07e4acafbccc7a28c076a847fb060ffc1406036bc2005acb1b2af620e53c3", size = 98483, upload_time = "2025-01-25T08:38:38.198Z" }, + { url = "https://files.pythonhosted.org/packages/70/49/ba64c050dd646060f835f1db6b2cd60a6485f3b0ea04976e7a29ace7312e/mmh3-5.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9e25ba5b530e9a7d65f41a08d48f4b3fedc1e89c26486361166a5544aa4cad33", size = 96496, upload_time = "2025-01-25T08:38:39.257Z" }, + { url = "https://files.pythonhosted.org/packages/9e/07/f2751d6a0b535bb865e1066e9c6b80852571ef8d61bce7eb44c18720fbfc/mmh3-5.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bb9bf7475b4d99156ce2f0cf277c061a17560c8c10199c910a680869a278ddc7", size = 105109, upload_time = "2025-01-25T08:38:40.395Z" }, + { url = "https://files.pythonhosted.org/packages/b7/02/30360a5a66f7abba44596d747cc1e6fb53136b168eaa335f63454ab7bb79/mmh3-5.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a1b0878dd281ea3003368ab53ff6f568e175f1b39f281df1da319e58a19c23a", size = 98231, upload_time = "2025-01-25T08:38:42.141Z" }, + { url = "https://files.pythonhosted.org/packages/8c/60/8526b0c750ff4d7ae1266e68b795f14b97758a1d9fcc19f6ecabf9c55656/mmh3-5.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:25f565093ac8b8aefe0f61f8f95c9a9d11dd69e6a9e9832ff0d293511bc36258", size = 97548, upload_time = "2025-01-25T08:38:43.402Z" }, + { url = "https://files.pythonhosted.org/packages/6d/4c/26e1222aca65769280d5427a1ce5875ef4213449718c8f03958d0bf91070/mmh3-5.1.0-cp311-cp311-win32.whl", hash = "sha256:1e3554d8792387eac73c99c6eaea0b3f884e7130eb67986e11c403e4f9b6d372", size = 40810, upload_time = "2025-01-25T08:38:45.143Z" }, + { url = "https://files.pythonhosted.org/packages/98/d5/424ba95062d1212ea615dc8debc8d57983f2242d5e6b82e458b89a117a1e/mmh3-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8ad777a48197882492af50bf3098085424993ce850bdda406a358b6ab74be759", size = 41476, upload_time = "2025-01-25T08:38:46.029Z" }, + { url = "https://files.pythonhosted.org/packages/bd/08/0315ccaf087ba55bb19a6dd3b1e8acd491e74ce7f5f9c4aaa06a90d66441/mmh3-5.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f29dc4efd99bdd29fe85ed6c81915b17b2ef2cf853abf7213a48ac6fb3eaabe1", size = 38880, upload_time = "2025-01-25T08:38:47.035Z" }, + { url = "https://files.pythonhosted.org/packages/f4/47/e5f452bdf16028bfd2edb4e2e35d0441e4a4740f30e68ccd4cfd2fb2c57e/mmh3-5.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:45712987367cb9235026e3cbf4334670522a97751abfd00b5bc8bfa022c3311d", size = 56152, upload_time = "2025-01-25T08:38:47.902Z" }, + { url = "https://files.pythonhosted.org/packages/60/38/2132d537dc7a7fdd8d2e98df90186c7fcdbd3f14f95502a24ba443c92245/mmh3-5.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b1020735eb35086ab24affbea59bb9082f7f6a0ad517cb89f0fc14f16cea4dae", size = 40564, upload_time = "2025-01-25T08:38:48.839Z" }, + { url = "https://files.pythonhosted.org/packages/c0/2a/c52cf000581bfb8d94794f58865658e7accf2fa2e90789269d4ae9560b16/mmh3-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:babf2a78ce5513d120c358722a2e3aa7762d6071cd10cede026f8b32452be322", size = 40104, upload_time = "2025-01-25T08:38:49.773Z" }, + { url = "https://files.pythonhosted.org/packages/83/33/30d163ce538c54fc98258db5621447e3ab208d133cece5d2577cf913e708/mmh3-5.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4f47f58cd5cbef968c84a7c1ddc192fef0a36b48b0b8a3cb67354531aa33b00", size = 102634, upload_time = "2025-01-25T08:38:51.5Z" }, + { url = "https://files.pythonhosted.org/packages/94/5c/5a18acb6ecc6852be2d215c3d811aa61d7e425ab6596be940877355d7f3e/mmh3-5.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2044a601c113c981f2c1e14fa33adc9b826c9017034fe193e9eb49a6882dbb06", size = 108888, upload_time = "2025-01-25T08:38:52.542Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f6/11c556324c64a92aa12f28e221a727b6e082e426dc502e81f77056f6fc98/mmh3-5.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c94d999c9f2eb2da44d7c2826d3fbffdbbbbcde8488d353fee7c848ecc42b968", size = 106968, upload_time = "2025-01-25T08:38:54.286Z" }, + { url = "https://files.pythonhosted.org/packages/5d/61/ca0c196a685aba7808a5c00246f17b988a9c4f55c594ee0a02c273e404f3/mmh3-5.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a015dcb24fa0c7a78f88e9419ac74f5001c1ed6a92e70fd1803f74afb26a4c83", size = 93771, upload_time = "2025-01-25T08:38:55.576Z" }, + { url = "https://files.pythonhosted.org/packages/b4/55/0927c33528710085ee77b808d85bbbafdb91a1db7c8eaa89cac16d6c513e/mmh3-5.1.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:457da019c491a2d20e2022c7d4ce723675e4c081d9efc3b4d8b9f28a5ea789bd", size = 101726, upload_time = "2025-01-25T08:38:56.654Z" }, + { url = "https://files.pythonhosted.org/packages/49/39/a92c60329fa470f41c18614a93c6cd88821412a12ee78c71c3f77e1cfc2d/mmh3-5.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:71408579a570193a4ac9c77344d68ddefa440b00468a0b566dcc2ba282a9c559", size = 98523, upload_time = "2025-01-25T08:38:57.662Z" }, + { url = "https://files.pythonhosted.org/packages/81/90/26adb15345af8d9cf433ae1b6adcf12e0a4cad1e692de4fa9f8e8536c5ae/mmh3-5.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8b3a04bc214a6e16c81f02f855e285c6df274a2084787eeafaa45f2fbdef1b63", size = 96628, upload_time = "2025-01-25T08:38:59.505Z" }, + { url = "https://files.pythonhosted.org/packages/8a/4d/340d1e340df972a13fd4ec84c787367f425371720a1044220869c82364e9/mmh3-5.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:832dae26a35514f6d3c1e267fa48e8de3c7b978afdafa0529c808ad72e13ada3", size = 105190, upload_time = "2025-01-25T08:39:00.483Z" }, + { url = "https://files.pythonhosted.org/packages/d3/7c/65047d1cccd3782d809936db446430fc7758bda9def5b0979887e08302a2/mmh3-5.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bf658a61fc92ef8a48945ebb1076ef4ad74269e353fffcb642dfa0890b13673b", size = 98439, upload_time = "2025-01-25T08:39:01.484Z" }, + { url = "https://files.pythonhosted.org/packages/72/d2/3c259d43097c30f062050f7e861075099404e8886b5d4dd3cebf180d6e02/mmh3-5.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3313577453582b03383731b66447cdcdd28a68f78df28f10d275d7d19010c1df", size = 97780, upload_time = "2025-01-25T08:39:02.444Z" }, + { url = "https://files.pythonhosted.org/packages/29/29/831ea8d4abe96cdb3e28b79eab49cac7f04f9c6b6e36bfc686197ddba09d/mmh3-5.1.0-cp312-cp312-win32.whl", hash = "sha256:1d6508504c531ab86c4424b5a5ff07c1132d063863339cf92f6657ff7a580f76", size = 40835, upload_time = "2025-01-25T08:39:03.369Z" }, + { url = "https://files.pythonhosted.org/packages/12/dd/7cbc30153b73f08eeac43804c1dbc770538a01979b4094edbe1a4b8eb551/mmh3-5.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:aa75981fcdf3f21759d94f2c81b6a6e04a49dfbcdad88b152ba49b8e20544776", size = 41509, upload_time = "2025-01-25T08:39:04.284Z" }, + { url = "https://files.pythonhosted.org/packages/80/9d/627375bab4c90dd066093fc2c9a26b86f87e26d980dbf71667b44cbee3eb/mmh3-5.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:a4c1a76808dfea47f7407a0b07aaff9087447ef6280716fd0783409b3088bb3c", size = 38888, upload_time = "2025-01-25T08:39:05.174Z" }, + { url = "https://files.pythonhosted.org/packages/05/06/a098a42870db16c0a54a82c56a5bdc873de3165218cd5b3ca59dbc0d31a7/mmh3-5.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a523899ca29cfb8a5239618474a435f3d892b22004b91779fcb83504c0d5b8c", size = 56165, upload_time = "2025-01-25T08:39:06.887Z" }, + { url = "https://files.pythonhosted.org/packages/5a/65/eaada79a67fde1f43e1156d9630e2fb70655e1d3f4e8f33d7ffa31eeacfd/mmh3-5.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:17cef2c3a6ca2391ca7171a35ed574b5dab8398163129a3e3a4c05ab85a4ff40", size = 40569, upload_time = "2025-01-25T08:39:07.945Z" }, + { url = "https://files.pythonhosted.org/packages/36/7e/2b6c43ed48be583acd68e34d16f19209a9f210e4669421b0321e326d8554/mmh3-5.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:52e12895b30110f3d89dae59a888683cc886ed0472dd2eca77497edef6161997", size = 40104, upload_time = "2025-01-25T08:39:09.598Z" }, + { url = "https://files.pythonhosted.org/packages/11/2b/1f9e962fdde8e41b0f43d22c8ba719588de8952f9376df7d73a434827590/mmh3-5.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d6719045cda75c3f40397fc24ab67b18e0cb8f69d3429ab4c39763c4c608dd", size = 102497, upload_time = "2025-01-25T08:39:10.512Z" }, + { url = "https://files.pythonhosted.org/packages/46/94/d6c5c3465387ba077cccdc028ab3eec0d86eed1eebe60dcf4d15294056be/mmh3-5.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d19fa07d303a91f8858982c37e6939834cb11893cb3ff20e6ee6fa2a7563826a", size = 108834, upload_time = "2025-01-25T08:39:11.568Z" }, + { url = "https://files.pythonhosted.org/packages/34/1e/92c212bb81796b69dddfd50a8a8f4b26ab0d38fdaf1d3e8628a67850543b/mmh3-5.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31b47a620d622fbde8ca1ca0435c5d25de0ac57ab507209245e918128e38e676", size = 106936, upload_time = "2025-01-25T08:39:12.638Z" }, + { url = "https://files.pythonhosted.org/packages/f4/41/f2f494bbff3aad5ffd2085506255049de76cde51ddac84058e32768acc79/mmh3-5.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00f810647c22c179b6821079f7aa306d51953ac893587ee09cf1afb35adf87cb", size = 93709, upload_time = "2025-01-25T08:39:14.071Z" }, + { url = "https://files.pythonhosted.org/packages/9e/a9/a2cc4a756d73d9edf4fb85c76e16fd56b0300f8120fd760c76b28f457730/mmh3-5.1.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6128b610b577eed1e89ac7177ab0c33d06ade2aba93f5c89306032306b5f1c6", size = 101623, upload_time = "2025-01-25T08:39:15.507Z" }, + { url = "https://files.pythonhosted.org/packages/5e/6f/b9d735533b6a56b2d56333ff89be6a55ac08ba7ff33465feb131992e33eb/mmh3-5.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1e550a45d2ff87a1c11b42015107f1778c93f4c6f8e731bf1b8fa770321b8cc4", size = 98521, upload_time = "2025-01-25T08:39:16.77Z" }, + { url = "https://files.pythonhosted.org/packages/99/47/dff2b54fac0d421c1e6ecbd2d9c85b2d0e6f6ee0d10b115d9364116a511e/mmh3-5.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:785ae09276342f79fd8092633e2d52c0f7c44d56e8cfda8274ccc9b76612dba2", size = 96696, upload_time = "2025-01-25T08:39:17.805Z" }, + { url = "https://files.pythonhosted.org/packages/be/43/9e205310f47c43ddf1575bb3a1769c36688f30f1ac105e0f0c878a29d2cd/mmh3-5.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0f4be3703a867ef976434afd3661a33884abe73ceb4ee436cac49d3b4c2aaa7b", size = 105234, upload_time = "2025-01-25T08:39:18.908Z" }, + { url = "https://files.pythonhosted.org/packages/6b/44/90b11fd2b67dcb513f5bfe9b476eb6ca2d5a221c79b49884dc859100905e/mmh3-5.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e513983830c4ff1f205ab97152a0050cf7164f1b4783d702256d39c637b9d107", size = 98449, upload_time = "2025-01-25T08:39:20.719Z" }, + { url = "https://files.pythonhosted.org/packages/f0/d0/25c4b0c7b8e49836541059b28e034a4cccd0936202800d43a1cc48495ecb/mmh3-5.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9135c300535c828c0bae311b659f33a31c941572eae278568d1a953c4a57b59", size = 97796, upload_time = "2025-01-25T08:39:22.453Z" }, + { url = "https://files.pythonhosted.org/packages/23/fa/cbbb7fcd0e287a715f1cd28a10de94c0535bd94164e38b852abc18da28c6/mmh3-5.1.0-cp313-cp313-win32.whl", hash = "sha256:c65dbd12885a5598b70140d24de5839551af5a99b29f9804bb2484b29ef07692", size = 40828, upload_time = "2025-01-25T08:39:23.372Z" }, + { url = "https://files.pythonhosted.org/packages/09/33/9fb90ef822f7b734955a63851907cf72f8a3f9d8eb3c5706bfa6772a2a77/mmh3-5.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:10db7765201fc65003fa998faa067417ef6283eb5f9bba8f323c48fd9c33e91f", size = 41504, upload_time = "2025-01-25T08:39:24.286Z" }, + { url = "https://files.pythonhosted.org/packages/16/71/4ad9a42f2772793a03cb698f0fc42499f04e6e8d2560ba2f7da0fb059a8e/mmh3-5.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:b22fe2e54be81f6c07dcb36b96fa250fb72effe08aa52fbb83eade6e1e2d5fd7", size = 38890, upload_time = "2025-01-25T08:39:25.28Z" }, +] + +[[package]] +name = "more-itertools" +version = "10.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/78/65922308c4248e0eb08ebcbe67c95d48615cc6f27854b6f2e57143e9178f/more-itertools-10.5.0.tar.gz", hash = "sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6", size = 121020, upload_time = "2024-09-05T15:28:22.081Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/7e/3a64597054a70f7c86eb0a7d4fc315b8c1ab932f64883a297bdffeb5f967/more_itertools-10.5.0-py3-none-any.whl", hash = "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", size = 60952, upload_time = "2024-09-05T15:28:20.141Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload_time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload_time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "murmurhash" +version = "1.0.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/e9/02efbc6dfc2dd2085da3daacf9a8c17e8356019eceaedbfa21555e32d2af/murmurhash-1.0.13.tar.gz", hash = "sha256:737246d41ee00ff74b07b0bd1f0888be304d203ce668e642c86aa64ede30f8b7", size = 13258, upload_time = "2025-05-22T12:35:57.019Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/c3/ac14ed2aff4f18eadccf7d4e80c2361cf6e9a6a350442db9987919c4a747/murmurhash-1.0.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:136c7017e7d59ef16f065c2285bf5d30557ad8260adf47714c3c2802725e3e07", size = 26278, upload_time = "2025-05-22T12:35:10.16Z" }, + { url = "https://files.pythonhosted.org/packages/62/38/87e5f72aa96a0a816b90cd66209cda713e168d4d23b52af62fdba3c8b33c/murmurhash-1.0.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d0292f6fcd99361157fafad5c86d508f367931b7699cce1e14747364596950cb", size = 26528, upload_time = "2025-05-22T12:35:12.181Z" }, + { url = "https://files.pythonhosted.org/packages/6a/df/f74b22acf2ebf04ea24b858667836c9490e677ef29c1fe7bc993ecf4bc12/murmurhash-1.0.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12265dc748257966c62041b677201b8fa74334a2548dc27f1c7a9e78dab7c2c1", size = 120045, upload_time = "2025-05-22T12:35:13.657Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/19c48d4c5ad475e144fba5b1adf45d8a189eabde503168660e1ec5d081e8/murmurhash-1.0.13-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e411d5be64d37f2ce10a5d4d74c50bb35bd06205745b9631c4d8b1cb193e540", size = 117103, upload_time = "2025-05-22T12:35:14.899Z" }, + { url = "https://files.pythonhosted.org/packages/48/0e/3d6e009c539709f0cf643679977e2dfbd5d50e1ef49928f9a92941839482/murmurhash-1.0.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:da3500ad3dbf75ac9c6bc8c5fbc677d56dfc34aec0a289269939d059f194f61d", size = 118191, upload_time = "2025-05-22T12:35:16.098Z" }, + { url = "https://files.pythonhosted.org/packages/7c/8c/fab9d11bde62783d2aa7919e1ecbbf12dea7100ea61f63f55c9e0f199a6a/murmurhash-1.0.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b23278c5428fc14f3101f8794f38ec937da042198930073e8c86d00add0fa2f0", size = 118663, upload_time = "2025-05-22T12:35:17.847Z" }, + { url = "https://files.pythonhosted.org/packages/cf/23/322d87ab935782f2676a836ea88d92f87e58db40fb49112ba03b03d335a1/murmurhash-1.0.13-cp310-cp310-win_amd64.whl", hash = "sha256:7bc27226c0e8d9927f8e59af0dfefc93f5009e4ec3dde8da4ba7751ba19edd47", size = 24504, upload_time = "2025-05-22T12:35:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d1/9d13a02d9c8bfff10b1f68d19df206eaf2a8011defeccf7eb05ea0b8c54e/murmurhash-1.0.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b20d168370bc3ce82920121b78ab35ae244070a9b18798f4a2e8678fa03bd7e0", size = 26410, upload_time = "2025-05-22T12:35:20.786Z" }, + { url = "https://files.pythonhosted.org/packages/14/b0/3ee762e98cf9a8c2df9c8b377c326f3dd4495066d4eace9066fca46eba7a/murmurhash-1.0.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cef667d2e83bdceea3bc20c586c491fa442662ace1aea66ff5e3a18bb38268d8", size = 26679, upload_time = "2025-05-22T12:35:21.808Z" }, + { url = "https://files.pythonhosted.org/packages/39/06/24618f79cd5aac48490932e50263bddfd1ea90f7123d49bfe806a5982675/murmurhash-1.0.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:507148e50929ba1fce36898808573b9f81c763d5676f3fc6e4e832ff56b66992", size = 125970, upload_time = "2025-05-22T12:35:23.222Z" }, + { url = "https://files.pythonhosted.org/packages/e8/09/0e7afce0a422692506c85474a26fb3a03c1971b2b5f7e7745276c4b3de7f/murmurhash-1.0.13-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d50f6173d266ad165beb8bca6101d824217fc9279f9e9981f4c0245c1e7ee6", size = 123390, upload_time = "2025-05-22T12:35:24.303Z" }, + { url = "https://files.pythonhosted.org/packages/22/4c/c98f579b1a951b2bcc722a35270a2eec105c1e21585c9b314a02079e3c4d/murmurhash-1.0.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0f272e15a84a8ae5f8b4bc0a68f9f47be38518ddffc72405791178058e9d019a", size = 124007, upload_time = "2025-05-22T12:35:25.446Z" }, + { url = "https://files.pythonhosted.org/packages/df/f8/1b0dcebc8df8e091341617102b5b3b97deb6435f345b84f75382c290ec2c/murmurhash-1.0.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9423e0b0964ed1013a06c970199538c7ef9ca28c0be54798c0f1473a6591761", size = 123705, upload_time = "2025-05-22T12:35:26.709Z" }, + { url = "https://files.pythonhosted.org/packages/79/17/f2a38558e150a0669d843f75e128afb83c1a67af41885ea2acb940e18e2a/murmurhash-1.0.13-cp311-cp311-win_amd64.whl", hash = "sha256:83b81e7084b696df3d853f2c78e0c9bda6b285d643f923f1a6fa9ab145d705c5", size = 24572, upload_time = "2025-05-22T12:35:30.38Z" }, + { url = "https://files.pythonhosted.org/packages/e1/53/56ce2d8d4b9ab89557cb1d00ffce346b80a2eb2d8c7944015e5c83eacdec/murmurhash-1.0.13-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bbe882e46cb3f86e092d8a1dd7a5a1c992da1ae3b39f7dd4507b6ce33dae7f92", size = 26859, upload_time = "2025-05-22T12:35:31.815Z" }, + { url = "https://files.pythonhosted.org/packages/f8/85/3a0ad54a61257c31496545ae6861515d640316f93681d1dd917e7be06634/murmurhash-1.0.13-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:52a33a12ecedc432493692c207c784b06b6427ffaa897fc90b7a76e65846478d", size = 26900, upload_time = "2025-05-22T12:35:34.267Z" }, + { url = "https://files.pythonhosted.org/packages/d0/cd/6651de26744b50ff11c79f0c0d41244db039625de53c0467a7a52876b2d8/murmurhash-1.0.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:950403a7f0dc2d9c8d0710f07c296f2daab66299d9677d6c65d6b6fa2cb30aaa", size = 131367, upload_time = "2025-05-22T12:35:35.258Z" }, + { url = "https://files.pythonhosted.org/packages/50/6c/01ded95ddce33811c9766cae4ce32e0a54288da1d909ee2bcaa6ed13b9f1/murmurhash-1.0.13-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fde9fb5d2c106d86ff3ef2e4a9a69c2a8d23ba46e28c6b30034dc58421bc107b", size = 128943, upload_time = "2025-05-22T12:35:36.358Z" }, + { url = "https://files.pythonhosted.org/packages/ab/27/e539a9622d7bea3ae22706c1eb80d4af80f9dddd93b54d151955c2ae4011/murmurhash-1.0.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3aa55d62773745616e1ab19345dece122f6e6d09224f7be939cc5b4c513c8473", size = 129108, upload_time = "2025-05-22T12:35:37.864Z" }, + { url = "https://files.pythonhosted.org/packages/7a/84/18af5662e07d06839ad4db18ce026e6f8ef850d7b0ba92817b28dad28ba6/murmurhash-1.0.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:060dfef1b405cf02c450f182fb629f76ebe7f79657cced2db5054bc29b34938b", size = 129175, upload_time = "2025-05-22T12:35:38.928Z" }, + { url = "https://files.pythonhosted.org/packages/fe/8d/b01d3ee1f1cf3957250223b7c6ce35454f38fbf4abe236bf04a3f769341d/murmurhash-1.0.13-cp312-cp312-win_amd64.whl", hash = "sha256:a8e79627d44a6e20a6487effc30bfe1c74754c13d179106e68cc6d07941b022c", size = 24869, upload_time = "2025-05-22T12:35:40.035Z" }, + { url = "https://files.pythonhosted.org/packages/00/b4/8919dfdc4a131ad38a57b2c5de69f4bd74538bf546637ee59ebaebe6e5a4/murmurhash-1.0.13-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b8a7f8befd901379b6dc57a9e49c5188454113747ad6aa8cdd951a6048e10790", size = 26852, upload_time = "2025-05-22T12:35:41.061Z" }, + { url = "https://files.pythonhosted.org/packages/b4/32/ce78bef5d6101568bcb12f5bb5103fabcbe23723ec52e76ff66132d5dbb7/murmurhash-1.0.13-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f741aab86007510199193eee4f87c5ece92bc5a6ca7d0fe0d27335c1203dface", size = 26900, upload_time = "2025-05-22T12:35:42.097Z" }, + { url = "https://files.pythonhosted.org/packages/0c/4c/0f47c0b4f6b31a1de84d65f9573832c78cd47b4b8ce25ab5596a8238d150/murmurhash-1.0.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82614f18fa6d9d83da6bb0918f3789a3e1555d0ce12c2548153e97f79b29cfc9", size = 130033, upload_time = "2025-05-22T12:35:43.113Z" }, + { url = "https://files.pythonhosted.org/packages/e0/cb/e47233e32fb792dcc9fb18a2cf65f795d47179b29c2b4a2034689f14c707/murmurhash-1.0.13-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91f22a48b9454712e0690aa0b76cf0156a5d5a083d23ec7e209cfaeef28f56ff", size = 130619, upload_time = "2025-05-22T12:35:44.229Z" }, + { url = "https://files.pythonhosted.org/packages/8f/f1/f89911bf304ba5d385ccd346cc7fbb1c1450a24f093b592c3bfe87768467/murmurhash-1.0.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c4bc7938627b8fcb3d598fe6657cc96d1e31f4eba6a871b523c1512ab6dacb3e", size = 127643, upload_time = "2025-05-22T12:35:45.369Z" }, + { url = "https://files.pythonhosted.org/packages/a4/24/262229221f6840c1a04a46051075e99675e591571abcca6b9a8b6aa1602b/murmurhash-1.0.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58a61f1fc840f9ef704e638c39b8517bab1d21f1a9dbb6ba3ec53e41360e44ec", size = 127981, upload_time = "2025-05-22T12:35:46.503Z" }, + { url = "https://files.pythonhosted.org/packages/18/25/addbc1d28f83252732ac3e57334d42f093890b4c2cce483ba01a42bc607c/murmurhash-1.0.13-cp313-cp313-win_amd64.whl", hash = "sha256:c451a22f14c2f40e7abaea521ee24fa0e46fbec480c4304c25c946cdb6e81883", size = 24880, upload_time = "2025-05-22T12:35:47.625Z" }, +] + +[[package]] +name = "mypy" +version = "1.11.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/86/5d7cbc4974fd564550b80fbb8103c05501ea11aa7835edf3351d90095896/mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79", size = 3078806, upload_time = "2024-08-24T22:50:11.357Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/cd/815368cd83c3a31873e5e55b317551500b12f2d1d7549720632f32630333/mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a", size = 10939401, upload_time = "2024-08-24T22:49:18.929Z" }, + { url = "https://files.pythonhosted.org/packages/f1/27/e18c93a195d2fad75eb96e1f1cbc431842c332e8eba2e2b77eaf7313c6b7/mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef", size = 10111697, upload_time = "2024-08-24T22:49:32.504Z" }, + { url = "https://files.pythonhosted.org/packages/dc/08/cdc1fc6d0d5a67d354741344cc4aa7d53f7128902ebcbe699ddd4f15a61c/mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383", size = 12500508, upload_time = "2024-08-24T22:49:12.327Z" }, + { url = "https://files.pythonhosted.org/packages/64/12/aad3af008c92c2d5d0720ea3b6674ba94a98cdb86888d389acdb5f218c30/mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8", size = 13020712, upload_time = "2024-08-24T22:49:49.399Z" }, + { url = "https://files.pythonhosted.org/packages/03/e6/a7d97cc124a565be5e9b7d5c2a6ebf082379ffba99646e4863ed5bbcb3c3/mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7", size = 9567319, upload_time = "2024-08-24T22:49:26.88Z" }, + { url = "https://files.pythonhosted.org/packages/e2/aa/cc56fb53ebe14c64f1fe91d32d838d6f4db948b9494e200d2f61b820b85d/mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385", size = 10859630, upload_time = "2024-08-24T22:49:51.895Z" }, + { url = "https://files.pythonhosted.org/packages/04/c8/b19a760fab491c22c51975cf74e3d253b8c8ce2be7afaa2490fbf95a8c59/mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca", size = 10037973, upload_time = "2024-08-24T22:49:21.428Z" }, + { url = "https://files.pythonhosted.org/packages/88/57/7e7e39f2619c8f74a22efb9a4c4eff32b09d3798335625a124436d121d89/mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104", size = 12416659, upload_time = "2024-08-24T22:49:35.02Z" }, + { url = "https://files.pythonhosted.org/packages/fc/a6/37f7544666b63a27e46c48f49caeee388bf3ce95f9c570eb5cfba5234405/mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4", size = 12897010, upload_time = "2024-08-24T22:49:29.725Z" }, + { url = "https://files.pythonhosted.org/packages/84/8b/459a513badc4d34acb31c736a0101c22d2bd0697b969796ad93294165cfb/mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6", size = 9562873, upload_time = "2024-08-24T22:49:40.448Z" }, + { url = "https://files.pythonhosted.org/packages/35/3a/ed7b12ecc3f6db2f664ccf85cb2e004d3e90bec928e9d7be6aa2f16b7cdf/mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318", size = 10990335, upload_time = "2024-08-24T22:49:54.245Z" }, + { url = "https://files.pythonhosted.org/packages/04/e4/1a9051e2ef10296d206519f1df13d2cc896aea39e8683302f89bf5792a59/mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36", size = 10007119, upload_time = "2024-08-24T22:49:03.451Z" }, + { url = "https://files.pythonhosted.org/packages/f3/3c/350a9da895f8a7e87ade0028b962be0252d152e0c2fbaafa6f0658b4d0d4/mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987", size = 12506856, upload_time = "2024-08-24T22:50:08.804Z" }, + { url = "https://files.pythonhosted.org/packages/b6/49/ee5adf6a49ff13f4202d949544d3d08abb0ea1f3e7f2a6d5b4c10ba0360a/mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca", size = 12952066, upload_time = "2024-08-24T22:50:03.89Z" }, + { url = "https://files.pythonhosted.org/packages/27/c0/b19d709a42b24004d720db37446a42abadf844d5c46a2c442e2a074d70d9/mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70", size = 9664000, upload_time = "2024-08-24T22:49:59.703Z" }, + { url = "https://files.pythonhosted.org/packages/42/3a/bdf730640ac523229dd6578e8a581795720a9321399de494374afc437ec5/mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12", size = 2619625, upload_time = "2024-08-24T22:50:01.842Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433, upload_time = "2023-02-04T12:11:27.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695, upload_time = "2023-02-04T12:11:25.002Z" }, +] + +[[package]] +name = "networkx" +version = "3.4.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368, upload_time = "2024-10-21T12:39:38.695Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263, upload_time = "2024-10-21T12:39:36.247Z" }, +] + +[[package]] +name = "networkx" +version = "3.5" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", + "python_full_version >= '3.13'", +] +sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065, upload_time = "2025-05-29T11:35:07.804Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec", size = 2034406, upload_time = "2025-05-29T11:35:04.961Z" }, +] + +[[package]] +name = "nltk" +version = "3.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "joblib" }, + { name = "regex" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3c/87/db8be88ad32c2d042420b6fd9ffd4a149f9a0d7f0e86b3f543be2eeeedd2/nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868", size = 2904691, upload_time = "2024-08-18T19:48:37.769Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/66/7d9e26593edda06e8cb531874633f7c2372279c3b0f46235539fe546df8b/nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1", size = 1505442, upload_time = "2024-08-18T19:48:21.909Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload_time = "2024-06-04T18:44:11.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload_time = "2024-06-04T18:44:08.352Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload_time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload_time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload_time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload_time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload_time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload_time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload_time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload_time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload_time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload_time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload_time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload_time = "2025-05-17T21:31:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload_time = "2025-05-17T21:31:41.087Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload_time = "2025-05-17T21:31:50.072Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload_time = "2025-05-17T21:32:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload_time = "2025-05-17T21:32:23.332Z" }, + { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload_time = "2025-05-17T21:32:47.991Z" }, + { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload_time = "2025-05-17T21:33:11.728Z" }, + { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload_time = "2025-05-17T21:33:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload_time = "2025-05-17T21:33:50.273Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload_time = "2025-05-17T21:34:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload_time = "2025-05-17T21:34:39.648Z" }, + { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload_time = "2025-05-17T21:35:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload_time = "2025-05-17T21:35:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload_time = "2025-05-17T21:35:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload_time = "2025-05-17T21:35:42.174Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload_time = "2025-05-17T21:36:06.711Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload_time = "2025-05-17T21:36:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload_time = "2025-05-17T21:36:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload_time = "2025-05-17T21:37:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload_time = "2025-05-17T21:37:26.213Z" }, + { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload_time = "2025-05-17T21:37:56.699Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload_time = "2025-05-17T21:38:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload_time = "2025-05-17T21:38:27.319Z" }, + { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload_time = "2025-05-17T21:38:38.141Z" }, + { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload_time = "2025-05-17T21:38:58.433Z" }, + { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload_time = "2025-05-17T21:39:22.638Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload_time = "2025-05-17T21:39:45.865Z" }, + { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload_time = "2025-05-17T21:40:13.331Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload_time = "2025-05-17T21:43:46.099Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload_time = "2025-05-17T21:44:05.145Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload_time = "2025-05-17T21:40:44Z" }, + { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload_time = "2025-05-17T21:41:05.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload_time = "2025-05-17T21:41:15.903Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload_time = "2025-05-17T21:41:27.321Z" }, + { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload_time = "2025-05-17T21:41:49.738Z" }, + { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload_time = "2025-05-17T21:42:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload_time = "2025-05-17T21:42:37.464Z" }, + { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload_time = "2025-05-17T21:43:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload_time = "2025-05-17T21:43:16.254Z" }, + { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload_time = "2025-05-17T21:43:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload_time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload_time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload_time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload_time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", + "python_full_version >= '3.13'", +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/19/d7c972dfe90a353dbd3efbbe1d14a5951de80c99c9dc1b93cd998d51dc0f/numpy-2.3.1.tar.gz", hash = "sha256:1ec9ae20a4226da374362cca3c62cd753faf2f951440b0e3b98e93c235441d2b", size = 20390372, upload_time = "2025-06-21T12:28:33.469Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/c7/87c64d7ab426156530676000c94784ef55676df2f13b2796f97722464124/numpy-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6ea9e48336a402551f52cd8f593343699003d2353daa4b72ce8d34f66b722070", size = 21199346, upload_time = "2025-06-21T11:47:47.57Z" }, + { url = "https://files.pythonhosted.org/packages/58/0e/0966c2f44beeac12af8d836e5b5f826a407cf34c45cb73ddcdfce9f5960b/numpy-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ccb7336eaf0e77c1635b232c141846493a588ec9ea777a7c24d7166bb8533ae", size = 14361143, upload_time = "2025-06-21T11:48:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/7d/31/6e35a247acb1bfc19226791dfc7d4c30002cd4e620e11e58b0ddf836fe52/numpy-2.3.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0bb3a4a61e1d327e035275d2a993c96fa786e4913aa089843e6a2d9dd205c66a", size = 5378989, upload_time = "2025-06-21T11:48:19.998Z" }, + { url = "https://files.pythonhosted.org/packages/b0/25/93b621219bb6f5a2d4e713a824522c69ab1f06a57cd571cda70e2e31af44/numpy-2.3.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:e344eb79dab01f1e838ebb67aab09965fb271d6da6b00adda26328ac27d4a66e", size = 6912890, upload_time = "2025-06-21T11:48:31.376Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/6b06ed98d11fb32e27fb59468b42383f3877146d3ee639f733776b6ac596/numpy-2.3.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:467db865b392168ceb1ef1ffa6f5a86e62468c43e0cfb4ab6da667ede10e58db", size = 14569032, upload_time = "2025-06-21T11:48:52.563Z" }, + { url = "https://files.pythonhosted.org/packages/75/c9/9bec03675192077467a9c7c2bdd1f2e922bd01d3a69b15c3a0fdcd8548f6/numpy-2.3.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:afed2ce4a84f6b0fc6c1ce734ff368cbf5a5e24e8954a338f3bdffa0718adffb", size = 16930354, upload_time = "2025-06-21T11:49:17.473Z" }, + { url = "https://files.pythonhosted.org/packages/6a/e2/5756a00cabcf50a3f527a0c968b2b4881c62b1379223931853114fa04cda/numpy-2.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0025048b3c1557a20bc80d06fdeb8cc7fc193721484cca82b2cfa072fec71a93", size = 15879605, upload_time = "2025-06-21T11:49:41.161Z" }, + { url = "https://files.pythonhosted.org/packages/ff/86/a471f65f0a86f1ca62dcc90b9fa46174dd48f50214e5446bc16a775646c5/numpy-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5ee121b60aa509679b682819c602579e1df14a5b07fe95671c8849aad8f2115", size = 18666994, upload_time = "2025-06-21T11:50:08.516Z" }, + { url = "https://files.pythonhosted.org/packages/43/a6/482a53e469b32be6500aaf61cfafd1de7a0b0d484babf679209c3298852e/numpy-2.3.1-cp311-cp311-win32.whl", hash = "sha256:a8b740f5579ae4585831b3cf0e3b0425c667274f82a484866d2adf9570539369", size = 6603672, upload_time = "2025-06-21T11:50:19.584Z" }, + { url = "https://files.pythonhosted.org/packages/6b/fb/bb613f4122c310a13ec67585c70e14b03bfc7ebabd24f4d5138b97371d7c/numpy-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4580adadc53311b163444f877e0789f1c8861e2698f6b2a4ca852fda154f3ff", size = 13024015, upload_time = "2025-06-21T11:50:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/51/58/2d842825af9a0c041aca246dc92eb725e1bc5e1c9ac89712625db0c4e11c/numpy-2.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:ec0bdafa906f95adc9a0c6f26a4871fa753f25caaa0e032578a30457bff0af6a", size = 10456989, upload_time = "2025-06-21T11:50:55.616Z" }, + { url = "https://files.pythonhosted.org/packages/c6/56/71ad5022e2f63cfe0ca93559403d0edef14aea70a841d640bd13cdba578e/numpy-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2959d8f268f3d8ee402b04a9ec4bb7604555aeacf78b360dc4ec27f1d508177d", size = 20896664, upload_time = "2025-06-21T12:15:30.845Z" }, + { url = "https://files.pythonhosted.org/packages/25/65/2db52ba049813670f7f987cc5db6dac9be7cd95e923cc6832b3d32d87cef/numpy-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:762e0c0c6b56bdedfef9a8e1d4538556438288c4276901ea008ae44091954e29", size = 14131078, upload_time = "2025-06-21T12:15:52.23Z" }, + { url = "https://files.pythonhosted.org/packages/57/dd/28fa3c17b0e751047ac928c1e1b6990238faad76e9b147e585b573d9d1bd/numpy-2.3.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:867ef172a0976aaa1f1d1b63cf2090de8b636a7674607d514505fb7276ab08fc", size = 5112554, upload_time = "2025-06-21T12:16:01.434Z" }, + { url = "https://files.pythonhosted.org/packages/c9/fc/84ea0cba8e760c4644b708b6819d91784c290288c27aca916115e3311d17/numpy-2.3.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:4e602e1b8682c2b833af89ba641ad4176053aaa50f5cacda1a27004352dde943", size = 6646560, upload_time = "2025-06-21T12:16:11.895Z" }, + { url = "https://files.pythonhosted.org/packages/61/b2/512b0c2ddec985ad1e496b0bd853eeb572315c0f07cd6997473ced8f15e2/numpy-2.3.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:8e333040d069eba1652fb08962ec5b76af7f2c7bce1df7e1418c8055cf776f25", size = 14260638, upload_time = "2025-06-21T12:16:32.611Z" }, + { url = "https://files.pythonhosted.org/packages/6e/45/c51cb248e679a6c6ab14b7a8e3ead3f4a3fe7425fc7a6f98b3f147bec532/numpy-2.3.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e7cbf5a5eafd8d230a3ce356d892512185230e4781a361229bd902ff403bc660", size = 16632729, upload_time = "2025-06-21T12:16:57.439Z" }, + { url = "https://files.pythonhosted.org/packages/e4/ff/feb4be2e5c09a3da161b412019caf47183099cbea1132fd98061808c2df2/numpy-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f1b8f26d1086835f442286c1d9b64bb3974b0b1e41bb105358fd07d20872952", size = 15565330, upload_time = "2025-06-21T12:17:20.638Z" }, + { url = "https://files.pythonhosted.org/packages/bc/6d/ceafe87587101e9ab0d370e4f6e5f3f3a85b9a697f2318738e5e7e176ce3/numpy-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ee8340cb48c9b7a5899d1149eece41ca535513a9698098edbade2a8e7a84da77", size = 18361734, upload_time = "2025-06-21T12:17:47.938Z" }, + { url = "https://files.pythonhosted.org/packages/2b/19/0fb49a3ea088be691f040c9bf1817e4669a339d6e98579f91859b902c636/numpy-2.3.1-cp312-cp312-win32.whl", hash = "sha256:e772dda20a6002ef7061713dc1e2585bc1b534e7909b2030b5a46dae8ff077ab", size = 6320411, upload_time = "2025-06-21T12:17:58.475Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3e/e28f4c1dd9e042eb57a3eb652f200225e311b608632bc727ae378623d4f8/numpy-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:cfecc7822543abdea6de08758091da655ea2210b8ffa1faf116b940693d3df76", size = 12734973, upload_time = "2025-06-21T12:18:17.601Z" }, + { url = "https://files.pythonhosted.org/packages/04/a8/8a5e9079dc722acf53522b8f8842e79541ea81835e9b5483388701421073/numpy-2.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:7be91b2239af2658653c5bb6f1b8bccafaf08226a258caf78ce44710a0160d30", size = 10191491, upload_time = "2025-06-21T12:18:33.585Z" }, + { url = "https://files.pythonhosted.org/packages/d4/bd/35ad97006d8abff8631293f8ea6adf07b0108ce6fec68da3c3fcca1197f2/numpy-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25a1992b0a3fdcdaec9f552ef10d8103186f5397ab45e2d25f8ac51b1a6b97e8", size = 20889381, upload_time = "2025-06-21T12:19:04.103Z" }, + { url = "https://files.pythonhosted.org/packages/f1/4f/df5923874d8095b6062495b39729178eef4a922119cee32a12ee1bd4664c/numpy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dea630156d39b02a63c18f508f85010230409db5b2927ba59c8ba4ab3e8272e", size = 14152726, upload_time = "2025-06-21T12:19:25.599Z" }, + { url = "https://files.pythonhosted.org/packages/8c/0f/a1f269b125806212a876f7efb049b06c6f8772cf0121139f97774cd95626/numpy-2.3.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bada6058dd886061f10ea15f230ccf7dfff40572e99fef440a4a857c8728c9c0", size = 5105145, upload_time = "2025-06-21T12:19:34.782Z" }, + { url = "https://files.pythonhosted.org/packages/6d/63/a7f7fd5f375b0361682f6ffbf686787e82b7bbd561268e4f30afad2bb3c0/numpy-2.3.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:a894f3816eb17b29e4783e5873f92faf55b710c2519e5c351767c51f79d8526d", size = 6639409, upload_time = "2025-06-21T12:19:45.228Z" }, + { url = "https://files.pythonhosted.org/packages/bf/0d/1854a4121af895aab383f4aa233748f1df4671ef331d898e32426756a8a6/numpy-2.3.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:18703df6c4a4fee55fd3d6e5a253d01c5d33a295409b03fda0c86b3ca2ff41a1", size = 14257630, upload_time = "2025-06-21T12:20:06.544Z" }, + { url = "https://files.pythonhosted.org/packages/50/30/af1b277b443f2fb08acf1c55ce9d68ee540043f158630d62cef012750f9f/numpy-2.3.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5902660491bd7a48b2ec16c23ccb9124b8abfd9583c5fdfa123fe6b421e03de1", size = 16627546, upload_time = "2025-06-21T12:20:31.002Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ec/3b68220c277e463095342d254c61be8144c31208db18d3fd8ef02712bcd6/numpy-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:36890eb9e9d2081137bd78d29050ba63b8dab95dff7912eadf1185e80074b2a0", size = 15562538, upload_time = "2025-06-21T12:20:54.322Z" }, + { url = "https://files.pythonhosted.org/packages/77/2b/4014f2bcc4404484021c74d4c5ee8eb3de7e3f7ac75f06672f8dcf85140a/numpy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a780033466159c2270531e2b8ac063704592a0bc62ec4a1b991c7c40705eb0e8", size = 18360327, upload_time = "2025-06-21T12:21:21.053Z" }, + { url = "https://files.pythonhosted.org/packages/40/8d/2ddd6c9b30fcf920837b8672f6c65590c7d92e43084c25fc65edc22e93ca/numpy-2.3.1-cp313-cp313-win32.whl", hash = "sha256:39bff12c076812595c3a306f22bfe49919c5513aa1e0e70fac756a0be7c2a2b8", size = 6312330, upload_time = "2025-06-21T12:25:07.447Z" }, + { url = "https://files.pythonhosted.org/packages/dd/c8/beaba449925988d415efccb45bf977ff8327a02f655090627318f6398c7b/numpy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d5ee6eec45f08ce507a6570e06f2f879b374a552087a4179ea7838edbcbfa42", size = 12731565, upload_time = "2025-06-21T12:25:26.444Z" }, + { url = "https://files.pythonhosted.org/packages/0b/c3/5c0c575d7ec78c1126998071f58facfc124006635da75b090805e642c62e/numpy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:0c4d9e0a8368db90f93bd192bfa771ace63137c3488d198ee21dfb8e7771916e", size = 10190262, upload_time = "2025-06-21T12:25:42.196Z" }, + { url = "https://files.pythonhosted.org/packages/ea/19/a029cd335cf72f79d2644dcfc22d90f09caa86265cbbde3b5702ccef6890/numpy-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b0b5397374f32ec0649dd98c652a1798192042e715df918c20672c62fb52d4b8", size = 20987593, upload_time = "2025-06-21T12:21:51.664Z" }, + { url = "https://files.pythonhosted.org/packages/25/91/8ea8894406209107d9ce19b66314194675d31761fe2cb3c84fe2eeae2f37/numpy-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c5bdf2015ccfcee8253fb8be695516ac4457c743473a43290fd36eba6a1777eb", size = 14300523, upload_time = "2025-06-21T12:22:13.583Z" }, + { url = "https://files.pythonhosted.org/packages/a6/7f/06187b0066eefc9e7ce77d5f2ddb4e314a55220ad62dd0bfc9f2c44bac14/numpy-2.3.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d70f20df7f08b90a2062c1f07737dd340adccf2068d0f1b9b3d56e2038979fee", size = 5227993, upload_time = "2025-06-21T12:22:22.53Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ec/a926c293c605fa75e9cfb09f1e4840098ed46d2edaa6e2152ee35dc01ed3/numpy-2.3.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:2fb86b7e58f9ac50e1e9dd1290154107e47d1eef23a0ae9145ded06ea606f992", size = 6736652, upload_time = "2025-06-21T12:22:33.629Z" }, + { url = "https://files.pythonhosted.org/packages/e3/62/d68e52fb6fde5586650d4c0ce0b05ff3a48ad4df4ffd1b8866479d1d671d/numpy-2.3.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:23ab05b2d241f76cb883ce8b9a93a680752fbfcbd51c50eff0b88b979e471d8c", size = 14331561, upload_time = "2025-06-21T12:22:55.056Z" }, + { url = "https://files.pythonhosted.org/packages/fc/ec/b74d3f2430960044bdad6900d9f5edc2dc0fb8bf5a0be0f65287bf2cbe27/numpy-2.3.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ce2ce9e5de4703a673e705183f64fd5da5bf36e7beddcb63a25ee2286e71ca48", size = 16693349, upload_time = "2025-06-21T12:23:20.53Z" }, + { url = "https://files.pythonhosted.org/packages/0d/15/def96774b9d7eb198ddadfcbd20281b20ebb510580419197e225f5c55c3e/numpy-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c4913079974eeb5c16ccfd2b1f09354b8fed7e0d6f2cab933104a09a6419b1ee", size = 15642053, upload_time = "2025-06-21T12:23:43.697Z" }, + { url = "https://files.pythonhosted.org/packages/2b/57/c3203974762a759540c6ae71d0ea2341c1fa41d84e4971a8e76d7141678a/numpy-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:010ce9b4f00d5c036053ca684c77441f2f2c934fd23bee058b4d6f196efd8280", size = 18434184, upload_time = "2025-06-21T12:24:10.708Z" }, + { url = "https://files.pythonhosted.org/packages/22/8a/ccdf201457ed8ac6245187850aff4ca56a79edbea4829f4e9f14d46fa9a5/numpy-2.3.1-cp313-cp313t-win32.whl", hash = "sha256:6269b9edfe32912584ec496d91b00b6d34282ca1d07eb10e82dfc780907d6c2e", size = 6440678, upload_time = "2025-06-21T12:24:21.596Z" }, + { url = "https://files.pythonhosted.org/packages/f1/7e/7f431d8bd8eb7e03d79294aed238b1b0b174b3148570d03a8a8a8f6a0da9/numpy-2.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2a809637460e88a113e186e87f228d74ae2852a2e0c44de275263376f17b5bdc", size = 12870697, upload_time = "2025-06-21T12:24:40.644Z" }, + { url = "https://files.pythonhosted.org/packages/d4/ca/af82bf0fad4c3e573c6930ed743b5308492ff19917c7caaf2f9b6f9e2e98/numpy-2.3.1-cp313-cp313t-win_arm64.whl", hash = "sha256:eccb9a159db9aed60800187bc47a6d3451553f0e1b08b068d8b277ddfbb9b244", size = 10260376, upload_time = "2025-06-21T12:24:56.884Z" }, + { url = "https://files.pythonhosted.org/packages/e8/34/facc13b9b42ddca30498fc51f7f73c3d0f2be179943a4b4da8686e259740/numpy-2.3.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ad506d4b09e684394c42c966ec1527f6ebc25da7f4da4b1b056606ffe446b8a3", size = 21070637, upload_time = "2025-06-21T12:26:12.518Z" }, + { url = "https://files.pythonhosted.org/packages/65/b6/41b705d9dbae04649b529fc9bd3387664c3281c7cd78b404a4efe73dcc45/numpy-2.3.1-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:ebb8603d45bc86bbd5edb0d63e52c5fd9e7945d3a503b77e486bd88dde67a19b", size = 5304087, upload_time = "2025-06-21T12:26:22.294Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/fe3ac1902bff7a4934a22d49e1c9d71a623204d654d4cc43c6e8fe337fcb/numpy-2.3.1-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:15aa4c392ac396e2ad3d0a2680c0f0dee420f9fed14eef09bdb9450ee6dcb7b7", size = 6817588, upload_time = "2025-06-21T12:26:32.939Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ee/89bedf69c36ace1ac8f59e97811c1f5031e179a37e4821c3a230bf750142/numpy-2.3.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c6e0bf9d1a2f50d2b65a7cf56db37c095af17b59f6c132396f7c6d5dd76484df", size = 14399010, upload_time = "2025-06-21T12:26:54.086Z" }, + { url = "https://files.pythonhosted.org/packages/15/08/e00e7070ede29b2b176165eba18d6f9784d5349be3c0c1218338e79c27fd/numpy-2.3.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eabd7e8740d494ce2b4ea0ff05afa1b7b291e978c0ae075487c51e8bd93c0c68", size = 16752042, upload_time = "2025-06-21T12:27:19.018Z" }, + { url = "https://files.pythonhosted.org/packages/48/6b/1c6b515a83d5564b1698a61efa245727c8feecf308f4091f565988519d20/numpy-2.3.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e610832418a2bc09d974cc9fecebfa51e9532d6190223bc5ef6a7402ebf3b5cb", size = 12927246, upload_time = "2025-06-21T12:27:38.618Z" }, +] + +[[package]] +name = "nvidia-cublas-cu12" +version = "12.6.4.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/eb/ff4b8c503fa1f1796679dce648854d58751982426e4e4b37d6fce49d259c/nvidia_cublas_cu12-12.6.4.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:08ed2686e9875d01b58e3cb379c6896df8e76c75e0d4a7f7dace3d7b6d9ef8eb", size = 393138322, upload_time = "2024-11-20T17:40:25.65Z" }, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.6.80" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/60/7b6497946d74bcf1de852a21824d63baad12cd417db4195fc1bfe59db953/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6768bad6cab4f19e8292125e5f1ac8aa7d1718704012a0e3272a6f61c4bce132", size = 8917980, upload_time = "2024-11-20T17:36:04.019Z" }, + { url = "https://files.pythonhosted.org/packages/a5/24/120ee57b218d9952c379d1e026c4479c9ece9997a4fb46303611ee48f038/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a3eff6cdfcc6a4c35db968a06fcadb061cbc7d6dde548609a941ff8701b98b73", size = 8917972, upload_time = "2024-10-01T16:58:06.036Z" }, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.6.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/2e/46030320b5a80661e88039f59060d1790298b4718944a65a7f2aeda3d9e9/nvidia_cuda_nvrtc_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:35b0cc6ee3a9636d5409133e79273ce1f3fd087abb0532d2d2e8fff1fe9efc53", size = 23650380, upload_time = "2024-10-01T17:00:14.643Z" }, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.6.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/23/e717c5ac26d26cf39a27fbc076240fad2e3b817e5889d671b67f4f9f49c5/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ba3b56a4f896141e25e19ab287cd71e52a6a0f4b29d0d31609f60e3b4d5219b7", size = 897690, upload_time = "2024-11-20T17:35:30.697Z" }, + { url = "https://files.pythonhosted.org/packages/f0/62/65c05e161eeddbafeca24dc461f47de550d9fa8a7e04eb213e32b55cfd99/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a84d15d5e1da416dd4774cb42edf5e954a3e60cc945698dc1d5be02321c44dc8", size = 897678, upload_time = "2024-10-01T16:57:33.821Z" }, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "9.5.1.17" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/78/4535c9c7f859a64781e43c969a3a7e84c54634e319a996d43ef32ce46f83/nvidia_cudnn_cu12-9.5.1.17-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:30ac3869f6db17d170e0e556dd6cc5eee02647abc31ca856634d5a40f82c15b2", size = 570988386, upload_time = "2024-10-25T19:54:26.39Z" }, +] + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.3.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/16/73727675941ab8e6ffd86ca3a4b7b47065edcca7a997920b831f8147c99d/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ccba62eb9cef5559abd5e0d54ceed2d9934030f51163df018532142a8ec533e5", size = 200221632, upload_time = "2024-11-20T17:41:32.357Z" }, + { url = "https://files.pythonhosted.org/packages/60/de/99ec247a07ea40c969d904fc14f3a356b3e2a704121675b75c366b694ee1/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.whl", hash = "sha256:768160ac89f6f7b459bee747e8d175dbf53619cfe74b2a5636264163138013ca", size = 200221622, upload_time = "2024-10-01T17:03:58.79Z" }, +] + +[[package]] +name = "nvidia-cufile-cu12" +version = "1.11.1.6" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/66/cc9876340ac68ae71b15c743ddb13f8b30d5244af344ec8322b449e35426/nvidia_cufile_cu12-1.11.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc23469d1c7e52ce6c1d55253273d32c565dd22068647f3aa59b3c6b005bf159", size = 1142103, upload_time = "2024-11-20T17:42:11.83Z" }, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.7.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/1b/44a01c4e70933637c93e6e1a8063d1e998b50213a6b65ac5a9169c47e98e/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a42cd1344297f70b9e39a1e4f467a4e1c10f1da54ff7a85c12197f6c652c8bdf", size = 56279010, upload_time = "2024-11-20T17:42:50.958Z" }, + { url = "https://files.pythonhosted.org/packages/4a/aa/2c7ff0b5ee02eaef890c0ce7d4f74bc30901871c5e45dee1ae6d0083cd80/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:99f1a32f1ac2bd134897fc7a203f779303261268a65762a623bf30cc9fe79117", size = 56279000, upload_time = "2024-10-01T17:04:45.274Z" }, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.7.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cusparse-cu12" }, + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/6e/c2cf12c9ff8b872e92b4a5740701e51ff17689c4d726fca91875b07f655d/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e9e49843a7707e42022babb9bcfa33c29857a93b88020c4e4434656a655b698c", size = 158229790, upload_time = "2024-11-20T17:43:43.211Z" }, + { url = "https://files.pythonhosted.org/packages/9f/81/baba53585da791d043c10084cf9553e074548408e04ae884cfe9193bd484/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf28f17f64107a0c4d7802be5ff5537b2130bfc112f25d5a30df227058ca0e6", size = 158229780, upload_time = "2024-10-01T17:05:39.875Z" }, +] + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.5.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/1e/b8b7c2f4099a37b96af5c9bb158632ea9e5d9d27d7391d7eb8fc45236674/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7556d9eca156e18184b94947ade0fba5bb47d69cec46bf8660fd2c71a4b48b73", size = 216561367, upload_time = "2024-11-20T17:44:54.824Z" }, + { url = "https://files.pythonhosted.org/packages/43/ac/64c4316ba163e8217a99680c7605f779accffc6a4bcd0c778c12948d3707/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:23749a6571191a215cb74d1cdbff4a86e7b19f1200c071b3fcf844a5bea23a2f", size = 216561357, upload_time = "2024-10-01T17:06:29.861Z" }, +] + +[[package]] +name = "nvidia-cusparselt-cu12" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/9a/72ef35b399b0e183bc2e8f6f558036922d453c4d8237dab26c666a04244b/nvidia_cusparselt_cu12-0.6.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e5c8a26c36445dd2e6812f1177978a24e2d37cacce7e090f297a688d1ec44f46", size = 156785796, upload_time = "2024-10-15T21:29:17.709Z" }, +] + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.26.2" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/ca/f42388aed0fddd64ade7493dbba36e1f534d4e6fdbdd355c6a90030ae028/nvidia_nccl_cu12-2.26.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:694cf3879a206553cc9d7dbda76b13efaf610fdb70a50cba303de1b0d1530ac6", size = 201319755, upload_time = "2025-03-13T00:29:55.296Z" }, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.6.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/d7/c5383e47c7e9bf1c99d5bd2a8c935af2b6d705ad831a7ec5c97db4d82f4f/nvidia_nvjitlink_cu12-12.6.85-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:eedc36df9e88b682efe4309aa16b5b4e78c2407eac59e8c10a6a47535164369a", size = 19744971, upload_time = "2024-11-20T17:46:53.366Z" }, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.6.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/9a/fff8376f8e3d084cd1530e1ef7b879bb7d6d265620c95c1b322725c694f4/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b90bed3df379fa79afbd21be8e04a0314336b8ae16768b58f2d34cb1d04cd7d2", size = 89276, upload_time = "2024-11-20T17:38:27.621Z" }, + { url = "https://files.pythonhosted.org/packages/9e/4e/0d0c945463719429b7bd21dece907ad0bde437a2ff12b9b12fee94722ab0/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6574241a3ec5fdc9334353ab8c479fe75841dbe8f4532a8fc97ce63503330ba1", size = 89265, upload_time = "2024-10-01T17:00:38.172Z" }, +] + +[[package]] +name = "oauthlib" +version = "3.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/5f/19930f824ffeb0ad4372da4812c50edbd1434f678c90c2733e1188edfc63/oauthlib-3.3.1.tar.gz", hash = "sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9", size = 185918, upload_time = "2025-06-19T22:48:08.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl", hash = "sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1", size = 160065, upload_time = "2025-06-19T22:48:06.508Z" }, +] + +[[package]] +name = "onnxruntime" +version = "1.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coloredlogs" }, + { name = "flatbuffers" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "sympy" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/3c/c99b21646a782b89c33cffd96fdee02a81bc43f0cb651de84d58ec11e30e/onnxruntime-1.22.0-cp310-cp310-macosx_13_0_universal2.whl", hash = "sha256:85d8826cc8054e4d6bf07f779dc742a363c39094015bdad6a08b3c18cfe0ba8c", size = 34273493, upload_time = "2025-05-09T20:25:55.66Z" }, + { url = "https://files.pythonhosted.org/packages/54/ab/fd9a3b5285008c060618be92e475337fcfbf8689787953d37273f7b52ab0/onnxruntime-1.22.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:468c9502a12f6f49ec335c2febd22fdceecc1e4cc96dfc27e419ba237dff5aff", size = 14445346, upload_time = "2025-05-09T20:25:41.322Z" }, + { url = "https://files.pythonhosted.org/packages/1f/ca/a5625644bc079e04e3076a5ac1fb954d1e90309b8eb987a4f800732ffee6/onnxruntime-1.22.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:681fe356d853630a898ee05f01ddb95728c9a168c9460e8361d0a240c9b7cb97", size = 16392959, upload_time = "2025-05-09T20:26:09.047Z" }, + { url = "https://files.pythonhosted.org/packages/6d/6b/8267490476e8d4dd1883632c7e46a4634384c7ff1c35ae44edc8ab0bb7a9/onnxruntime-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:20bca6495d06925631e201f2b257cc37086752e8fe7b6c83a67c6509f4759bc9", size = 12689974, upload_time = "2025-05-12T21:26:09.704Z" }, + { url = "https://files.pythonhosted.org/packages/7a/08/c008711d1b92ff1272f4fea0fbee57723171f161d42e5c680625535280af/onnxruntime-1.22.0-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:8d6725c5b9a681d8fe72f2960c191a96c256367887d076b08466f52b4e0991df", size = 34282151, upload_time = "2025-05-09T20:25:59.246Z" }, + { url = "https://files.pythonhosted.org/packages/3e/8b/22989f6b59bc4ad1324f07a945c80b9ab825f0a581ad7a6064b93716d9b7/onnxruntime-1.22.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fef17d665a917866d1f68f09edc98223b9a27e6cb167dec69da4c66484ad12fd", size = 14446302, upload_time = "2025-05-09T20:25:44.299Z" }, + { url = "https://files.pythonhosted.org/packages/7a/d5/aa83d084d05bc8f6cf8b74b499c77431ffd6b7075c761ec48ec0c161a47f/onnxruntime-1.22.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b978aa63a9a22095479c38371a9b359d4c15173cbb164eaad5f2cd27d666aa65", size = 16393496, upload_time = "2025-05-09T20:26:11.588Z" }, + { url = "https://files.pythonhosted.org/packages/89/a5/1c6c10322201566015183b52ef011dfa932f5dd1b278de8d75c3b948411d/onnxruntime-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:03d3ef7fb11adf154149d6e767e21057e0e577b947dd3f66190b212528e1db31", size = 12691517, upload_time = "2025-05-12T21:26:13.354Z" }, + { url = "https://files.pythonhosted.org/packages/4d/de/9162872c6e502e9ac8c99a98a8738b2fab408123d11de55022ac4f92562a/onnxruntime-1.22.0-cp312-cp312-macosx_13_0_universal2.whl", hash = "sha256:f3c0380f53c1e72a41b3f4d6af2ccc01df2c17844072233442c3a7e74851ab97", size = 34298046, upload_time = "2025-05-09T20:26:02.399Z" }, + { url = "https://files.pythonhosted.org/packages/03/79/36f910cd9fc96b444b0e728bba14607016079786adf032dae61f7c63b4aa/onnxruntime-1.22.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8601128eaef79b636152aea76ae6981b7c9fc81a618f584c15d78d42b310f1c", size = 14443220, upload_time = "2025-05-09T20:25:47.078Z" }, + { url = "https://files.pythonhosted.org/packages/8c/60/16d219b8868cc8e8e51a68519873bdb9f5f24af080b62e917a13fff9989b/onnxruntime-1.22.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6964a975731afc19dc3418fad8d4e08c48920144ff590149429a5ebe0d15fb3c", size = 16406377, upload_time = "2025-05-09T20:26:14.478Z" }, + { url = "https://files.pythonhosted.org/packages/36/b4/3f1c71ce1d3d21078a6a74c5483bfa2b07e41a8d2b8fb1e9993e6a26d8d3/onnxruntime-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0d534a43d1264d1273c2d4f00a5a588fa98d21117a3345b7104fa0bbcaadb9a", size = 12692233, upload_time = "2025-05-12T21:26:16.963Z" }, + { url = "https://files.pythonhosted.org/packages/a9/65/5cb5018d5b0b7cba820d2c4a1d1b02d40df538d49138ba36a509457e4df6/onnxruntime-1.22.0-cp313-cp313-macosx_13_0_universal2.whl", hash = "sha256:fe7c051236aae16d8e2e9ffbfc1e115a0cc2450e873a9c4cb75c0cc96c1dae07", size = 34298715, upload_time = "2025-05-09T20:26:05.634Z" }, + { url = "https://files.pythonhosted.org/packages/e1/89/1dfe1b368831d1256b90b95cb8d11da8ab769febd5c8833ec85ec1f79d21/onnxruntime-1.22.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a6bbed10bc5e770c04d422893d3045b81acbbadc9fb759a2cd1ca00993da919", size = 14443266, upload_time = "2025-05-09T20:25:49.479Z" }, + { url = "https://files.pythonhosted.org/packages/1e/70/342514ade3a33ad9dd505dcee96ff1f0e7be6d0e6e9c911fe0f1505abf42/onnxruntime-1.22.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fe45ee3e756300fccfd8d61b91129a121d3d80e9d38e01f03ff1295badc32b8", size = 16406707, upload_time = "2025-05-09T20:26:17.454Z" }, + { url = "https://files.pythonhosted.org/packages/3e/89/2f64e250945fa87140fb917ba377d6d0e9122e029c8512f389a9b7f953f4/onnxruntime-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:5a31d84ef82b4b05d794a4ce8ba37b0d9deb768fd580e36e17b39e0b4840253b", size = 12691777, upload_time = "2025-05-12T21:26:20.19Z" }, + { url = "https://files.pythonhosted.org/packages/9f/48/d61d5f1ed098161edd88c56cbac49207d7b7b149e613d2cd7e33176c63b3/onnxruntime-1.22.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a2ac5bd9205d831541db4e508e586e764a74f14efdd3f89af7fd20e1bf4a1ed", size = 14454003, upload_time = "2025-05-09T20:25:52.287Z" }, + { url = "https://files.pythonhosted.org/packages/c3/16/873b955beda7bada5b0d798d3a601b2ff210e44ad5169f6d405b93892103/onnxruntime-1.22.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64845709f9e8a2809e8e009bc4c8f73b788cee9c6619b7d9930344eae4c9cd36", size = 16427482, upload_time = "2025-05-09T20:26:20.376Z" }, +] + +[[package]] +name = "openai" +version = "1.93.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "httpx" }, + { name = "jiter" }, + { name = "pydantic" }, + { name = "sniffio" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/d7/e91c6a9cf71726420cddf539852ee4c29176ebb716a702d9118d0409fd8e/openai-1.93.0.tar.gz", hash = "sha256:988f31ade95e1ff0585af11cc5a64510225e4f5cd392698c675d0a9265b8e337", size = 486573, upload_time = "2025-06-27T21:21:39.421Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/46/a10d9df4673df56f71201d129ba1cb19eaff3366d08c8664d61a7df52e65/openai-1.93.0-py3-none-any.whl", hash = "sha256:3d746fe5498f0dd72e0d9ab706f26c91c0f646bf7459e5629af8ba7c9dbdf090", size = 755038, upload_time = "2025-06-27T21:21:37.532Z" }, +] + +[[package]] +name = "openpyxl" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "et-xmlfile" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload_time = "2024-06-28T14:03:44.161Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload_time = "2024-06-28T14:03:41.161Z" }, +] + +[[package]] +name = "opentelemetry-api" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/5e/94a8cb759e4e409022229418294e098ca7feca00eb3c467bb20cbd329bda/opentelemetry_api-1.34.1.tar.gz", hash = "sha256:64f0bd06d42824843731d05beea88d4d4b6ae59f9fe347ff7dfa2cc14233bbb3", size = 64987, upload_time = "2025-06-10T08:55:19.818Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/3a/2ba85557e8dc024c0842ad22c570418dc02c36cbd1ab4b832a93edf071b8/opentelemetry_api-1.34.1-py3-none-any.whl", hash = "sha256:b7df4cb0830d5a6c29ad0c0691dbae874d8daefa934b8b1d642de48323d32a8c", size = 65767, upload_time = "2025-06-10T08:54:56.717Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-proto" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/f0/ff235936ee40db93360233b62da932d4fd9e8d103cd090c6bcb9afaf5f01/opentelemetry_exporter_otlp_proto_common-1.34.1.tar.gz", hash = "sha256:b59a20a927facd5eac06edaf87a07e49f9e4a13db487b7d8a52b37cb87710f8b", size = 20817, upload_time = "2025-06-10T08:55:22.55Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/e8/8b292a11cc8d8d87ec0c4089ae21b6a58af49ca2e51fa916435bc922fdc7/opentelemetry_exporter_otlp_proto_common-1.34.1-py3-none-any.whl", hash = "sha256:8e2019284bf24d3deebbb6c59c71e6eef3307cd88eff8c633e061abba33f7e87", size = 18834, upload_time = "2025-06-10T08:55:00.806Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-grpc" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "grpcio" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/f7/bb63837a3edb9ca857aaf5760796874e7cecddc88a2571b0992865a48fb6/opentelemetry_exporter_otlp_proto_grpc-1.34.1.tar.gz", hash = "sha256:7c841b90caa3aafcfc4fee58487a6c71743c34c6dc1787089d8b0578bbd794dd", size = 22566, upload_time = "2025-06-10T08:55:23.214Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/42/0a4dd47e7ef54edf670c81fc06a83d68ea42727b82126a1df9dd0477695d/opentelemetry_exporter_otlp_proto_grpc-1.34.1-py3-none-any.whl", hash = "sha256:04bb8b732b02295be79f8a86a4ad28fae3d4ddb07307a98c7aa6f331de18cca6", size = 18615, upload_time = "2025-06-10T08:55:02.214Z" }, +] + +[[package]] +name = "opentelemetry-proto" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/b3/c3158dd012463bb7c0eb7304a85a6f63baeeb5b4c93a53845cf89f848c7e/opentelemetry_proto-1.34.1.tar.gz", hash = "sha256:16286214e405c211fc774187f3e4bbb1351290b8dfb88e8948af209ce85b719e", size = 34344, upload_time = "2025-06-10T08:55:32.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/ab/4591bfa54e946350ce8b3f28e5c658fe9785e7cd11e9c11b1671a867822b/opentelemetry_proto-1.34.1-py3-none-any.whl", hash = "sha256:eb4bb5ac27f2562df2d6857fc557b3a481b5e298bc04f94cc68041f00cebcbd2", size = 55692, upload_time = "2025-06-10T08:55:14.904Z" }, +] + +[[package]] +name = "opentelemetry-sdk" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6f/41/fe20f9036433da8e0fcef568984da4c1d1c771fa072ecd1a4d98779dccdd/opentelemetry_sdk-1.34.1.tar.gz", hash = "sha256:8091db0d763fcd6098d4781bbc80ff0971f94e260739aa6afe6fd379cdf3aa4d", size = 159441, upload_time = "2025-06-10T08:55:33.028Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/1b/def4fe6aa73f483cabf4c748f4c25070d5f7604dcc8b52e962983491b29e/opentelemetry_sdk-1.34.1-py3-none-any.whl", hash = "sha256:308effad4059562f1d92163c61c8141df649da24ce361827812c40abb2a1e96e", size = 118477, upload_time = "2025-06-10T08:55:16.02Z" }, +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.55b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5d/f0/f33458486da911f47c4aa6db9bda308bb80f3236c111bf848bd870c16b16/opentelemetry_semantic_conventions-0.55b1.tar.gz", hash = "sha256:ef95b1f009159c28d7a7849f5cbc71c4c34c845bb514d66adfdf1b3fff3598b3", size = 119829, upload_time = "2025-06-10T08:55:33.881Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/89/267b0af1b1d0ba828f0e60642b6a5116ac1fd917cde7fc02821627029bd1/opentelemetry_semantic_conventions-0.55b1-py3-none-any.whl", hash = "sha256:5da81dfdf7d52e3d37f8fe88d5e771e191de924cfff5f550ab0b8f7b2409baed", size = 196223, upload_time = "2025-06-10T08:55:17.638Z" }, +] + +[[package]] +name = "orjson" +version = "3.10.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/81/0b/fea456a3ffe74e70ba30e01ec183a9b26bec4d497f61dcfce1b601059c60/orjson-3.10.18.tar.gz", hash = "sha256:e8da3947d92123eda795b68228cafe2724815621fe35e8e320a9e9593a4bcd53", size = 5422810, upload_time = "2025-04-29T23:30:08.423Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/16/2ceb9fb7bc2b11b1e4a3ea27794256e93dee2309ebe297fd131a778cd150/orjson-3.10.18-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a45e5d68066b408e4bc383b6e4ef05e717c65219a9e1390abc6155a520cac402", size = 248927, upload_time = "2025-04-29T23:28:08.643Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e1/d3c0a2bba5b9906badd121da449295062b289236c39c3a7801f92c4682b0/orjson-3.10.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be3b9b143e8b9db05368b13b04c84d37544ec85bb97237b3a923f076265ec89c", size = 136995, upload_time = "2025-04-29T23:28:11.503Z" }, + { url = "https://files.pythonhosted.org/packages/d7/51/698dd65e94f153ee5ecb2586c89702c9e9d12f165a63e74eb9ea1299f4e1/orjson-3.10.18-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9b0aa09745e2c9b3bf779b096fa71d1cc2d801a604ef6dd79c8b1bfef52b2f92", size = 132893, upload_time = "2025-04-29T23:28:12.751Z" }, + { url = "https://files.pythonhosted.org/packages/b3/e5/155ce5a2c43a85e790fcf8b985400138ce5369f24ee6770378ee6b691036/orjson-3.10.18-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53a245c104d2792e65c8d225158f2b8262749ffe64bc7755b00024757d957a13", size = 137017, upload_time = "2025-04-29T23:28:14.498Z" }, + { url = "https://files.pythonhosted.org/packages/46/bb/6141ec3beac3125c0b07375aee01b5124989907d61c72c7636136e4bd03e/orjson-3.10.18-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9495ab2611b7f8a0a8a505bcb0f0cbdb5469caafe17b0e404c3c746f9900469", size = 138290, upload_time = "2025-04-29T23:28:16.211Z" }, + { url = "https://files.pythonhosted.org/packages/77/36/6961eca0b66b7809d33c4ca58c6bd4c23a1b914fb23aba2fa2883f791434/orjson-3.10.18-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73be1cbcebadeabdbc468f82b087df435843c809cd079a565fb16f0f3b23238f", size = 142828, upload_time = "2025-04-29T23:28:18.065Z" }, + { url = "https://files.pythonhosted.org/packages/8b/2f/0c646d5fd689d3be94f4d83fa9435a6c4322c9b8533edbb3cd4bc8c5f69a/orjson-3.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8936ee2679e38903df158037a2f1c108129dee218975122e37847fb1d4ac68", size = 132806, upload_time = "2025-04-29T23:28:19.782Z" }, + { url = "https://files.pythonhosted.org/packages/ea/af/65907b40c74ef4c3674ef2bcfa311c695eb934710459841b3c2da212215c/orjson-3.10.18-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7115fcbc8525c74e4c2b608129bef740198e9a120ae46184dac7683191042056", size = 135005, upload_time = "2025-04-29T23:28:21.367Z" }, + { url = "https://files.pythonhosted.org/packages/c7/d1/68bd20ac6a32cd1f1b10d23e7cc58ee1e730e80624e3031d77067d7150fc/orjson-3.10.18-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:771474ad34c66bc4d1c01f645f150048030694ea5b2709b87d3bda273ffe505d", size = 413418, upload_time = "2025-04-29T23:28:23.097Z" }, + { url = "https://files.pythonhosted.org/packages/31/31/c701ec0bcc3e80e5cb6e319c628ef7b768aaa24b0f3b4c599df2eaacfa24/orjson-3.10.18-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7c14047dbbea52886dd87169f21939af5d55143dad22d10db6a7514f058156a8", size = 153288, upload_time = "2025-04-29T23:28:25.02Z" }, + { url = "https://files.pythonhosted.org/packages/d9/31/5e1aa99a10893a43cfc58009f9da840990cc8a9ebb75aa452210ba18587e/orjson-3.10.18-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:641481b73baec8db14fdf58f8967e52dc8bda1f2aba3aa5f5c1b07ed6df50b7f", size = 137181, upload_time = "2025-04-29T23:28:26.318Z" }, + { url = "https://files.pythonhosted.org/packages/bf/8c/daba0ac1b8690011d9242a0f37235f7d17df6d0ad941021048523b76674e/orjson-3.10.18-cp310-cp310-win32.whl", hash = "sha256:607eb3ae0909d47280c1fc657c4284c34b785bae371d007595633f4b1a2bbe06", size = 142694, upload_time = "2025-04-29T23:28:28.092Z" }, + { url = "https://files.pythonhosted.org/packages/16/62/8b687724143286b63e1d0fab3ad4214d54566d80b0ba9d67c26aaf28a2f8/orjson-3.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:8770432524ce0eca50b7efc2a9a5f486ee0113a5fbb4231526d414e6254eba92", size = 134600, upload_time = "2025-04-29T23:28:29.422Z" }, + { url = "https://files.pythonhosted.org/packages/97/c7/c54a948ce9a4278794f669a353551ce7db4ffb656c69a6e1f2264d563e50/orjson-3.10.18-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e0a183ac3b8e40471e8d843105da6fbe7c070faab023be3b08188ee3f85719b8", size = 248929, upload_time = "2025-04-29T23:28:30.716Z" }, + { url = "https://files.pythonhosted.org/packages/9e/60/a9c674ef1dd8ab22b5b10f9300e7e70444d4e3cda4b8258d6c2488c32143/orjson-3.10.18-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:5ef7c164d9174362f85238d0cd4afdeeb89d9e523e4651add6a5d458d6f7d42d", size = 133364, upload_time = "2025-04-29T23:28:32.392Z" }, + { url = "https://files.pythonhosted.org/packages/c1/4e/f7d1bdd983082216e414e6d7ef897b0c2957f99c545826c06f371d52337e/orjson-3.10.18-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd14c5d99cdc7bf93f22b12ec3b294931518aa019e2a147e8aa2f31fd3240f7", size = 136995, upload_time = "2025-04-29T23:28:34.024Z" }, + { url = "https://files.pythonhosted.org/packages/17/89/46b9181ba0ea251c9243b0c8ce29ff7c9796fa943806a9c8b02592fce8ea/orjson-3.10.18-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b672502323b6cd133c4af6b79e3bea36bad2d16bca6c1f645903fce83909a7a", size = 132894, upload_time = "2025-04-29T23:28:35.318Z" }, + { url = "https://files.pythonhosted.org/packages/ca/dd/7bce6fcc5b8c21aef59ba3c67f2166f0a1a9b0317dcca4a9d5bd7934ecfd/orjson-3.10.18-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51f8c63be6e070ec894c629186b1c0fe798662b8687f3d9fdfa5e401c6bd7679", size = 137016, upload_time = "2025-04-29T23:28:36.674Z" }, + { url = "https://files.pythonhosted.org/packages/1c/4a/b8aea1c83af805dcd31c1f03c95aabb3e19a016b2a4645dd822c5686e94d/orjson-3.10.18-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9478ade5313d724e0495d167083c6f3be0dd2f1c9c8a38db9a9e912cdaf947", size = 138290, upload_time = "2025-04-29T23:28:38.3Z" }, + { url = "https://files.pythonhosted.org/packages/36/d6/7eb05c85d987b688707f45dcf83c91abc2251e0dd9fb4f7be96514f838b1/orjson-3.10.18-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:187aefa562300a9d382b4b4eb9694806e5848b0cedf52037bb5c228c61bb66d4", size = 142829, upload_time = "2025-04-29T23:28:39.657Z" }, + { url = "https://files.pythonhosted.org/packages/d2/78/ddd3ee7873f2b5f90f016bc04062713d567435c53ecc8783aab3a4d34915/orjson-3.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da552683bc9da222379c7a01779bddd0ad39dd699dd6300abaf43eadee38334", size = 132805, upload_time = "2025-04-29T23:28:40.969Z" }, + { url = "https://files.pythonhosted.org/packages/8c/09/c8e047f73d2c5d21ead9c180203e111cddeffc0848d5f0f974e346e21c8e/orjson-3.10.18-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e450885f7b47a0231979d9c49b567ed1c4e9f69240804621be87c40bc9d3cf17", size = 135008, upload_time = "2025-04-29T23:28:42.284Z" }, + { url = "https://files.pythonhosted.org/packages/0c/4b/dccbf5055ef8fb6eda542ab271955fc1f9bf0b941a058490293f8811122b/orjson-3.10.18-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5e3c9cc2ba324187cd06287ca24f65528f16dfc80add48dc99fa6c836bb3137e", size = 413419, upload_time = "2025-04-29T23:28:43.673Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f3/1eac0c5e2d6d6790bd2025ebfbefcbd37f0d097103d76f9b3f9302af5a17/orjson-3.10.18-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:50ce016233ac4bfd843ac5471e232b865271d7d9d44cf9d33773bcd883ce442b", size = 153292, upload_time = "2025-04-29T23:28:45.573Z" }, + { url = "https://files.pythonhosted.org/packages/1f/b4/ef0abf64c8f1fabf98791819ab502c2c8c1dc48b786646533a93637d8999/orjson-3.10.18-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b3ceff74a8f7ffde0b2785ca749fc4e80e4315c0fd887561144059fb1c138aa7", size = 137182, upload_time = "2025-04-29T23:28:47.229Z" }, + { url = "https://files.pythonhosted.org/packages/a9/a3/6ea878e7b4a0dc5c888d0370d7752dcb23f402747d10e2257478d69b5e63/orjson-3.10.18-cp311-cp311-win32.whl", hash = "sha256:fdba703c722bd868c04702cac4cb8c6b8ff137af2623bc0ddb3b3e6a2c8996c1", size = 142695, upload_time = "2025-04-29T23:28:48.564Z" }, + { url = "https://files.pythonhosted.org/packages/79/2a/4048700a3233d562f0e90d5572a849baa18ae4e5ce4c3ba6247e4ece57b0/orjson-3.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:c28082933c71ff4bc6ccc82a454a2bffcef6e1d7379756ca567c772e4fb3278a", size = 134603, upload_time = "2025-04-29T23:28:50.442Z" }, + { url = "https://files.pythonhosted.org/packages/03/45/10d934535a4993d27e1c84f1810e79ccf8b1b7418cef12151a22fe9bb1e1/orjson-3.10.18-cp311-cp311-win_arm64.whl", hash = "sha256:a6c7c391beaedd3fa63206e5c2b7b554196f14debf1ec9deb54b5d279b1b46f5", size = 131400, upload_time = "2025-04-29T23:28:51.838Z" }, + { url = "https://files.pythonhosted.org/packages/21/1a/67236da0916c1a192d5f4ccbe10ec495367a726996ceb7614eaa687112f2/orjson-3.10.18-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:50c15557afb7f6d63bc6d6348e0337a880a04eaa9cd7c9d569bcb4e760a24753", size = 249184, upload_time = "2025-04-29T23:28:53.612Z" }, + { url = "https://files.pythonhosted.org/packages/b3/bc/c7f1db3b1d094dc0c6c83ed16b161a16c214aaa77f311118a93f647b32dc/orjson-3.10.18-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:356b076f1662c9813d5fa56db7d63ccceef4c271b1fb3dd522aca291375fcf17", size = 133279, upload_time = "2025-04-29T23:28:55.055Z" }, + { url = "https://files.pythonhosted.org/packages/af/84/664657cd14cc11f0d81e80e64766c7ba5c9b7fc1ec304117878cc1b4659c/orjson-3.10.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:559eb40a70a7494cd5beab2d73657262a74a2c59aff2068fdba8f0424ec5b39d", size = 136799, upload_time = "2025-04-29T23:28:56.828Z" }, + { url = "https://files.pythonhosted.org/packages/9a/bb/f50039c5bb05a7ab024ed43ba25d0319e8722a0ac3babb0807e543349978/orjson-3.10.18-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f3c29eb9a81e2fbc6fd7ddcfba3e101ba92eaff455b8d602bf7511088bbc0eae", size = 132791, upload_time = "2025-04-29T23:28:58.751Z" }, + { url = "https://files.pythonhosted.org/packages/93/8c/ee74709fc072c3ee219784173ddfe46f699598a1723d9d49cbc78d66df65/orjson-3.10.18-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6612787e5b0756a171c7d81ba245ef63a3533a637c335aa7fcb8e665f4a0966f", size = 137059, upload_time = "2025-04-29T23:29:00.129Z" }, + { url = "https://files.pythonhosted.org/packages/6a/37/e6d3109ee004296c80426b5a62b47bcadd96a3deab7443e56507823588c5/orjson-3.10.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ac6bd7be0dcab5b702c9d43d25e70eb456dfd2e119d512447468f6405b4a69c", size = 138359, upload_time = "2025-04-29T23:29:01.704Z" }, + { url = "https://files.pythonhosted.org/packages/4f/5d/387dafae0e4691857c62bd02839a3bf3fa648eebd26185adfac58d09f207/orjson-3.10.18-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f72f100cee8dde70100406d5c1abba515a7df926d4ed81e20a9730c062fe9ad", size = 142853, upload_time = "2025-04-29T23:29:03.576Z" }, + { url = "https://files.pythonhosted.org/packages/27/6f/875e8e282105350b9a5341c0222a13419758545ae32ad6e0fcf5f64d76aa/orjson-3.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dca85398d6d093dd41dc0983cbf54ab8e6afd1c547b6b8a311643917fbf4e0c", size = 133131, upload_time = "2025-04-29T23:29:05.753Z" }, + { url = "https://files.pythonhosted.org/packages/48/b2/73a1f0b4790dcb1e5a45f058f4f5dcadc8a85d90137b50d6bbc6afd0ae50/orjson-3.10.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22748de2a07fcc8781a70edb887abf801bb6142e6236123ff93d12d92db3d406", size = 134834, upload_time = "2025-04-29T23:29:07.35Z" }, + { url = "https://files.pythonhosted.org/packages/56/f5/7ed133a5525add9c14dbdf17d011dd82206ca6840811d32ac52a35935d19/orjson-3.10.18-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3a83c9954a4107b9acd10291b7f12a6b29e35e8d43a414799906ea10e75438e6", size = 413368, upload_time = "2025-04-29T23:29:09.301Z" }, + { url = "https://files.pythonhosted.org/packages/11/7c/439654221ed9c3324bbac7bdf94cf06a971206b7b62327f11a52544e4982/orjson-3.10.18-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:303565c67a6c7b1f194c94632a4a39918e067bd6176a48bec697393865ce4f06", size = 153359, upload_time = "2025-04-29T23:29:10.813Z" }, + { url = "https://files.pythonhosted.org/packages/48/e7/d58074fa0cc9dd29a8fa2a6c8d5deebdfd82c6cfef72b0e4277c4017563a/orjson-3.10.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:86314fdb5053a2f5a5d881f03fca0219bfdf832912aa88d18676a5175c6916b5", size = 137466, upload_time = "2025-04-29T23:29:12.26Z" }, + { url = "https://files.pythonhosted.org/packages/57/4d/fe17581cf81fb70dfcef44e966aa4003360e4194d15a3f38cbffe873333a/orjson-3.10.18-cp312-cp312-win32.whl", hash = "sha256:187ec33bbec58c76dbd4066340067d9ece6e10067bb0cc074a21ae3300caa84e", size = 142683, upload_time = "2025-04-29T23:29:13.865Z" }, + { url = "https://files.pythonhosted.org/packages/e6/22/469f62d25ab5f0f3aee256ea732e72dc3aab6d73bac777bd6277955bceef/orjson-3.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:f9f94cf6d3f9cd720d641f8399e390e7411487e493962213390d1ae45c7814fc", size = 134754, upload_time = "2025-04-29T23:29:15.338Z" }, + { url = "https://files.pythonhosted.org/packages/10/b0/1040c447fac5b91bc1e9c004b69ee50abb0c1ffd0d24406e1350c58a7fcb/orjson-3.10.18-cp312-cp312-win_arm64.whl", hash = "sha256:3d600be83fe4514944500fa8c2a0a77099025ec6482e8087d7659e891f23058a", size = 131218, upload_time = "2025-04-29T23:29:17.324Z" }, + { url = "https://files.pythonhosted.org/packages/04/f0/8aedb6574b68096f3be8f74c0b56d36fd94bcf47e6c7ed47a7bd1474aaa8/orjson-3.10.18-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:69c34b9441b863175cc6a01f2935de994025e773f814412030f269da4f7be147", size = 249087, upload_time = "2025-04-29T23:29:19.083Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f7/7118f965541aeac6844fcb18d6988e111ac0d349c9b80cda53583e758908/orjson-3.10.18-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:1ebeda919725f9dbdb269f59bc94f861afbe2a27dce5608cdba2d92772364d1c", size = 133273, upload_time = "2025-04-29T23:29:20.602Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d9/839637cc06eaf528dd8127b36004247bf56e064501f68df9ee6fd56a88ee/orjson-3.10.18-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5adf5f4eed520a4959d29ea80192fa626ab9a20b2ea13f8f6dc58644f6927103", size = 136779, upload_time = "2025-04-29T23:29:22.062Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/f226ecfef31a1f0e7d6bf9a31a0bbaf384c7cbe3fce49cc9c2acc51f902a/orjson-3.10.18-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7592bb48a214e18cd670974f289520f12b7aed1fa0b2e2616b8ed9e069e08595", size = 132811, upload_time = "2025-04-29T23:29:23.602Z" }, + { url = "https://files.pythonhosted.org/packages/73/2d/371513d04143c85b681cf8f3bce743656eb5b640cb1f461dad750ac4b4d4/orjson-3.10.18-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f872bef9f042734110642b7a11937440797ace8c87527de25e0c53558b579ccc", size = 137018, upload_time = "2025-04-29T23:29:25.094Z" }, + { url = "https://files.pythonhosted.org/packages/69/cb/a4d37a30507b7a59bdc484e4a3253c8141bf756d4e13fcc1da760a0b00cb/orjson-3.10.18-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0315317601149c244cb3ecef246ef5861a64824ccbcb8018d32c66a60a84ffbc", size = 138368, upload_time = "2025-04-29T23:29:26.609Z" }, + { url = "https://files.pythonhosted.org/packages/1e/ae/cd10883c48d912d216d541eb3db8b2433415fde67f620afe6f311f5cd2ca/orjson-3.10.18-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0da26957e77e9e55a6c2ce2e7182a36a6f6b180ab7189315cb0995ec362e049", size = 142840, upload_time = "2025-04-29T23:29:28.153Z" }, + { url = "https://files.pythonhosted.org/packages/6d/4c/2bda09855c6b5f2c055034c9eda1529967b042ff8d81a05005115c4e6772/orjson-3.10.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb70d489bc79b7519e5803e2cc4c72343c9dc1154258adf2f8925d0b60da7c58", size = 133135, upload_time = "2025-04-29T23:29:29.726Z" }, + { url = "https://files.pythonhosted.org/packages/13/4a/35971fd809a8896731930a80dfff0b8ff48eeb5d8b57bb4d0d525160017f/orjson-3.10.18-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e9e86a6af31b92299b00736c89caf63816f70a4001e750bda179e15564d7a034", size = 134810, upload_time = "2025-04-29T23:29:31.269Z" }, + { url = "https://files.pythonhosted.org/packages/99/70/0fa9e6310cda98365629182486ff37a1c6578e34c33992df271a476ea1cd/orjson-3.10.18-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c382a5c0b5931a5fc5405053d36c1ce3fd561694738626c77ae0b1dfc0242ca1", size = 413491, upload_time = "2025-04-29T23:29:33.315Z" }, + { url = "https://files.pythonhosted.org/packages/32/cb/990a0e88498babddb74fb97855ae4fbd22a82960e9b06eab5775cac435da/orjson-3.10.18-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8e4b2ae732431127171b875cb2668f883e1234711d3c147ffd69fe5be51a8012", size = 153277, upload_time = "2025-04-29T23:29:34.946Z" }, + { url = "https://files.pythonhosted.org/packages/92/44/473248c3305bf782a384ed50dd8bc2d3cde1543d107138fd99b707480ca1/orjson-3.10.18-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d808e34ddb24fc29a4d4041dcfafbae13e129c93509b847b14432717d94b44f", size = 137367, upload_time = "2025-04-29T23:29:36.52Z" }, + { url = "https://files.pythonhosted.org/packages/ad/fd/7f1d3edd4ffcd944a6a40e9f88af2197b619c931ac4d3cfba4798d4d3815/orjson-3.10.18-cp313-cp313-win32.whl", hash = "sha256:ad8eacbb5d904d5591f27dee4031e2c1db43d559edb8f91778efd642d70e6bea", size = 142687, upload_time = "2025-04-29T23:29:38.292Z" }, + { url = "https://files.pythonhosted.org/packages/4b/03/c75c6ad46be41c16f4cfe0352a2d1450546f3c09ad2c9d341110cd87b025/orjson-3.10.18-cp313-cp313-win_amd64.whl", hash = "sha256:aed411bcb68bf62e85588f2a7e03a6082cc42e5a2796e06e72a962d7c6310b52", size = 134794, upload_time = "2025-04-29T23:29:40.349Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/f53038a5a72cc4fd0b56c1eafb4ef64aec9685460d5ac34de98ca78b6e29/orjson-3.10.18-cp313-cp313-win_arm64.whl", hash = "sha256:f54c1385a0e6aba2f15a40d703b858bedad36ded0491e55d35d905b2c34a4cc3", size = 131186, upload_time = "2025-04-29T23:29:41.922Z" }, +] + +[[package]] +name = "overrides" +version = "7.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812, upload_time = "2024-01-27T21:01:33.423Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832, upload_time = "2024-01-27T21:01:31.393Z" }, +] + +[[package]] +name = "packaging" +version = "24.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788, upload_time = "2024-06-09T23:19:24.956Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985, upload_time = "2024-06-09T23:19:21.909Z" }, +] + +[[package]] +name = "passlib" +version = "1.7.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/06/9da9ee59a67fae7761aab3ccc84fa4f3f33f125b370f1ccdb915bf967c11/passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04", size = 689844, upload_time = "2020-10-08T19:00:52.121Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/a4/ab6b7589382ca3df236e03faa71deac88cae040af60c071a78d254a62172/passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1", size = 525554, upload_time = "2020-10-08T19:00:49.856Z" }, +] + +[package.optional-dependencies] +bcrypt = [ + { name = "bcrypt" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload_time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload_time = "2023-12-10T22:30:43.14Z" }, +] + +[[package]] +name = "pillow" +version = "11.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload_time = "2025-07-01T09:16:30.666Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/5d/45a3553a253ac8763f3561371432a90bdbe6000fbdcf1397ffe502aa206c/pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860", size = 5316554, upload_time = "2025-07-01T09:13:39.342Z" }, + { url = "https://files.pythonhosted.org/packages/7c/c8/67c12ab069ef586a25a4a79ced553586748fad100c77c0ce59bb4983ac98/pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad", size = 4686548, upload_time = "2025-07-01T09:13:41.835Z" }, + { url = "https://files.pythonhosted.org/packages/2f/bd/6741ebd56263390b382ae4c5de02979af7f8bd9807346d068700dd6d5cf9/pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0", size = 5859742, upload_time = "2025-07-03T13:09:47.439Z" }, + { url = "https://files.pythonhosted.org/packages/ca/0b/c412a9e27e1e6a829e6ab6c2dca52dd563efbedf4c9c6aa453d9a9b77359/pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b", size = 7633087, upload_time = "2025-07-03T13:09:51.796Z" }, + { url = "https://files.pythonhosted.org/packages/59/9d/9b7076aaf30f5dd17e5e5589b2d2f5a5d7e30ff67a171eb686e4eecc2adf/pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50", size = 5963350, upload_time = "2025-07-01T09:13:43.865Z" }, + { url = "https://files.pythonhosted.org/packages/f0/16/1a6bf01fb622fb9cf5c91683823f073f053005c849b1f52ed613afcf8dae/pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae", size = 6631840, upload_time = "2025-07-01T09:13:46.161Z" }, + { url = "https://files.pythonhosted.org/packages/7b/e6/6ff7077077eb47fde78739e7d570bdcd7c10495666b6afcd23ab56b19a43/pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9", size = 6074005, upload_time = "2025-07-01T09:13:47.829Z" }, + { url = "https://files.pythonhosted.org/packages/c3/3a/b13f36832ea6d279a697231658199e0a03cd87ef12048016bdcc84131601/pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e", size = 6708372, upload_time = "2025-07-01T09:13:52.145Z" }, + { url = "https://files.pythonhosted.org/packages/6c/e4/61b2e1a7528740efbc70b3d581f33937e38e98ef3d50b05007267a55bcb2/pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6", size = 6277090, upload_time = "2025-07-01T09:13:53.915Z" }, + { url = "https://files.pythonhosted.org/packages/a9/d3/60c781c83a785d6afbd6a326ed4d759d141de43aa7365725cbcd65ce5e54/pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f", size = 6985988, upload_time = "2025-07-01T09:13:55.699Z" }, + { url = "https://files.pythonhosted.org/packages/9f/28/4f4a0203165eefb3763939c6789ba31013a2e90adffb456610f30f613850/pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f", size = 2422899, upload_time = "2025-07-01T09:13:57.497Z" }, + { url = "https://files.pythonhosted.org/packages/db/26/77f8ed17ca4ffd60e1dcd220a6ec6d71210ba398cfa33a13a1cd614c5613/pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", size = 5316531, upload_time = "2025-07-01T09:13:59.203Z" }, + { url = "https://files.pythonhosted.org/packages/cb/39/ee475903197ce709322a17a866892efb560f57900d9af2e55f86db51b0a5/pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", size = 4686560, upload_time = "2025-07-01T09:14:01.101Z" }, + { url = "https://files.pythonhosted.org/packages/d5/90/442068a160fd179938ba55ec8c97050a612426fae5ec0a764e345839f76d/pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", size = 5870978, upload_time = "2025-07-03T13:09:55.638Z" }, + { url = "https://files.pythonhosted.org/packages/13/92/dcdd147ab02daf405387f0218dcf792dc6dd5b14d2573d40b4caeef01059/pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", size = 7641168, upload_time = "2025-07-03T13:10:00.37Z" }, + { url = "https://files.pythonhosted.org/packages/6e/db/839d6ba7fd38b51af641aa904e2960e7a5644d60ec754c046b7d2aee00e5/pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", size = 5973053, upload_time = "2025-07-01T09:14:04.491Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", size = 6640273, upload_time = "2025-07-01T09:14:06.235Z" }, + { url = "https://files.pythonhosted.org/packages/45/ad/931694675ede172e15b2ff03c8144a0ddaea1d87adb72bb07655eaffb654/pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", size = 6082043, upload_time = "2025-07-01T09:14:07.978Z" }, + { url = "https://files.pythonhosted.org/packages/3a/04/ba8f2b11fc80d2dd462d7abec16351b45ec99cbbaea4387648a44190351a/pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", size = 6715516, upload_time = "2025-07-01T09:14:10.233Z" }, + { url = "https://files.pythonhosted.org/packages/48/59/8cd06d7f3944cc7d892e8533c56b0acb68399f640786313275faec1e3b6f/pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", size = 6274768, upload_time = "2025-07-01T09:14:11.921Z" }, + { url = "https://files.pythonhosted.org/packages/f1/cc/29c0f5d64ab8eae20f3232da8f8571660aa0ab4b8f1331da5c2f5f9a938e/pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", size = 6986055, upload_time = "2025-07-01T09:14:13.623Z" }, + { url = "https://files.pythonhosted.org/packages/c6/df/90bd886fabd544c25addd63e5ca6932c86f2b701d5da6c7839387a076b4a/pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", size = 2423079, upload_time = "2025-07-01T09:14:15.268Z" }, + { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload_time = "2025-07-01T09:14:17.648Z" }, + { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload_time = "2025-07-01T09:14:19.828Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload_time = "2025-07-03T13:10:04.448Z" }, + { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload_time = "2025-07-03T13:10:10.391Z" }, + { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload_time = "2025-07-01T09:14:21.63Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload_time = "2025-07-01T09:14:23.321Z" }, + { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload_time = "2025-07-01T09:14:25.237Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload_time = "2025-07-01T09:14:27.053Z" }, + { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload_time = "2025-07-01T09:14:30.104Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload_time = "2025-07-01T09:14:31.899Z" }, + { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload_time = "2025-07-01T09:14:33.709Z" }, + { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload_time = "2025-07-01T09:14:35.276Z" }, + { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload_time = "2025-07-01T09:14:37.203Z" }, + { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload_time = "2025-07-01T09:14:39.344Z" }, + { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload_time = "2025-07-01T09:14:41.843Z" }, + { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload_time = "2025-07-01T09:14:44.008Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload_time = "2025-07-03T13:10:15.628Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload_time = "2025-07-03T13:10:21.857Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload_time = "2025-07-01T09:14:45.698Z" }, + { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload_time = "2025-07-01T09:14:47.415Z" }, + { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload_time = "2025-07-01T09:14:49.636Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload_time = "2025-07-01T09:14:51.962Z" }, + { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload_time = "2025-07-01T09:14:54.142Z" }, + { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload_time = "2025-07-01T09:14:56.436Z" }, + { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload_time = "2025-07-01T09:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload_time = "2025-07-01T09:14:59.79Z" }, + { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload_time = "2025-07-01T09:15:01.648Z" }, + { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload_time = "2025-07-03T13:10:27.018Z" }, + { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload_time = "2025-07-03T13:10:33.01Z" }, + { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload_time = "2025-07-01T09:15:03.365Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload_time = "2025-07-01T09:15:05.655Z" }, + { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload_time = "2025-07-01T09:15:07.358Z" }, + { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload_time = "2025-07-01T09:15:09.317Z" }, + { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload_time = "2025-07-01T09:15:11.311Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload_time = "2025-07-01T09:15:13.164Z" }, + { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload_time = "2025-07-01T09:15:15.695Z" }, + { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload_time = "2025-07-01T09:15:17.429Z" }, + { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload_time = "2025-07-01T09:15:19.423Z" }, + { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload_time = "2025-07-03T13:10:38.404Z" }, + { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload_time = "2025-07-03T13:10:44.987Z" }, + { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload_time = "2025-07-01T09:15:21.237Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload_time = "2025-07-01T09:15:23.186Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload_time = "2025-07-01T09:15:25.1Z" }, + { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload_time = "2025-07-01T09:15:27.378Z" }, + { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload_time = "2025-07-01T09:15:29.294Z" }, + { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload_time = "2025-07-01T09:15:31.128Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload_time = "2025-07-01T09:15:33.328Z" }, + { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload_time = "2025-07-01T09:15:35.194Z" }, + { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload_time = "2025-07-01T09:15:37.114Z" }, + { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload_time = "2025-07-03T13:10:50.248Z" }, + { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload_time = "2025-07-03T13:10:56.432Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload_time = "2025-07-01T09:15:39.436Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload_time = "2025-07-01T09:15:41.269Z" }, + { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload_time = "2025-07-01T09:15:43.13Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload_time = "2025-07-01T09:15:44.937Z" }, + { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload_time = "2025-07-01T09:15:46.673Z" }, + { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload_time = "2025-07-01T09:15:48.512Z" }, + { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload_time = "2025-07-01T09:15:50.399Z" }, + { url = "https://files.pythonhosted.org/packages/6f/8b/209bd6b62ce8367f47e68a218bffac88888fdf2c9fcf1ecadc6c3ec1ebc7/pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967", size = 5270556, upload_time = "2025-07-01T09:16:09.961Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e6/231a0b76070c2cfd9e260a7a5b504fb72da0a95279410fa7afd99d9751d6/pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe", size = 4654625, upload_time = "2025-07-01T09:16:11.913Z" }, + { url = "https://files.pythonhosted.org/packages/13/f4/10cf94fda33cb12765f2397fc285fa6d8eb9c29de7f3185165b702fc7386/pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c", size = 4874207, upload_time = "2025-07-03T13:11:10.201Z" }, + { url = "https://files.pythonhosted.org/packages/72/c9/583821097dc691880c92892e8e2d41fe0a5a3d6021f4963371d2f6d57250/pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25", size = 6583939, upload_time = "2025-07-03T13:11:15.68Z" }, + { url = "https://files.pythonhosted.org/packages/3b/8e/5c9d410f9217b12320efc7c413e72693f48468979a013ad17fd690397b9a/pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27", size = 4957166, upload_time = "2025-07-01T09:16:13.74Z" }, + { url = "https://files.pythonhosted.org/packages/62/bb/78347dbe13219991877ffb3a91bf09da8317fbfcd4b5f9140aeae020ad71/pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a", size = 5581482, upload_time = "2025-07-01T09:16:16.107Z" }, + { url = "https://files.pythonhosted.org/packages/d9/28/1000353d5e61498aaeaaf7f1e4b49ddb05f2c6575f9d4f9f914a3538b6e1/pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f", size = 6984596, upload_time = "2025-07-01T09:16:18.07Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e3/6fa84033758276fb31da12e5fb66ad747ae83b93c67af17f8c6ff4cc8f34/pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", size = 5270566, upload_time = "2025-07-01T09:16:19.801Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ee/e8d2e1ab4892970b561e1ba96cbd59c0d28cf66737fc44abb2aec3795a4e/pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", size = 4654618, upload_time = "2025-07-01T09:16:21.818Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6d/17f80f4e1f0761f02160fc433abd4109fa1548dcfdca46cfdadaf9efa565/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3", size = 4874248, upload_time = "2025-07-03T13:11:20.738Z" }, + { url = "https://files.pythonhosted.org/packages/de/5f/c22340acd61cef960130585bbe2120e2fd8434c214802f07e8c03596b17e/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", size = 6583963, upload_time = "2025-07-03T13:11:26.283Z" }, + { url = "https://files.pythonhosted.org/packages/31/5e/03966aedfbfcbb4d5f8aa042452d3361f325b963ebbadddac05b122e47dd/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", size = 4957170, upload_time = "2025-07-01T09:16:23.762Z" }, + { url = "https://files.pythonhosted.org/packages/cc/2d/e082982aacc927fc2cab48e1e731bdb1643a1406acace8bed0900a61464e/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", size = 5581505, upload_time = "2025-07-01T09:16:25.593Z" }, + { url = "https://files.pythonhosted.org/packages/34/e7/ae39f538fd6844e982063c3a5e4598b8ced43b9633baa3a85ef33af8c05c/pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", size = 6984598, upload_time = "2025-07-01T09:16:27.732Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302, upload_time = "2024-09-17T19:06:50.688Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439, upload_time = "2024-09-17T19:06:49.212Z" }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload_time = "2024-04-20T21:34:42.531Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload_time = "2024-04-20T21:34:40.434Z" }, +] + +[[package]] +name = "portalocker" +version = "2.10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywin32", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/d3/c6c64067759e87af98cc668c1cc75171347d0f1577fab7ca3749134e3cd4/portalocker-2.10.1.tar.gz", hash = "sha256:ef1bf844e878ab08aee7e40184156e1151f228f103aa5c6bd0724cc330960f8f", size = 40891, upload_time = "2024-07-13T23:15:34.86Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/fb/a70a4214956182e0d7a9099ab17d50bfcba1056188e9b14f35b9e2b62a0d/portalocker-2.10.1-py3-none-any.whl", hash = "sha256:53a5984ebc86a025552264b459b46a2086e269b21823cb572f8f28ee759e45bf", size = 18423, upload_time = "2024-07-13T23:15:32.602Z" }, +] + +[[package]] +name = "posthog" +version = "5.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "backoff" }, + { name = "distro" }, + { name = "python-dateutil" }, + { name = "requests" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/20/60ae67bb9d82f00427946218d49e2e7e80fb41c15dc5019482289ec9ce8d/posthog-5.4.0.tar.gz", hash = "sha256:701669261b8d07cdde0276e5bc096b87f9e200e3b9589c5ebff14df658c5893c", size = 88076, upload_time = "2025-06-20T23:19:23.485Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/98/e480cab9a08d1c09b1c59a93dade92c1bb7544826684ff2acbfd10fcfbd4/posthog-5.4.0-py3-none-any.whl", hash = "sha256:284dfa302f64353484420b52d4ad81ff5c2c2d1d607c4e2db602ac72761831bd", size = 105364, upload_time = "2025-06-20T23:19:22.001Z" }, +] + +[[package]] +name = "pre-commit" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/10/97ee2fa54dff1e9da9badbc5e35d0bbaef0776271ea5907eccf64140f72f/pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af", size = 177815, upload_time = "2024-07-28T19:59:01.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/92/caae8c86e94681b42c246f0bca35c059a2f0529e5b92619f6aba4cf7e7b6/pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f", size = 204643, upload_time = "2024-07-28T19:58:59.335Z" }, +] + +[[package]] +name = "premailer" +version = "3.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cachetools" }, + { name = "cssselect" }, + { name = "cssutils" }, + { name = "lxml" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/6f/e49bd31941eff2987076383fa6d811eb785a28f498f5bb131e981bd71e13/premailer-3.10.0.tar.gz", hash = "sha256:d1875a8411f5dc92b53ef9f193db6c0f879dc378d618e0ad292723e388bfe4c2", size = 24342, upload_time = "2021-08-02T20:32:54.328Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/07/4e8d94f94c7d41ca5ddf8a9695ad87b888104e2fd41a35546c1dc9ca74ac/premailer-3.10.0-py2.py3-none-any.whl", hash = "sha256:021b8196364d7df96d04f9ade51b794d0b77bcc19e998321c515633a2273be1a", size = 19544, upload_time = "2021-08-02T20:32:52.771Z" }, +] + +[[package]] +name = "preshed" +version = "3.0.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cymem" }, + { name = "murmurhash" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/3a/db814f67a05b6d7f9c15d38edef5ec9b21415710705b393883de92aee5ef/preshed-3.0.10.tar.gz", hash = "sha256:5a5c8e685e941f4ffec97f1fbf32694b8107858891a4bc34107fac981d8296ff", size = 15039, upload_time = "2025-05-26T15:18:33.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/12/3bfd7790481513d71a281a3a7194a6d7aa9a59289a109253e78d9bcedcec/preshed-3.0.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:14593c32e6705fda0fd54684293ca079530418bb1fb036dcbaa6c0ef0f144b7d", size = 131102, upload_time = "2025-05-26T15:17:41.762Z" }, + { url = "https://files.pythonhosted.org/packages/e4/bf/54635387524315fe40b1f3d1688a5ad369f59a4e3a377b0da6e8a3ecba30/preshed-3.0.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ba1960a3996678aded882260133853e19e3a251d9f35a19c9d7d830c4238c4eb", size = 127302, upload_time = "2025-05-26T15:17:43.263Z" }, + { url = "https://files.pythonhosted.org/packages/fe/df/d057705c9c6aff877ee687f612f242006750f165c0e557f6075fe913a8e3/preshed-3.0.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0830c0a262015be743a01455a1da5963750afed1bde2395590b01af3b7da2741", size = 793737, upload_time = "2025-05-26T15:17:44.736Z" }, + { url = "https://files.pythonhosted.org/packages/c4/73/9206a60e59e81a259d49273f95307821f5e88c84c400533ed0cb9a8093af/preshed-3.0.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:165dda5862c28e77ee1f3feabad98d4ebb65345f458b5626596b92fd20a65275", size = 795131, upload_time = "2025-05-26T15:17:46.382Z" }, + { url = "https://files.pythonhosted.org/packages/25/18/02a40bcb13ae6c1ca3a859a709354621b45c83857994943c9c409f85f183/preshed-3.0.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e88e4c7fbbfa7c23a90d7d0cbe27e4c5fa2fd742ef1be09c153f9ccd2c600098", size = 777924, upload_time = "2025-05-26T15:17:48.184Z" }, + { url = "https://files.pythonhosted.org/packages/11/13/bb2db0f037fc659494fbe964255f80fbca7e5e4154137e9855619e3543d9/preshed-3.0.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:87780ae00def0c97130c9d1652295ec8362c2e4ca553673b64fe0dc7b321a382", size = 796024, upload_time = "2025-05-26T15:17:49.568Z" }, + { url = "https://files.pythonhosted.org/packages/99/ab/7187df84a32f02d987b689f4bbb1ad77304bdc8129d8fed483b8ebde113d/preshed-3.0.10-cp310-cp310-win_amd64.whl", hash = "sha256:32496f216255a6cbdd60965dde29ff42ed8fc2d77968c28ae875e3856c6fa01a", size = 117429, upload_time = "2025-05-26T15:17:51.091Z" }, + { url = "https://files.pythonhosted.org/packages/08/99/c3709638f687da339504d1daeca48604cadb338bf3556a1484d1f0cd95e6/preshed-3.0.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d96c4fe2b41c1cdcc8c4fc1fdb10f922a6095c0430a3ebe361fe62c78902d068", size = 131486, upload_time = "2025-05-26T15:17:52.231Z" }, + { url = "https://files.pythonhosted.org/packages/e0/27/0fd36b63caa8bbf57b31a121d9565d385bbd7521771d4eb93e17d326873d/preshed-3.0.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cb01ea930b96f3301526a2ab26f41347d07555e4378c4144c6b7645074f2ebb0", size = 127938, upload_time = "2025-05-26T15:17:54.19Z" }, + { url = "https://files.pythonhosted.org/packages/90/54/6a876d9cc8d401a9c1fb6bb8ca5a31b3664d0bcb888a9016258a1ae17344/preshed-3.0.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dd1f0a7b7d150e229d073fd4fe94f72610cae992e907cee74687c4695873a98", size = 842263, upload_time = "2025-05-26T15:17:55.398Z" }, + { url = "https://files.pythonhosted.org/packages/1c/7d/ff19f74d15ee587905bafa3582883cfe2f72b574e6d691ee64dc690dc276/preshed-3.0.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fd7b350c280137f324cd447afbf6ba9a849af0e8898850046ac6f34010e08bd", size = 842913, upload_time = "2025-05-26T15:17:56.687Z" }, + { url = "https://files.pythonhosted.org/packages/f1/3a/1c345a26463345557705b61965e1e0a732cc0e9c6dfd4787845dbfa50b4a/preshed-3.0.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cf6a5fdc89ad06079aa6ee63621e417d4f4cf2a3d8b63c72728baad35a9ff641", size = 820548, upload_time = "2025-05-26T15:17:58.057Z" }, + { url = "https://files.pythonhosted.org/packages/7f/6b/71f25e2b7a23dba168f43edfae0bb508552dbef89114ce65c73f2ea7172f/preshed-3.0.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b4c29a7bd66985808ad181c9ad05205a6aa7400cd0f98426acd7bc86588b93f8", size = 840379, upload_time = "2025-05-26T15:17:59.565Z" }, + { url = "https://files.pythonhosted.org/packages/3a/86/d8f32b0b31a36ee8770a9b1a95321430e364cd0ba4bfebb7348aed2f198d/preshed-3.0.10-cp311-cp311-win_amd64.whl", hash = "sha256:1367c1fd6f44296305315d4e1c3fe3171787d4d01c1008a76bc9466bd79c3249", size = 117655, upload_time = "2025-05-26T15:18:00.836Z" }, + { url = "https://files.pythonhosted.org/packages/c3/14/322a4f58bc25991a87f216acb1351800739b0794185d27508ee86c35f382/preshed-3.0.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6e9c46933d55c8898c8f7a6019a8062cd87ef257b075ada2dd5d1e57810189ea", size = 131367, upload_time = "2025-05-26T15:18:02.408Z" }, + { url = "https://files.pythonhosted.org/packages/38/80/67507653c35620cace913f617df6d6f658b87e8da83087b851557d65dd86/preshed-3.0.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c4ebc4f8ef0114d55f2ffdce4965378129c7453d0203664aeeb03055572d9e4", size = 126535, upload_time = "2025-05-26T15:18:03.589Z" }, + { url = "https://files.pythonhosted.org/packages/db/b1/ab4f811aeaf20af0fa47148c1c54b62d7e8120d59025bd0a3f773bb67725/preshed-3.0.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ab5ab4c6dfd3746fb4328e7fbeb2a0544416b872db02903bfac18e6f5cd412f", size = 864907, upload_time = "2025-05-26T15:18:04.794Z" }, + { url = "https://files.pythonhosted.org/packages/fb/db/fe37c1f99cfb26805dd89381ddd54901307feceb267332eaaca228e9f9c1/preshed-3.0.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40586fd96ae3974c552a7cd78781b6844ecb1559ee7556586f487058cf13dd96", size = 869329, upload_time = "2025-05-26T15:18:06.353Z" }, + { url = "https://files.pythonhosted.org/packages/a7/fd/efb6a6233d1cd969966f3f65bdd8e662579c3d83114e5c356cec1927b1f7/preshed-3.0.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a606c24cda931306b98e0edfafed3309bffcf8d6ecfe07804db26024c4f03cd6", size = 846829, upload_time = "2025-05-26T15:18:07.716Z" }, + { url = "https://files.pythonhosted.org/packages/14/49/0e4ce5db3bf86b081abb08a404fb37b7c2dbfd7a73ec6c0bc71b650307eb/preshed-3.0.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:394015566f9354738be903447039e8dbc6d93ba5adf091af694eb03c4e726b1e", size = 874008, upload_time = "2025-05-26T15:18:09.364Z" }, + { url = "https://files.pythonhosted.org/packages/6f/17/76d6593fc2d055d4e413b68a8c87b70aa9b7697d4972cb8062559edcf6e9/preshed-3.0.10-cp312-cp312-win_amd64.whl", hash = "sha256:fd7e38225937e580420c84d1996dde9b4f726aacd9405093455c3a2fa60fede5", size = 116701, upload_time = "2025-05-26T15:18:11.905Z" }, + { url = "https://files.pythonhosted.org/packages/bf/5e/87671bc58c4f6c8cf0a5601ccd74b8bb50281ff28aa4ab3e3cad5cd9d06a/preshed-3.0.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:23e6e0581a517597f3f76bc24a4cdb0ba5509933d4f61c34fca49649dd71edf9", size = 129184, upload_time = "2025-05-26T15:18:13.331Z" }, + { url = "https://files.pythonhosted.org/packages/92/69/b3969a3c95778def5bf5126484a1f7d2ad324d1040077f55f56e027d8ea4/preshed-3.0.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:574e6d6056981540310ff181b47a2912f4bddc91bcace3c7a9c6726eafda24ca", size = 124258, upload_time = "2025-05-26T15:18:14.497Z" }, + { url = "https://files.pythonhosted.org/packages/32/df/6e828ec4565bf33bd4803a3eb3b1102830b739143e5d6c132bf7181a58ec/preshed-3.0.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd658dd73e853d1bb5597976a407feafa681b9d6155bc9bc7b4c2acc2a6ee96", size = 825445, upload_time = "2025-05-26T15:18:15.71Z" }, + { url = "https://files.pythonhosted.org/packages/05/3d/478b585f304920e51f328c9231e22f30dc64baa68e079e08a46ab72be738/preshed-3.0.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b95396046328ffb461a68859ce2141aca4815b8624167832d28ced70d541626", size = 831690, upload_time = "2025-05-26T15:18:17.08Z" }, + { url = "https://files.pythonhosted.org/packages/c3/65/938f21f77227e8d398d46fb10b9d1b3467be859468ce8db138fc3d50589c/preshed-3.0.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3e6728b2028bbe79565eb6cf676b5bae5ce1f9cc56e4bf99bb28ce576f88054d", size = 808593, upload_time = "2025-05-26T15:18:18.535Z" }, + { url = "https://files.pythonhosted.org/packages/6c/1c/2a3961fc88bc72300ff7e4ca54689bda90d2d77cc994167cc09a310480b6/preshed-3.0.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c4ef96cb28bf5f08de9c070143113e168efccbb68fd4961e7d445f734c051a97", size = 837333, upload_time = "2025-05-26T15:18:19.937Z" }, + { url = "https://files.pythonhosted.org/packages/fa/8c/d3e30f80b2ef21f267f09f0b7d18995adccc928ede5b73ea3fe54e1303f4/preshed-3.0.10-cp313-cp313-win_amd64.whl", hash = "sha256:97e0e2edfd25a7dfba799b49b3c5cc248ad0318a76edd9d5fd2c82aa3d5c64ed", size = 115769, upload_time = "2025-05-26T15:18:21.842Z" }, +] + +[[package]] +name = "prometheus-client" +version = "0.22.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/cf/40dde0a2be27cc1eb41e333d1a674a74ce8b8b0457269cc640fd42b07cf7/prometheus_client-0.22.1.tar.gz", hash = "sha256:190f1331e783cf21eb60bca559354e0a4d4378facecf78f5428c39b675d20d28", size = 69746, upload_time = "2025-06-02T14:29:01.152Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl", hash = "sha256:cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094", size = 58694, upload_time = "2025-06-02T14:29:00.068Z" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.51" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bb/6e/9d084c929dfe9e3bfe0c6a47e31f78a25c54627d64a66e884a8bf5474f1c/prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed", size = 428940, upload_time = "2025-04-15T09:18:47.731Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07", size = 387810, upload_time = "2025-04-15T09:18:44.753Z" }, +] + +[[package]] +name = "protobuf" +version = "5.29.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/29/d09e70352e4e88c9c7a198d5645d7277811448d76c23b00345670f7c8a38/protobuf-5.29.5.tar.gz", hash = "sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84", size = 425226, upload_time = "2025-05-28T23:51:59.82Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/11/6e40e9fc5bba02988a214c07cf324595789ca7820160bfd1f8be96e48539/protobuf-5.29.5-cp310-abi3-win32.whl", hash = "sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079", size = 422963, upload_time = "2025-05-28T23:51:41.204Z" }, + { url = "https://files.pythonhosted.org/packages/81/7f/73cefb093e1a2a7c3ffd839e6f9fcafb7a427d300c7f8aef9c64405d8ac6/protobuf-5.29.5-cp310-abi3-win_amd64.whl", hash = "sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc", size = 434818, upload_time = "2025-05-28T23:51:44.297Z" }, + { url = "https://files.pythonhosted.org/packages/dd/73/10e1661c21f139f2c6ad9b23040ff36fee624310dc28fba20d33fdae124c/protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671", size = 418091, upload_time = "2025-05-28T23:51:45.907Z" }, + { url = "https://files.pythonhosted.org/packages/6c/04/98f6f8cf5b07ab1294c13f34b4e69b3722bb609c5b701d6c169828f9f8aa/protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015", size = 319824, upload_time = "2025-05-28T23:51:47.545Z" }, + { url = "https://files.pythonhosted.org/packages/85/e4/07c80521879c2d15f321465ac24c70efe2381378c00bf5e56a0f4fbac8cd/protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61", size = 319942, upload_time = "2025-05-28T23:51:49.11Z" }, + { url = "https://files.pythonhosted.org/packages/7e/cc/7e77861000a0691aeea8f4566e5d3aa716f2b1dece4a24439437e41d3d25/protobuf-5.29.5-py3-none-any.whl", hash = "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5", size = 172823, upload_time = "2025-05-28T23:51:58.157Z" }, +] + +[[package]] +name = "psutil" +version = "7.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003, upload_time = "2025-02-13T21:54:07.946Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051, upload_time = "2025-02-13T21:54:12.36Z" }, + { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535, upload_time = "2025-02-13T21:54:16.07Z" }, + { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004, upload_time = "2025-02-13T21:54:18.662Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986, upload_time = "2025-02-13T21:54:21.811Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544, upload_time = "2025-02-13T21:54:24.68Z" }, + { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053, upload_time = "2025-02-13T21:54:34.31Z" }, + { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload_time = "2025-02-13T21:54:37.486Z" }, ] [[package]] name = "psycopg" -version = "3.2.2" +version = "3.2.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/70/d1e4c251be6e0752cbc7408f0556f8f922690837309442b9019122295712/psycopg-3.2.2.tar.gz", hash = "sha256:8bad2e497ce22d556dac1464738cb948f8d6bab450d965cf1d8a8effd52412e0", size = 155483 } +sdist = { url = "https://files.pythonhosted.org/packages/27/4a/93a6ab570a8d1a4ad171a1f4256e205ce48d828781312c0bbaff36380ecb/psycopg-3.2.9.tar.gz", hash = "sha256:2fbb46fcd17bc81f993f28c47f1ebea38d66ae97cc2dbc3cad73b37cefbff700", size = 158122, upload_time = "2025-05-13T16:11:15.533Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/89/e63ec25b80290c4a923cdb5ecd5dbc85e310f93fb84b7f294006c9269d95/psycopg-3.2.2-py3-none-any.whl", hash = "sha256:babf565d459d8f72fb65da5e211dd0b58a52c51e4e1fa9cadecff42d6b7619b2", size = 197852 }, + { url = "https://files.pythonhosted.org/packages/44/b0/a73c195a56eb6b92e937a5ca58521a5c3346fb233345adc80fd3e2f542e2/psycopg-3.2.9-py3-none-any.whl", hash = "sha256:01a8dadccdaac2123c916208c96e06631641c0566b22005493f09663c7a8d3b6", size = 202705, upload_time = "2025-05-13T16:06:26.584Z" }, ] -[package.optional-dependencies] -binary = [ - { name = "psycopg-binary", marker = "implementation_name != 'pypy'" }, -] - -[[package]] -name = "psycopg-binary" -version = "3.2.2" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/01/42/f5a181d07c0ae5c8091449fda45d562d3b0861c127b94d7009eaea45c61f/psycopg_binary-3.2.2-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:8eacbf58d4f8d7bc82e0a60476afa2622b5a58f639a3cc2710e3e37b72aff3cb", size = 3381668 }, - { url = "https://files.pythonhosted.org/packages/ce/fb/66d2e3e5d550ba3b9d33e30bf6d5beb871a85eb95553c851fce7f09f8a1e/psycopg_binary-3.2.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:d07e62476ee8c54853b2b8cfdf3858a574218103b4cd213211f64326c7812437", size = 3502272 }, - { url = "https://files.pythonhosted.org/packages/f0/8d/758da39eca57f046ee712ad4c310840bcc08d889042d1b297cd28c78e909/psycopg_binary-3.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c22e615ee0ecfc6687bb8a39a4ed9d6bac030b5e72ac15e7324fd6e48979af71", size = 4467251 }, - { url = "https://files.pythonhosted.org/packages/91/bb/1abb1ccc318eb878acf9637479334de7406529516126e4af48b16dd85426/psycopg_binary-3.2.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec29c7ec136263628e3f09a53e51d0a4b1ad765a6e45135707bfa848b39113f9", size = 4268614 }, - { url = "https://files.pythonhosted.org/packages/f5/1a/14b4ae68f1c7cfba543883987d2f134eca31b0983bb684a52e0f51f3ac21/psycopg_binary-3.2.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:035753f80cbbf6aceca6386f53e139df70c7aca057b0592711047b5a8cfef8bb", size = 4512352 }, - { url = "https://files.pythonhosted.org/packages/12/44/53df01c7c7cffb351cafa88c58692fab0ab962edd89f22974cbfc38b6677/psycopg_binary-3.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9ee99336151ff7c30682f2ef9cb1174d235bc1471322faabba97f9db1398167", size = 4212477 }, - { url = "https://files.pythonhosted.org/packages/b7/31/c918927692fc5a9c4db0a7c454e1595e9d40378d5c526d26505f310e4068/psycopg_binary-3.2.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a60674dff4a4194e88312b463fb84ac80924c2b9e25d0e0460f3176bf1af4a6b", size = 3137907 }, - { url = "https://files.pythonhosted.org/packages/cb/65/538aa057b3e8245a31ea8baac93df9947ee1b2ebf4c02014a556cddd875e/psycopg_binary-3.2.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3c701507a49340de422d77a6ce95918a0019990bbf27daec35aa40050c6eadb6", size = 3113363 }, - { url = "https://files.pythonhosted.org/packages/dc/81/eaee4f05bcba19984615e90319c429d125d07e5f0fe8c8ec3025901de4df/psycopg_binary-3.2.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1b3c5a04eaf8866e399315cff2e810260cce10b797437a9f49fd71b5f4b94d0a", size = 3220512 }, - { url = "https://files.pythonhosted.org/packages/48/cc/1d0f82a47216f925e36be6f6d7be61984a5168ff8c0496c57f468cc0e219/psycopg_binary-3.2.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0ad9c09de4c262f516ae6891d042a4325649b18efa39dd82bbe0f7bc95c37bfb", size = 3255023 }, - { url = "https://files.pythonhosted.org/packages/d0/29/c45760ba6218eae37474aa5f46c1f55b290a6d4b86c0c59e60fa5613257a/psycopg_binary-3.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:bf1d3582185cb43ecc27403bee2f5405b7a45ccaab46c8508d9a9327341574fc", size = 2921688 }, - { url = "https://files.pythonhosted.org/packages/1f/1a/76299ad86a01f57a67961c4a45ce06c6eb8e76b8bc7bfb92548c62a6fa72/psycopg_binary-3.2.2-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:554d208757129d34fa47b7c890f9ef922f754e99c6b089cb3a209aa0fe282682", size = 3390336 }, - { url = "https://files.pythonhosted.org/packages/c2/1d/04fbcadd568eb0ee04b0d99286fe4ffd6c76c9cdd130e58d477617b77941/psycopg_binary-3.2.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:71dc3cc10d1fd7d26a3079d0a5b4a8e8ad0d7b89a702ceb7605a52e4395be122", size = 3507406 }, - { url = "https://files.pythonhosted.org/packages/60/00/094a437f68d83fef4dd139630dfb0e060fcf2a7ac68fffdb63b2f3eaa43a/psycopg_binary-3.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86f578d63f2e1fdf87c9adaed4ff23d7919bda8791cf1380fa4cf3a857ccb8b", size = 4463745 }, - { url = "https://files.pythonhosted.org/packages/ea/de/0303e807a33251dec41aec709c3041b9ffd86b67d997088c504a24e90ba3/psycopg_binary-3.2.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a4eb737682c02a602a12aa85a492608066f77793dab681b1c4e885fedc160b1", size = 4263212 }, - { url = "https://files.pythonhosted.org/packages/3f/0d/8fa059bd936bb8e95164cc549d2eaaeaeb7df3a069bbb0ea01b48fab10a4/psycopg_binary-3.2.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e120a576e74e4e612c48f4b021e322e320ca102534d78a0ca4db2ffd058ae8d", size = 4513242 }, - { url = "https://files.pythonhosted.org/packages/1f/a5/9904c4ae040eef6cdb81c04e43b834302cfd3e47ee7cab8878d114abb168/psycopg_binary-3.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:849d518e7d4c6186e1e48ea2ac2671912edf7e732fffe6f01dfed61cf0245de4", size = 4207852 }, - { url = "https://files.pythonhosted.org/packages/07/b7/24438b2ecb3ae8ceea44cf6e2bb92baac6be9b3d92c2940c89b3aa8e520e/psycopg_binary-3.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8ee2b19152bcec8f356f989c31768702be5f139b4d51094273c4a9ddc8c55380", size = 3134053 }, - { url = "https://files.pythonhosted.org/packages/83/e3/d0157858ad814cdc6cf9f9b7543c736f6b56ab9d8dc1b4ca56908ec03586/psycopg_binary-3.2.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:00273dd011892e8216fcef76b42f775ddaa6348664a7fffae2a27c9557f45bfa", size = 3110817 }, - { url = "https://files.pythonhosted.org/packages/9f/fc/8554c822a80a08cd17b9e2a4e8fc098c940e972e01bc9e3f3774b9e02d54/psycopg_binary-3.2.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4bcb489615d7e56d1de42937e6a0fc13f766505729afdb54c2947a52db295220", size = 3214760 }, - { url = "https://files.pythonhosted.org/packages/6a/4d/a12d8a301fbd4416ebdb3f019c777a17edea0452278f630f83237cbcc3d4/psycopg_binary-3.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:06963f88916a177df95aaed27101af0989ba206654743b1a0e050b9d8e734686", size = 3253951 }, - { url = "https://files.pythonhosted.org/packages/09/0f/120b190ddaf6afed1eaa2fbc89e29ec810d8af44ff3599521f69f89b64b3/psycopg_binary-3.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:ed1ad836a0c21890c7f84e73c7ef1ed0950e0e4b0d8e49b609b6fd9c13f2ca21", size = 2924949 }, - { url = "https://files.pythonhosted.org/packages/1e/9a/68b76a795fe620c8848c758d12860b8b94998f374882dbf8ea4bc343b9e1/psycopg_binary-3.2.2-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:0dd314229885a81f9497875295d8788e651b78945627540f1e78ed71595e614a", size = 3361334 }, - { url = "https://files.pythonhosted.org/packages/0d/0c/f91242672c58bce7c290e11128569fe66ed27552388499cd80d75a5d4d0d/psycopg_binary-3.2.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:989acbe2f552769cdb780346cea32d86e7c117044238d5172ac10b025fe47194", size = 3504380 }, - { url = "https://files.pythonhosted.org/packages/e4/45/5fa47240357dea3646f3492d20141a5869cfaedcd5c64499622db7b17a8f/psycopg_binary-3.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:566b1c530898590f0ac9d949cf94351c08d73c89f8800c74c0a63ffd89a383c8", size = 4443783 }, - { url = "https://files.pythonhosted.org/packages/ee/e5/9da098d1f7c1b064b39a2499cb4dfebe8fa5a48a132c3f544dab994199c4/psycopg_binary-3.2.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68d03efab7e2830a0df3aa4c29a708930e3f6b9fd98774ff9c4fd1f33deafecc", size = 4247070 }, - { url = "https://files.pythonhosted.org/packages/ba/44/c905a0ce2c66c0250a4ddce8eef41edc728bd2055ecaf8bd23468110c3f4/psycopg_binary-3.2.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e1f013bfb744023df23750fde51edcb606def8328473361db3c192c392c6060", size = 4483735 }, - { url = "https://files.pythonhosted.org/packages/30/2d/9f6bfcff78b643d220e088d91103fde70d193b9745d8999c7654ad45cd65/psycopg_binary-3.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a06136aab55a2de7dd4e2555badae276846827cfb023e6ba1b22f7a7b88e3f1b", size = 4186284 }, - { url = "https://files.pythonhosted.org/packages/44/48/79e7886a28818fdb4d5d39a86b5769bb33681ac23efe23accdaab42514c6/psycopg_binary-3.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:020c5154be144a1440cf87eae012b9004fb414ae4b9e7b1b9fb808fe39e96e83", size = 3110593 }, - { url = "https://files.pythonhosted.org/packages/5c/93/83d5610d259feb1d4d2d37cc0e1781f0d1632c885f5e2f85808b5b196552/psycopg_binary-3.2.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef341c556aeaa43a2729b07b04e20bfffdcf3d96c4a96e728ca94fe4ce632d8c", size = 3095074 }, - { url = "https://files.pythonhosted.org/packages/b6/94/3126db7a06fa9fe2ab3b1d6dd7a4add6bc1596b6864e01a77239702827b4/psycopg_binary-3.2.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66de2dd7d37bf66eb234ca9d907f5cd8caca43ff8d8a50dd5c15844d1cf0390c", size = 3184181 }, - { url = "https://files.pythonhosted.org/packages/6c/0e/6cce5ffaa25a25ede5ff08e757232bb425cacafe622627f29d286774073b/psycopg_binary-3.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2eb6f8f410dbbb71b8c633f283b8588b63bee0a7321f00ab76e9c800c593f732", size = 3229942 }, - { url = "https://files.pythonhosted.org/packages/10/31/951247b07205711115307f36ec3dbf6726101e086562febf6f989cbd6b95/psycopg_binary-3.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:b45553c6b614d02e1486585980afdfd18f0000aac668e2e87c6e32da1adb051a", size = 2912528 }, - { url = "https://files.pythonhosted.org/packages/87/e5/245f749abdfc33b42ec2bc4d89fe2cdb29cd40dca7156d0e09308c33f933/psycopg_binary-3.2.2-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:1ee891287c2da57e7fee31fbe2fbcdf57125768133d811b02e9523d5a052eb28", size = 3358682 }, - { url = "https://files.pythonhosted.org/packages/93/dc/047a90e2bfd80a8414f5a203c7ff1747e3b3f43231c3c8059e8be91849cc/psycopg_binary-3.2.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:5e95e4a8076ac7611e571623e1113fa84fd48c0459601969ffbf534d7aa236e7", size = 3500354 }, - { url = "https://files.pythonhosted.org/packages/df/72/b905dec41c30a8aad21f7767b21d3e5d3b9a7e92c1844678e4083d79257b/psycopg_binary-3.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6269d79a3d7d76b6fcf0fafae8444da00e83777a6c68c43851351a571ad37155", size = 4445322 }, - { url = "https://files.pythonhosted.org/packages/aa/41/aef11d4cda1af4a8181fbd578af39d6920232624fc6222f6b2f9758cc0e0/psycopg_binary-3.2.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6dd5d21a298c3c53af20ced8da4ae4cd038c6fe88c80842a8888fa3660b2094", size = 4248626 }, - { url = "https://files.pythonhosted.org/packages/6c/75/39ed8598f44188e4985f31f2639aa9894851fdfbf061bf926744b08b5790/psycopg_binary-3.2.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4cf64e41e238620f05aad862f06bc8424f8f320d8075f1499bd85a225d18bd57", size = 4485767 }, - { url = "https://files.pythonhosted.org/packages/00/5a/ecdc4cf957d0658f77cc6fa61f6ee2e5118c914e5f93497375023389a1e5/psycopg_binary-3.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c482c3236ded54add31136a91d5223b233ec301f297fa2db79747404222dca6", size = 4188840 }, - { url = "https://files.pythonhosted.org/packages/2d/71/af4c47a665d13d2477085f77fb64195da5d6463dd54fc3a8bdfd5c082d24/psycopg_binary-3.2.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0718be095cefdad712542169d16fa58b3bd9200a3de1b0217ae761cdec1cf569", size = 3114998 }, - { url = "https://files.pythonhosted.org/packages/38/8f/6d56168d2ce7e7d802e09a4288faceb52f28bd4023cde72ede9e848c9f9b/psycopg_binary-3.2.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fb303b03c243a9041e1873b596e246f7caaf01710b312fafa65b1db5cd77dd6f", size = 3095882 }, - { url = "https://files.pythonhosted.org/packages/8b/76/c77643d97292673d8a5e3eea643812d585993155658f840c86bfa855e077/psycopg_binary-3.2.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:705da5bc4364bd7529473225fca02b795653bc5bd824dbe43e1df0b1a40fe691", size = 3189435 }, - { url = "https://files.pythonhosted.org/packages/30/31/b4ea793bdf44acca51e3fa6f68cc80d03725e8ef87fc2ee2b332c49fa521/psycopg_binary-3.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:05406b96139912574571b1c56bb023839a9146cf4b57c4548f36251dd5909fa1", size = 3233951 }, - { url = "https://files.pythonhosted.org/packages/49/e3/633d6d05e40651acb30458e296c90e878fa4caf3b3c21bb9e6adc912b811/psycopg_binary-3.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:7c357cf87e8d7612cfe781225be7669f35038a765d1b53ec9605f6c5aef9ee85", size = 2913412 }, +[[package]] +name = "pyasn1" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload_time = "2024-09-10T22:41:42.55Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload_time = "2024-09-11T16:00:36.122Z" }, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyasn1" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload_time = "2025-03-28T02:41:22.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload_time = "2025-03-28T02:41:19.028Z" }, +] + +[[package]] +name = "pybase64" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/38/32/5d25a15256d2e80d1e92be821f19fc49190e65a90ea86733cb5af2285449/pybase64-1.4.1.tar.gz", hash = "sha256:03fc365c601671add4f9e0713c2bc2485fa4ab2b32f0d3bb060bd7e069cdaa43", size = 136836, upload_time = "2025-03-02T11:13:57.109Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/68/32b6446f679a0236735bf55f7b6595a5398d614f4c29e022d205d3359858/pybase64-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7628c86c431e04ae192ffeff0f8ae96b70ff4c053ad666625e7d6335196ea8a", size = 38066, upload_time = "2025-03-02T11:10:09.239Z" }, + { url = "https://files.pythonhosted.org/packages/73/10/73637b81b54d785bc5873ba6a28d5b5062493a3801c37afb7734fa78ed09/pybase64-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5202939f188cf150e1bc56f8b0da54a2cae2dcb9b27f4f7d313b358f707e1f7f", size = 31487, upload_time = "2025-03-02T11:10:11.285Z" }, + { url = "https://files.pythonhosted.org/packages/ed/5c/64ffd0c251fbd672c1306ddc792762eec09d39d7748d2656592b5e24cd39/pybase64-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e15e0eaf665bcc5427c1f32f604ed02d599b7777e8b7f8391e943a8d7bc443f", size = 57334, upload_time = "2025-03-02T11:10:13.656Z" }, + { url = "https://files.pythonhosted.org/packages/f6/69/d5b5f2a0d036bd0cadd17b0e581c11863074a3aab2090b07209c5fc1e18a/pybase64-1.4.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a0206b4b65f7cc0e0b6c26428765d3f0bae1312cb9d0fcebfad7cc24dfae4788", size = 54342, upload_time = "2025-03-02T11:10:16.003Z" }, + { url = "https://files.pythonhosted.org/packages/d1/bf/521c75786f519745de80b50eed22d73f16df201a954fbd613de0fa8e96b7/pybase64-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:732c5a4f7b389e6655375e75bde6fbab15508c8ae819bf41bda2c0202a59ff19", size = 56996, upload_time = "2025-03-02T11:10:18.491Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f7/a510a06bea28ce17caec42a31d6587e196c288a9604a09af39191b410e76/pybase64-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ecc374ea70bcef1884d3745480e07d1502bfbb41ac138cc38445c58c685dee32", size = 57544, upload_time = "2025-03-02T11:10:21.395Z" }, + { url = "https://files.pythonhosted.org/packages/3f/68/e592b7641932a54a8255253865a646cfad4921471407263c33af47976023/pybase64-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a0433a4e76f10862817f303c2bf74371e118cb24124836bfb0d95ebc182dc97", size = 66115, upload_time = "2025-03-02T11:10:23.279Z" }, + { url = "https://files.pythonhosted.org/packages/4c/46/24f97d76fec6532a7a60133fd9691a8afab6c7eab791368d14353dac5488/pybase64-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25b8405f632cce8b2e2f991ec2e4074b6a98ea44273cd218ffc3f88524ed162a", size = 68719, upload_time = "2025-03-02T11:10:24.868Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/5d8f1b530c4bc22c943ce4879f4e66aa879fe23ff411c8725b81a03bdf95/pybase64-1.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab02c31afe58b03d55a66fd9bd2cc4a04698b6bb2c33f68955aaec151542d838", size = 56136, upload_time = "2025-03-02T11:10:27.206Z" }, + { url = "https://files.pythonhosted.org/packages/f7/34/f40fea3fb306857d8e86473b1b5c2bc8d401c58ac424f59f8ec8fd7e55be/pybase64-1.4.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:8030ad8fe74c034cfad9a9a037c7b6ee85094b522c8b94c05e81df46e9a0eb5c", size = 49929, upload_time = "2025-03-02T11:10:29.069Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/7cd961e5cfb6fee5f3838586b0036876d0c58566f65d5973b78d4c090cc7/pybase64-1.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fb18c6a4defe85d23b16b1e6d6c7c3038cc402adfd8af14acc774dc585e814c4", size = 66380, upload_time = "2025-03-02T11:10:30.95Z" }, + { url = "https://files.pythonhosted.org/packages/85/a3/384601da9e09907d7509ec448afbce4be75a366db9ac36692c924dae7519/pybase64-1.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3f645629fae78e337faaa2ad7d35ced3f65b66f66629542d374641e30b218d1f", size = 55508, upload_time = "2025-03-02T11:10:32.13Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f7/74ae590bafed894c634bd3684ea0c86d4878c5ccd31e3a10ae1e5391bdf3/pybase64-1.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02ff55724616a11eebceac6c8445dadac79289ae8d1e40eed1b24aa7517fa225", size = 53781, upload_time = "2025-03-02T11:10:33.946Z" }, + { url = "https://files.pythonhosted.org/packages/2b/74/26c2d3f1893cc6904822fb8966dd722f432438273cce9e14f45ddfb454d0/pybase64-1.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:426e1ab673c744012d4b072fa6dc0642ca900b5c341f5e0c3a1c30b5dac332d1", size = 68233, upload_time = "2025-03-02T11:10:35.133Z" }, + { url = "https://files.pythonhosted.org/packages/09/10/f6a2bb04e11f7e639e7b59a41fd4597f68d9f3dde1014184ddaa480e3eac/pybase64-1.4.1-cp310-cp310-win32.whl", hash = "sha256:9101ee786648fc45b4765626eaf71114dd021b73543d8a3ab975df3dfdcca667", size = 34219, upload_time = "2025-03-02T11:10:36.298Z" }, + { url = "https://files.pythonhosted.org/packages/46/61/efc03bf48590681839f7391696c51d6d304f4d5df7f47828c373dc657c3c/pybase64-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9117f9be7f9a190e245dd7045b760b775d0b11ccc4414925cf725cdee807d5f6", size = 36414, upload_time = "2025-03-02T11:10:38.046Z" }, + { url = "https://files.pythonhosted.org/packages/55/b1/c6edc2630e4e574f681f60e2b00e7b852e7127f37603e440d28d21a2ea67/pybase64-1.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:aa4232a7082cca16db5de64f30056702d2d4ee4a5da1e2bbf9fd59bd3a67baed", size = 29637, upload_time = "2025-03-02T11:10:39.9Z" }, + { url = "https://files.pythonhosted.org/packages/ff/74/6f60bddbc6badd9a821e590f960fcf55b2008842b724552e062273d2f3a2/pybase64-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a230b64474f02075608d81fc19073c86cb4e63111d5c94f8bf77a3f2c0569956", size = 38068, upload_time = "2025-03-02T11:10:41.74Z" }, + { url = "https://files.pythonhosted.org/packages/0e/ce/1e56414745cb92ed0b22fd640af1d559d8161c28d26e288da7bcd2836f93/pybase64-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26ebcd7ccadde46ab35b16fee6f3b9478142833a164e10040b942ad5ccc8c4c0", size = 31485, upload_time = "2025-03-02T11:10:42.943Z" }, + { url = "https://files.pythonhosted.org/packages/96/38/f561708ec3740ac7f0395122672d663cc525295a1021a0b9c16aba19115b/pybase64-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f033501b08bbfc89a725f9a283b485348df2cb7acb8c41ca52ccfa76785d9343", size = 59642, upload_time = "2025-03-02T11:10:44.016Z" }, + { url = "https://files.pythonhosted.org/packages/43/70/71ed3d6d8905079668e75c6eeaa2e5c6fd4c33b0f8d4672e9ec99bb4925a/pybase64-1.4.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f6634d77e2f4b559daf30234f2dc679de9de3ba88effbdc0354a68b3aa2d29d3", size = 56464, upload_time = "2025-03-02T11:10:45.116Z" }, + { url = "https://files.pythonhosted.org/packages/60/53/1558b2d756896f15ea6396e2791bb710a9f289a3e2a24db5bfcf203d54e6/pybase64-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e1837488c7aa9bc7ba7bb0449908e57ecfe444e3c7347a905a87450c7e523e00", size = 59197, upload_time = "2025-03-02T11:10:47.009Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ae/300cb522d7f7eb543165843d28db4046909a8aabe110afa50cdab0947c9d/pybase64-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80e85e5ca298d3a9916c47e6fb0c47ebe5bf7996eac6983c887027b378e9bcae", size = 59803, upload_time = "2025-03-02T11:10:48.163Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b4/355f03c656bb331e623466bc6be4307efd2c41cfe58fdbf869cfb126a70c/pybase64-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:480c0c444eb07e4855d2eeab3f91a70331b75862d7a3dce0e6d4caddbfb4c09b", size = 68444, upload_time = "2025-03-02T11:10:49.32Z" }, + { url = "https://files.pythonhosted.org/packages/6f/4b/8d0730e9507026e05a7e34daddcac3d548cf8ce51cda858d033b142fed4d/pybase64-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e25723ecf7c439f650192d43699aab0a22850dca9cc6d60377c42bb4df7812", size = 71184, upload_time = "2025-03-02T11:10:51.147Z" }, + { url = "https://files.pythonhosted.org/packages/53/95/4e7cda0cd38e5e38697fcb62ede30c42ed8f5a2427adc73296d2746ec12c/pybase64-1.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:82efee94d6bd93f7787afc42f260fa0b60e24c8dc7f172bd45cfe99fa39567ff", size = 58479, upload_time = "2025-03-02T11:10:52.908Z" }, + { url = "https://files.pythonhosted.org/packages/26/ed/cac0892746795de07b2e71f48e651af597ccb8b52ba36ac2afaa07e7da55/pybase64-1.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c15765be7921914d0dad0a2fb57c35a1811e1cbe2d1e47c39e0c66ed7db52898", size = 52148, upload_time = "2025-03-02T11:10:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ca/8eaae3ee3c0e7b8a827c00ca5d850a9188e0cab9575764ae3638cce6ff78/pybase64-1.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d1dcddfa521fb6cbab0385032d43f0ca13212459abd6efc381b6e9847e9fbd79", size = 68801, upload_time = "2025-03-02T11:10:55.416Z" }, + { url = "https://files.pythonhosted.org/packages/c7/55/a847b02b2c17a6353e7156f995a44bdd26b326332851fb35ee3a5dfedf82/pybase64-1.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd1de051b9b032d84e799af498b44499e90122a095da7dad89c2873518473c67", size = 57857, upload_time = "2025-03-02T11:10:56.607Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6d/7562e73ab1dbf7d735e1a2da6be06a4bdb3bb8ddfecf3c29f25288528bb7/pybase64-1.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bf8213e6b8c658df2971c5a56df42202d7f89d5d6312d066d49923cc98a39299", size = 56075, upload_time = "2025-03-02T11:10:57.796Z" }, + { url = "https://files.pythonhosted.org/packages/99/a4/795935ad7ef2d066c082a9c852b8dd658f2c61a2de1742b46c576665edd5/pybase64-1.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7d83ab7822da5740f1d17c72fb451e9468e72976b89cfb9eb4f6a5b66491b5dc", size = 70710, upload_time = "2025-03-02T11:10:58.947Z" }, + { url = "https://files.pythonhosted.org/packages/13/16/b487ba1382fca5451cb18552333999a52c47d5e561d41b1ba17bf3bbf407/pybase64-1.4.1-cp311-cp311-win32.whl", hash = "sha256:7726e655134132dde59bddabcd74d140f818eeecc70d149267267d5e29335193", size = 34200, upload_time = "2025-03-02T11:11:00.841Z" }, + { url = "https://files.pythonhosted.org/packages/ea/a4/354cfd978a145cbeacba73f70266687f3dd34e1df1cdeb882c23153697a3/pybase64-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:9d5202cd4a8a0cd1b28c11730cf5da3c014450ad03732b5da03fac89b7693ec2", size = 36417, upload_time = "2025-03-02T11:11:02.006Z" }, + { url = "https://files.pythonhosted.org/packages/19/6c/5a576f95c79aa28a4b476ec84afe751ac0cab23572d9fd000b93adab6c76/pybase64-1.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:72808de9aab43112deb04003e5e0d060c7cb1a60c3dcf74bbf61a9d7c596c5af", size = 29638, upload_time = "2025-03-02T11:11:03.635Z" }, + { url = "https://files.pythonhosted.org/packages/a6/a9/43bac4f39401f7241d233ddaf9e6561860b2466798cfb83b9e7dbf89bc1b/pybase64-1.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bbdcf77e424c91389f22bf10158851ce05c602c50a74ccf5943ee3f5ef4ba489", size = 38152, upload_time = "2025-03-02T11:11:07.576Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/d0ae801e31a5052dbb1744a45318f822078dd4ce4cc7f49bfe97e7768f7e/pybase64-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af41e2e6015f980d15eae0df0c365df94c7587790aea236ba0bf48c65a9fa04e", size = 31488, upload_time = "2025-03-02T11:11:09.758Z" }, + { url = "https://files.pythonhosted.org/packages/be/34/bf4119a88b2ad0536a8ed9d66ce4d70ff8152eac00ef8a27e5ae35da4328/pybase64-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ac21c1943a15552347305943b1d0d6298fb64a98b67c750cb8fb2c190cdefd4", size = 59734, upload_time = "2025-03-02T11:11:11.493Z" }, + { url = "https://files.pythonhosted.org/packages/99/1c/1901547adc7d4f24bdcb2f75cb7dcd3975bff42f39da37d4bd218c608c60/pybase64-1.4.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:65567e8f4f31cf6e1a8cc570723cc6b18adda79b4387a18f8d93c157ff5f1979", size = 56529, upload_time = "2025-03-02T11:11:12.657Z" }, + { url = "https://files.pythonhosted.org/packages/c5/1e/1993e4b9a03e94fc53552285e3998079d864fff332798bf30c25afdac8f3/pybase64-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:988e987f8cfe2dfde7475baf5f12f82b2f454841aef3a174b694a57a92d5dfb0", size = 59114, upload_time = "2025-03-02T11:11:13.972Z" }, + { url = "https://files.pythonhosted.org/packages/c5/f6/061fee5b7ba38b8824dd95752ab7115cf183ffbd3330d5fc1734a47b0f9e/pybase64-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:92b2305ac2442b451e19d42c4650c3bb090d6aa9abd87c0c4d700267d8fa96b1", size = 60095, upload_time = "2025-03-02T11:11:15.182Z" }, + { url = "https://files.pythonhosted.org/packages/37/da/ccfe5d1a9f1188cd703390522e96a31045c5b93af84df04a98e69ada5c8b/pybase64-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1ff80e03357b09dab016f41b4c75cf06e9b19cda7f898e4f3681028a3dff29b", size = 68431, upload_time = "2025-03-02T11:11:17.059Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d3/8ca4b0695876b52c0073a3557a65850b6d5c723333b5a271ab10a1085852/pybase64-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cdda297e668e118f6b9ba804e858ff49e3dd945d01fdd147de90445fd08927d", size = 71417, upload_time = "2025-03-02T11:11:19.178Z" }, + { url = "https://files.pythonhosted.org/packages/94/34/5f8f72d1b7b4ddb64c48d60160f3f4f03cfd0bfd2e7068d4558499d948ed/pybase64-1.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51a24d21a21a959eb8884f24346a6480c4bd624aa7976c9761504d847a2f9364", size = 58429, upload_time = "2025-03-02T11:11:20.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/b7/edf53af308c6e8aada1e6d6a0a3789176af8cbae37a2ce084eb9da87bf33/pybase64-1.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b19e169ea1b8a15a03d3a379116eb7b17740803e89bc6eb3efcc74f532323cf7", size = 52228, upload_time = "2025-03-02T11:11:21.632Z" }, + { url = "https://files.pythonhosted.org/packages/0c/bf/c9df141e24a259f38a38bdda5a3b63206f13e612ecbd3880fa10625e0294/pybase64-1.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8a9f1b614efd41240c9bb2cf66031aa7a2c3c092c928f9d429511fe18d4a3fd1", size = 68632, upload_time = "2025-03-02T11:11:23.56Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ae/1aec72325a3c48f7776cc55a3bab8b168eb77aea821253da8b9f09713734/pybase64-1.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d9947b5e289e2c5b018ddc2aee2b9ed137b8aaaba7edfcb73623e576a2407740", size = 57682, upload_time = "2025-03-02T11:11:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/4d/7a/7ad2799c0b3c4e2f7b993e1636468445c30870ca5485110b589b8921808d/pybase64-1.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ba4184ea43aa88a5ab8d6d15db284689765c7487ff3810764d8d823b545158e6", size = 56308, upload_time = "2025-03-02T11:11:26.803Z" }, + { url = "https://files.pythonhosted.org/packages/be/01/6008a4fbda0c4308dab00b95aedde8748032d7620bd95b686619c66917fe/pybase64-1.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4471257628785296efb2d50077fb9dfdbd4d2732c3487795224dd2644216fb07", size = 70784, upload_time = "2025-03-02T11:11:28.427Z" }, + { url = "https://files.pythonhosted.org/packages/27/31/913365a4f0e2922ec369ddaa3a1d6c11059acbe54531b003653efa007a48/pybase64-1.4.1-cp312-cp312-win32.whl", hash = "sha256:614561297ad14de315dd27381fd6ec3ea4de0d8206ba4c7678449afaff8a2009", size = 34271, upload_time = "2025-03-02T11:11:30.585Z" }, + { url = "https://files.pythonhosted.org/packages/d9/98/4d514d3e4c04819d80bccf9ea7b30d1cfc701832fa5ffca168f585004488/pybase64-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:35635db0d64fcbe9b3fad265314c052c47dc9bcef8dea17493ea8e3c15b2b972", size = 36496, upload_time = "2025-03-02T11:11:32.552Z" }, + { url = "https://files.pythonhosted.org/packages/c4/61/01353bc9c461e7b36d692daca3eee9616d8936ea6d8a64255ef7ec9ac307/pybase64-1.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:b4ccb438c4208ff41a260b70994c30a8631051f3b025cdca48be586b068b8f49", size = 29692, upload_time = "2025-03-02T11:11:33.735Z" }, + { url = "https://files.pythonhosted.org/packages/4b/1a/4e243ba702c07df3df3ba1795cfb02cf7a4242c53fc574b06a2bfa4f8478/pybase64-1.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1c38d9c4a7c132d45859af8d5364d3ce90975a42bd5995d18d174fb57621973", size = 38149, upload_time = "2025-03-02T11:11:35.537Z" }, + { url = "https://files.pythonhosted.org/packages/9c/35/3eae81bc8688a83f8b5bb84979d88e2cc3c3279a3b870a506f277d746c56/pybase64-1.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ab0b93ea93cf1f56ca4727d678a9c0144c2653e9de4e93e789a92b4e098c07d9", size = 31485, upload_time = "2025-03-02T11:11:36.656Z" }, + { url = "https://files.pythonhosted.org/packages/48/55/d99b9ff8083573bbf97fc433bbc20e2efb612792025f3bad0868c96c37ce/pybase64-1.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:644f393e9bb7f3bacc5cbd3534d02e1b660b258fc8315ecae74d2e23265e5c1f", size = 59738, upload_time = "2025-03-02T11:11:38.468Z" }, + { url = "https://files.pythonhosted.org/packages/63/3c/051512b9e139a11585447b286ede5ac3b284ce5df85de37eb8cff57d90f8/pybase64-1.4.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff172a4dacbd964e5edcf1c2152dae157aabf856508aed15276f46d04a22128e", size = 56239, upload_time = "2025-03-02T11:11:39.718Z" }, + { url = "https://files.pythonhosted.org/packages/af/11/f40c5cca587274d50baee88540a7839576204cb425fe2f73a752ea48ae74/pybase64-1.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2ab7b4535abc72d40114540cae32c9e07d76ffba132bdd5d4fff5fe340c5801", size = 59137, upload_time = "2025-03-02T11:11:41.524Z" }, + { url = "https://files.pythonhosted.org/packages/1a/a9/ace9f6d0926962c083671d7df247de442ef63cd06bd134f7c8251aab5c51/pybase64-1.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da66eb7cfb641486944fb0b95ab138e691ab78503115022caf992b6c89b10396", size = 60109, upload_time = "2025-03-02T11:11:42.699Z" }, + { url = "https://files.pythonhosted.org/packages/88/9c/d4e308b4b4e3b513bc084fc71b4e2dd00d21d4cd245a9a28144d2f6b03c9/pybase64-1.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:678f573ea1d06183b32d0336044fb5db60396333599dffcce28ffa3b68319fc0", size = 68391, upload_time = "2025-03-02T11:11:43.898Z" }, + { url = "https://files.pythonhosted.org/packages/53/87/e184bf982a3272f1021f417e5a18fac406e042c606950e9082fc3b0cec30/pybase64-1.4.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bccdf340c2a1d3dd1f41528f192265ddce7f8df1ee4f7b5b9163cdba0fe0ccb", size = 71438, upload_time = "2025-03-02T11:11:45.112Z" }, + { url = "https://files.pythonhosted.org/packages/2f/7f/d6e6a72db055eb2dc01ab877d8ee39d05cb665403433ff922fb95d1003ad/pybase64-1.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1ddf6366c34eb78931fd8a47c00cb886ba187a5ff8e6dbffe1d9dae4754b6c28", size = 58437, upload_time = "2025-03-02T11:11:47.034Z" }, + { url = "https://files.pythonhosted.org/packages/71/ef/c9051f2c0128194b861f3cd3b2d211b8d4d21ed2be354aa669fe29a059d8/pybase64-1.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:500afcb717a84e262c68f0baf9c56abaf97e2f058ba80c5546a9ed21ff4b705f", size = 52267, upload_time = "2025-03-02T11:11:48.448Z" }, + { url = "https://files.pythonhosted.org/packages/12/92/ae30a54eaa437989839c4f2404c1f004d7383c0f46d6ebb83546d587d2a7/pybase64-1.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d2de043312a1e7f15ee6d2b7d9e39ee6afe24f144e2248cce942b6be357b70d8", size = 68659, upload_time = "2025-03-02T11:11:49.615Z" }, + { url = "https://files.pythonhosted.org/packages/2b/65/d94788a35904f21694c4c581bcee2e165bec2408cc6fbed85a7fef5959ae/pybase64-1.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c36e214c25fb8dd4f3ecdaa0ff90073b793056e0065cc0a1e1e5525a6866a1ad", size = 57727, upload_time = "2025-03-02T11:11:50.843Z" }, + { url = "https://files.pythonhosted.org/packages/d0/97/8db416066b7917909c38346c03a8f3e6d4fc8a1dc98636408156514269ad/pybase64-1.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:8ec003224f6e36e8e607a1bb8df182b367c87ca7135788ffe89173c7d5085005", size = 56302, upload_time = "2025-03-02T11:11:52.547Z" }, + { url = "https://files.pythonhosted.org/packages/70/0b/98f0601391befe0f19aa8cbda821c62d95056a94cc41d452fe893d205523/pybase64-1.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c536c6ed161e6fb19f6acd6074f29a4c78cb41c9155c841d56aec1a4d20d5894", size = 70779, upload_time = "2025-03-02T11:11:53.735Z" }, + { url = "https://files.pythonhosted.org/packages/cc/07/116119c5b20688c052697f677cf56f05aa766535ff7691aba38447d4a0d8/pybase64-1.4.1-cp313-cp313-win32.whl", hash = "sha256:1d34872e5aa2eff9dc54cedaf36038bbfbd5a3440fdf0bdc5b3c81c54ef151ea", size = 34266, upload_time = "2025-03-02T11:11:54.892Z" }, + { url = "https://files.pythonhosted.org/packages/c0/f5/a7eed9f3692209a9869a28bdd92deddf8cbffb06b40954f89f4577e5c96e/pybase64-1.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b7765515d7e0a48ddfde914dc2b1782234ac188ce3fab173b078a6e82ec7017", size = 36488, upload_time = "2025-03-02T11:11:56.063Z" }, + { url = "https://files.pythonhosted.org/packages/5d/8a/0d65c4dcda06487305035f24888ffed219897c03fb7834635d5d5e27dae1/pybase64-1.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:7fb782f3ceb30e24dc4d8d99c1221a381917bffaf85d29542f0f25b51829987c", size = 29690, upload_time = "2025-03-02T11:11:57.702Z" }, + { url = "https://files.pythonhosted.org/packages/a3/83/646d65fafe5e6edbdaf4c9548efb2e1dd7784caddbde3ff8a843dd942b0f/pybase64-1.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2a98d323e97444a38db38e022ccaf1d3e053b1942455790a93f29086c687855f", size = 38506, upload_time = "2025-03-02T11:11:58.936Z" }, + { url = "https://files.pythonhosted.org/packages/87/14/dbf7fbbe91d71c8044fefe20d22480ad64097e2ba424944de512550e12a4/pybase64-1.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:19ef58d36b9b32024768fcedb024f32c05eb464128c75c07cac2b50c9ed47f4a", size = 31894, upload_time = "2025-03-02T11:12:00.762Z" }, + { url = "https://files.pythonhosted.org/packages/bd/5d/f8a47da2a5f8b599297b307d3bd0293adedc4e135be310620f061906070f/pybase64-1.4.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04fee0f5c174212868fde97b109db8fac8249b306a00ea323531ee61c7b0f398", size = 65212, upload_time = "2025-03-02T11:12:01.911Z" }, + { url = "https://files.pythonhosted.org/packages/90/95/ad9869c7cdcce3e8ada619dab5f9f2eff315ffb001704a3718c1597a2119/pybase64-1.4.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47737ff9eabc14b7553de6bc6395d67c5be80afcdbd25180285d13e089e40888", size = 60300, upload_time = "2025-03-02T11:12:03.071Z" }, + { url = "https://files.pythonhosted.org/packages/c2/91/4d8268b2488ae10c485cba04ecc23a5a7bdfb47ce9b876017b11ea0249a2/pybase64-1.4.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d8b5888cc239654fe68a0db196a18575ffc8b1c8c8f670c2971a44e3b7fe682", size = 63773, upload_time = "2025-03-02T11:12:04.231Z" }, + { url = "https://files.pythonhosted.org/packages/ae/1a/8afd27facc0723b1d69231da8c59a2343feb255f5db16f8b8765ddf1600b/pybase64-1.4.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a1af8d387dbce05944b65a618639918804b2d4438fed32bb7f06d9c90dbed01", size = 64684, upload_time = "2025-03-02T11:12:05.409Z" }, + { url = "https://files.pythonhosted.org/packages/cc/cd/422c74397210051125419fc8e425506ff27c04665459e18c8f7b037a754b/pybase64-1.4.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b0093c52bd099b80e422ad8cddf6f2c1ac1b09cb0922cca04891d736c2ad647", size = 72880, upload_time = "2025-03-02T11:12:06.652Z" }, + { url = "https://files.pythonhosted.org/packages/04/c1/c4f02f1d5f8e8a3d75715a3dd04196dde9e263e471470d099a26e91ebe2f/pybase64-1.4.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15e54f9b2a1686f5bbdc4ac8440b6f6145d9699fd53aa30f347931f3063b0915", size = 75344, upload_time = "2025-03-02T11:12:07.816Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0b/013006ca984f0472476cf7c0540db2e2b1f997d52977b15842a7681ab79c/pybase64-1.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3a0fdcf13f986c82f7ef04a1cd1163c70f39662d6f02aa4e7b448dacb966b39f", size = 63439, upload_time = "2025-03-02T11:12:09.669Z" }, + { url = "https://files.pythonhosted.org/packages/8a/d5/7848543b3c8dcc5396be574109acbe16706e6a9b4dbd9fc4e22f211668a9/pybase64-1.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:ac03f8eba72dd6da15dc25bb3e1b440ad21f5cb7ee2e6ffbbae4bd1b206bb503", size = 56004, upload_time = "2025-03-02T11:12:10.981Z" }, + { url = "https://files.pythonhosted.org/packages/63/58/70de1efb1b6f21d7aaea33578868214f82925d969e2091f7de3175a10092/pybase64-1.4.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:ea835272570aa811e08ae17612632b057623a9b27265d44288db666c02b438dc", size = 72460, upload_time = "2025-03-02T11:12:13.122Z" }, + { url = "https://files.pythonhosted.org/packages/90/0d/aa52dd1b1f25b98b1d94cc0522f864b03de55aa115de67cb6dbbddec4f46/pybase64-1.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:8f52c4c29a35381f3ae06d520144a0707132f2cbfb53bc907b74811734bc4ef3", size = 62295, upload_time = "2025-03-02T11:12:15.004Z" }, + { url = "https://files.pythonhosted.org/packages/39/cf/4d378a330249c937676ee8eab7992ec700ade362f35db36c15922b33b1c8/pybase64-1.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fa5cdabcb4d21b7e56d0b2edd7ed6fa933ac3535be30c2a9cf0a2e270c5369c8", size = 60604, upload_time = "2025-03-02T11:12:16.23Z" }, + { url = "https://files.pythonhosted.org/packages/15/45/e3f23929018d0aada84246ddd398843050971af614da67450bb20f45f880/pybase64-1.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8db9acf239bb71a888748bc9ffc12c97c1079393a38bc180c0548330746ece94", size = 74500, upload_time = "2025-03-02T11:12:17.48Z" }, + { url = "https://files.pythonhosted.org/packages/8d/98/6d2adaec318cae6ee968a10df0a7e870f17ee385ef623bcb2ab63fa11b59/pybase64-1.4.1-cp313-cp313t-win32.whl", hash = "sha256:bc06186cfa9a43e871fdca47c1379bdf1cfe964bd94a47f0919a1ffab195b39e", size = 34543, upload_time = "2025-03-02T11:12:18.625Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e7/1823de02d2c23324cf1142e9dce53b032085cee06c3f982806040f975ce7/pybase64-1.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:02c3647d270af1a3edd35e485bb7ccfe82180b8347c49e09973466165c03d7aa", size = 36909, upload_time = "2025-03-02T11:12:20.122Z" }, + { url = "https://files.pythonhosted.org/packages/43/6a/8ec0e4461bf89ef0499ef6c746b081f3520a1e710aeb58730bae693e0681/pybase64-1.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:4b3635e5873707906e72963c447a67969cfc6bac055432a57a91d7a4d5164fdf", size = 29961, upload_time = "2025-03-02T11:12:21.908Z" }, + { url = "https://files.pythonhosted.org/packages/34/22/4fcbd6b8dcbcabe30fdcd4d5145445cffc6724a90425dda0043c1cbd4919/pybase64-1.4.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b0bdb646f859132c68230efabc09fd8828ca20c59de7d53082f372c4b8af7aaa", size = 38055, upload_time = "2025-03-02T11:13:21.751Z" }, + { url = "https://files.pythonhosted.org/packages/16/d8/9a6c325c31c81897349c83bd4857f09f78d342bb03f0107df5ab9de0de1a/pybase64-1.4.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d4bf9c94bc948cb3c3b0e38074d0de04f23d35765a306059417751e982da384", size = 31354, upload_time = "2025-03-02T11:13:23.016Z" }, + { url = "https://files.pythonhosted.org/packages/72/30/4212a953d3fc4affa5ffa652096440daf1093ad6db734b17231f1f82a79a/pybase64-1.4.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b31da1466faf3cfa775027d161d07640f3d1c6bbc8edf3725f8833ed0b25a2f", size = 35265, upload_time = "2025-03-02T11:13:24.81Z" }, + { url = "https://files.pythonhosted.org/packages/12/b4/a54e9e3eb7f11f80a659eed05b0bfa6bc68ad8e7ec075e40236c7987d18e/pybase64-1.4.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc9a3f56630e707dbe7a34383943a1daefa699bc99c3250f8af9f8245056fccd", size = 40968, upload_time = "2025-03-02T11:13:26.165Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f1/d6bc1a548edc806ce8d25b6d761d2aed68abc3162f072f984940f59ae15b/pybase64-1.4.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdabd0d7fda2517ff36559189f7c00b376feafbd5d23bf5914e256246d29d7e", size = 41117, upload_time = "2025-03-02T11:13:27.433Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6c/5952201a062ac4746fc767c8556a7b933cb59295068b9dba0bcba8bde378/pybase64-1.4.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62e42807bde3a7d18a0a7d35bd7fb1fe68f99c897eea8d3ea3aa0791b91358eb", size = 36804, upload_time = "2025-03-02T11:13:29.414Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3e/90633da698742bfd11a1d6301295e9974c2f9e0e510aaae8cdd26cd10880/pybase64-1.4.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e8c28700ccf55348a7a4ad3554e6b4c5b83c640bfaa272fee6b4d0030566fe05", size = 38056, upload_time = "2025-03-02T11:13:30.6Z" }, + { url = "https://files.pythonhosted.org/packages/b1/02/79bdf96a780c3d1f4e9f1b583525247f3a33afebbba1e12e57fb28c395e7/pybase64-1.4.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:eb09bd829d4fef567505212b6bb87cd7a42b5aa2a3b83fc2bd61a188db7793e0", size = 31352, upload_time = "2025-03-02T11:13:32.395Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d0/4f8135c2459724a834a70481f6bb8af3e89ff527c9b5cff0b799321e29d6/pybase64-1.4.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc9504c4c2e893e0a6c1cc80bce51907e3461288289f630eab22b5735eba1104", size = 35262, upload_time = "2025-03-02T11:13:33.55Z" }, + { url = "https://files.pythonhosted.org/packages/21/c6/45ace9c84ccc9d51002c5bcfe8c50e7660f064e2bc272a30c7802036f1f3/pybase64-1.4.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:45a785a3d29faf0309910d96e13c34870adb4ae43ea262868c6cf6a311936f37", size = 40968, upload_time = "2025-03-02T11:13:34.748Z" }, + { url = "https://files.pythonhosted.org/packages/9d/d5/1bf0b5354ca404ba096e99e2634c27836c212affe722bd2ade7103fd3c48/pybase64-1.4.1-pp311-pypy311_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10e2cb40869fe703484ba89ae50e05d63a169f7c42db59e29f8af0890c50515d", size = 41107, upload_time = "2025-03-02T11:13:35.996Z" }, + { url = "https://files.pythonhosted.org/packages/0b/d7/0987f3d1c8196ad9affea9102c135a45342e1fa5affb849bf31bd633d000/pybase64-1.4.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:1a18644fb3e940ed622738f2ee14d9a2811bb542ffd3f85c3fb661130675ac4f", size = 36817, upload_time = "2025-03-02T11:13:37.624Z" }, +] + +[[package]] +name = "pycodestyle" +version = "2.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/e0/abfd2a0d2efe47670df87f3e3a0e2edda42f055053c85361f19c0e2c1ca8/pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", size = 39472, upload_time = "2025-06-20T18:49:48.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d", size = 31594, upload_time = "2025-06-20T18:49:47.491Z" }, +] + +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload_time = "2024-03-30T13:22:22.564Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload_time = "2024-03-30T13:22:20.476Z" }, ] [[package]] @@ -980,9 +3104,14 @@ dependencies = [ { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917 } +sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917, upload_time = "2024-09-17T15:59:54.273Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/e4/ba44652d562cbf0bf320e0f3810206149c8a4e99cdbf66da82e97ab53a15/pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12", size = 434928 }, + { url = "https://files.pythonhosted.org/packages/df/e4/ba44652d562cbf0bf320e0f3810206149c8a4e99cdbf66da82e97ab53a15/pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12", size = 434928, upload_time = "2024-09-17T15:59:51.827Z" }, +] + +[package.optional-dependencies] +email = [ + { name = "email-validator" }, ] [[package]] @@ -992,240 +3121,874 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/8b/d3ae387f66277bd8104096d6ec0a145f4baa2966ebb2cad746c0920c9526/pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", size = 1867835 }, - { url = "https://files.pythonhosted.org/packages/46/76/f68272e4c3a7df8777798282c5e47d508274917f29992d84e1898f8908c7/pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", size = 1776689 }, - { url = "https://files.pythonhosted.org/packages/cc/69/5f945b4416f42ea3f3bc9d2aaec66c76084a6ff4ff27555bf9415ab43189/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", size = 1800748 }, - { url = "https://files.pythonhosted.org/packages/50/ab/891a7b0054bcc297fb02d44d05c50e68154e31788f2d9d41d0b72c89fdf7/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", size = 1806469 }, - { url = "https://files.pythonhosted.org/packages/31/7c/6e3fa122075d78f277a8431c4c608f061881b76c2b7faca01d317ee39b5d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", size = 2002246 }, - { url = "https://files.pythonhosted.org/packages/ad/6f/22d5692b7ab63fc4acbc74de6ff61d185804a83160adba5e6cc6068e1128/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", size = 2659404 }, - { url = "https://files.pythonhosted.org/packages/11/ac/1e647dc1121c028b691028fa61a4e7477e6aeb5132628fde41dd34c1671f/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", size = 2053940 }, - { url = "https://files.pythonhosted.org/packages/91/75/984740c17f12c3ce18b5a2fcc4bdceb785cce7df1511a4ce89bca17c7e2d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", size = 1921437 }, - { url = "https://files.pythonhosted.org/packages/a0/74/13c5f606b64d93f0721e7768cd3e8b2102164866c207b8cd6f90bb15d24f/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", size = 1966129 }, - { url = "https://files.pythonhosted.org/packages/18/03/9c4aa5919457c7b57a016c1ab513b1a926ed9b2bb7915bf8e506bf65c34b/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", size = 2110908 }, - { url = "https://files.pythonhosted.org/packages/92/2c/053d33f029c5dc65e5cf44ff03ceeefb7cce908f8f3cca9265e7f9b540c8/pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", size = 1735278 }, - { url = "https://files.pythonhosted.org/packages/de/81/7dfe464eca78d76d31dd661b04b5f2036ec72ea8848dd87ab7375e185c23/pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", size = 1917453 }, - { url = "https://files.pythonhosted.org/packages/5d/30/890a583cd3f2be27ecf32b479d5d615710bb926d92da03e3f7838ff3e58b/pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", size = 1865160 }, - { url = "https://files.pythonhosted.org/packages/1d/9a/b634442e1253bc6889c87afe8bb59447f106ee042140bd57680b3b113ec7/pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", size = 1776777 }, - { url = "https://files.pythonhosted.org/packages/75/9a/7816295124a6b08c24c96f9ce73085032d8bcbaf7e5a781cd41aa910c891/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", size = 1799244 }, - { url = "https://files.pythonhosted.org/packages/a9/8f/89c1405176903e567c5f99ec53387449e62f1121894aa9fc2c4fdc51a59b/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607", size = 1805307 }, - { url = "https://files.pythonhosted.org/packages/d5/a5/1a194447d0da1ef492e3470680c66048fef56fc1f1a25cafbea4bc1d1c48/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", size = 2000663 }, - { url = "https://files.pythonhosted.org/packages/13/a5/1df8541651de4455e7d587cf556201b4f7997191e110bca3b589218745a5/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", size = 2655941 }, - { url = "https://files.pythonhosted.org/packages/44/31/a3899b5ce02c4316865e390107f145089876dff7e1dfc770a231d836aed8/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", size = 2052105 }, - { url = "https://files.pythonhosted.org/packages/1b/aa/98e190f8745d5ec831f6d5449344c48c0627ac5fed4e5340a44b74878f8e/pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", size = 1919967 }, - { url = "https://files.pythonhosted.org/packages/ae/35/b6e00b6abb2acfee3e8f85558c02a0822e9a8b2f2d812ea8b9079b118ba0/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", size = 1964291 }, - { url = "https://files.pythonhosted.org/packages/13/46/7bee6d32b69191cd649bbbd2361af79c472d72cb29bb2024f0b6e350ba06/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", size = 2109666 }, - { url = "https://files.pythonhosted.org/packages/39/ef/7b34f1b122a81b68ed0a7d0e564da9ccdc9a2924c8d6c6b5b11fa3a56970/pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", size = 1732940 }, - { url = "https://files.pythonhosted.org/packages/2f/76/37b7e76c645843ff46c1d73e046207311ef298d3f7b2f7d8f6ac60113071/pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", size = 1916804 }, - { url = "https://files.pythonhosted.org/packages/74/7b/8e315f80666194b354966ec84b7d567da77ad927ed6323db4006cf915f3f/pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", size = 1856459 }, - { url = "https://files.pythonhosted.org/packages/14/de/866bdce10ed808323d437612aca1ec9971b981e1c52e5e42ad9b8e17a6f6/pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", size = 1770007 }, - { url = "https://files.pythonhosted.org/packages/dc/69/8edd5c3cd48bb833a3f7ef9b81d7666ccddd3c9a635225214e044b6e8281/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", size = 1790245 }, - { url = "https://files.pythonhosted.org/packages/80/33/9c24334e3af796ce80d2274940aae38dd4e5676298b4398eff103a79e02d/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", size = 1801260 }, - { url = "https://files.pythonhosted.org/packages/a5/6f/e9567fd90104b79b101ca9d120219644d3314962caa7948dd8b965e9f83e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", size = 1996872 }, - { url = "https://files.pythonhosted.org/packages/2d/ad/b5f0fe9e6cfee915dd144edbd10b6e9c9c9c9d7a56b69256d124b8ac682e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", size = 2661617 }, - { url = "https://files.pythonhosted.org/packages/06/c8/7d4b708f8d05a5cbfda3243aad468052c6e99de7d0937c9146c24d9f12e9/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", size = 2071831 }, - { url = "https://files.pythonhosted.org/packages/89/4d/3079d00c47f22c9a9a8220db088b309ad6e600a73d7a69473e3a8e5e3ea3/pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", size = 1917453 }, - { url = "https://files.pythonhosted.org/packages/e9/88/9df5b7ce880a4703fcc2d76c8c2d8eb9f861f79d0c56f4b8f5f2607ccec8/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", size = 1968793 }, - { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, - { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, - { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, - { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, - { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, - { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, - { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, - { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, - { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, - { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, - { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, - { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, - { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, - { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, - { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, - { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135 }, - { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583 }, - { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637 }, - { url = "https://files.pythonhosted.org/packages/29/18/812222b6d18c2d13eebbb0f7cdc170a408d9ced65794fdb86147c77e1982/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", size = 1941963 }, - { url = "https://files.pythonhosted.org/packages/0f/36/c1f3642ac3f05e6bb4aec3ffc399fa3f84895d259cf5f0ce3054b7735c29/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", size = 1915332 }, - { url = "https://files.pythonhosted.org/packages/f7/ca/9c0854829311fb446020ebb540ee22509731abad886d2859c855dd29b904/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", size = 1957926 }, - { url = "https://files.pythonhosted.org/packages/c0/1c/7836b67c42d0cd4441fcd9fafbf6a027ad4b79b6559f80cf11f89fd83648/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", size = 2100342 }, - { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344 }, +sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156, upload_time = "2024-09-16T16:06:44.786Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/8b/d3ae387f66277bd8104096d6ec0a145f4baa2966ebb2cad746c0920c9526/pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", size = 1867835, upload_time = "2024-09-16T16:03:57.223Z" }, + { url = "https://files.pythonhosted.org/packages/46/76/f68272e4c3a7df8777798282c5e47d508274917f29992d84e1898f8908c7/pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", size = 1776689, upload_time = "2024-09-16T16:03:59.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/69/5f945b4416f42ea3f3bc9d2aaec66c76084a6ff4ff27555bf9415ab43189/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", size = 1800748, upload_time = "2024-09-16T16:04:01.011Z" }, + { url = "https://files.pythonhosted.org/packages/50/ab/891a7b0054bcc297fb02d44d05c50e68154e31788f2d9d41d0b72c89fdf7/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", size = 1806469, upload_time = "2024-09-16T16:04:02.323Z" }, + { url = "https://files.pythonhosted.org/packages/31/7c/6e3fa122075d78f277a8431c4c608f061881b76c2b7faca01d317ee39b5d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", size = 2002246, upload_time = "2024-09-16T16:04:03.688Z" }, + { url = "https://files.pythonhosted.org/packages/ad/6f/22d5692b7ab63fc4acbc74de6ff61d185804a83160adba5e6cc6068e1128/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", size = 2659404, upload_time = "2024-09-16T16:04:05.299Z" }, + { url = "https://files.pythonhosted.org/packages/11/ac/1e647dc1121c028b691028fa61a4e7477e6aeb5132628fde41dd34c1671f/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", size = 2053940, upload_time = "2024-09-16T16:04:06.604Z" }, + { url = "https://files.pythonhosted.org/packages/91/75/984740c17f12c3ce18b5a2fcc4bdceb785cce7df1511a4ce89bca17c7e2d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", size = 1921437, upload_time = "2024-09-16T16:04:08.071Z" }, + { url = "https://files.pythonhosted.org/packages/a0/74/13c5f606b64d93f0721e7768cd3e8b2102164866c207b8cd6f90bb15d24f/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", size = 1966129, upload_time = "2024-09-16T16:04:10.363Z" }, + { url = "https://files.pythonhosted.org/packages/18/03/9c4aa5919457c7b57a016c1ab513b1a926ed9b2bb7915bf8e506bf65c34b/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", size = 2110908, upload_time = "2024-09-16T16:04:12.412Z" }, + { url = "https://files.pythonhosted.org/packages/92/2c/053d33f029c5dc65e5cf44ff03ceeefb7cce908f8f3cca9265e7f9b540c8/pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", size = 1735278, upload_time = "2024-09-16T16:04:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/de/81/7dfe464eca78d76d31dd661b04b5f2036ec72ea8848dd87ab7375e185c23/pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", size = 1917453, upload_time = "2024-09-16T16:04:15.996Z" }, + { url = "https://files.pythonhosted.org/packages/5d/30/890a583cd3f2be27ecf32b479d5d615710bb926d92da03e3f7838ff3e58b/pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", size = 1865160, upload_time = "2024-09-16T16:04:18.628Z" }, + { url = "https://files.pythonhosted.org/packages/1d/9a/b634442e1253bc6889c87afe8bb59447f106ee042140bd57680b3b113ec7/pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", size = 1776777, upload_time = "2024-09-16T16:04:20.038Z" }, + { url = "https://files.pythonhosted.org/packages/75/9a/7816295124a6b08c24c96f9ce73085032d8bcbaf7e5a781cd41aa910c891/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", size = 1799244, upload_time = "2024-09-16T16:04:21.799Z" }, + { url = "https://files.pythonhosted.org/packages/a9/8f/89c1405176903e567c5f99ec53387449e62f1121894aa9fc2c4fdc51a59b/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607", size = 1805307, upload_time = "2024-09-16T16:04:23.324Z" }, + { url = "https://files.pythonhosted.org/packages/d5/a5/1a194447d0da1ef492e3470680c66048fef56fc1f1a25cafbea4bc1d1c48/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", size = 2000663, upload_time = "2024-09-16T16:04:25.203Z" }, + { url = "https://files.pythonhosted.org/packages/13/a5/1df8541651de4455e7d587cf556201b4f7997191e110bca3b589218745a5/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", size = 2655941, upload_time = "2024-09-16T16:04:27.211Z" }, + { url = "https://files.pythonhosted.org/packages/44/31/a3899b5ce02c4316865e390107f145089876dff7e1dfc770a231d836aed8/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", size = 2052105, upload_time = "2024-09-16T16:04:28.611Z" }, + { url = "https://files.pythonhosted.org/packages/1b/aa/98e190f8745d5ec831f6d5449344c48c0627ac5fed4e5340a44b74878f8e/pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", size = 1919967, upload_time = "2024-09-16T16:04:30.045Z" }, + { url = "https://files.pythonhosted.org/packages/ae/35/b6e00b6abb2acfee3e8f85558c02a0822e9a8b2f2d812ea8b9079b118ba0/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", size = 1964291, upload_time = "2024-09-16T16:04:32.376Z" }, + { url = "https://files.pythonhosted.org/packages/13/46/7bee6d32b69191cd649bbbd2361af79c472d72cb29bb2024f0b6e350ba06/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", size = 2109666, upload_time = "2024-09-16T16:04:33.923Z" }, + { url = "https://files.pythonhosted.org/packages/39/ef/7b34f1b122a81b68ed0a7d0e564da9ccdc9a2924c8d6c6b5b11fa3a56970/pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", size = 1732940, upload_time = "2024-09-16T16:04:35.467Z" }, + { url = "https://files.pythonhosted.org/packages/2f/76/37b7e76c645843ff46c1d73e046207311ef298d3f7b2f7d8f6ac60113071/pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", size = 1916804, upload_time = "2024-09-16T16:04:37.06Z" }, + { url = "https://files.pythonhosted.org/packages/74/7b/8e315f80666194b354966ec84b7d567da77ad927ed6323db4006cf915f3f/pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", size = 1856459, upload_time = "2024-09-16T16:04:38.438Z" }, + { url = "https://files.pythonhosted.org/packages/14/de/866bdce10ed808323d437612aca1ec9971b981e1c52e5e42ad9b8e17a6f6/pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", size = 1770007, upload_time = "2024-09-16T16:04:40.229Z" }, + { url = "https://files.pythonhosted.org/packages/dc/69/8edd5c3cd48bb833a3f7ef9b81d7666ccddd3c9a635225214e044b6e8281/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", size = 1790245, upload_time = "2024-09-16T16:04:41.794Z" }, + { url = "https://files.pythonhosted.org/packages/80/33/9c24334e3af796ce80d2274940aae38dd4e5676298b4398eff103a79e02d/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", size = 1801260, upload_time = "2024-09-16T16:04:43.991Z" }, + { url = "https://files.pythonhosted.org/packages/a5/6f/e9567fd90104b79b101ca9d120219644d3314962caa7948dd8b965e9f83e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", size = 1996872, upload_time = "2024-09-16T16:04:45.593Z" }, + { url = "https://files.pythonhosted.org/packages/2d/ad/b5f0fe9e6cfee915dd144edbd10b6e9c9c9c9d7a56b69256d124b8ac682e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", size = 2661617, upload_time = "2024-09-16T16:04:47.3Z" }, + { url = "https://files.pythonhosted.org/packages/06/c8/7d4b708f8d05a5cbfda3243aad468052c6e99de7d0937c9146c24d9f12e9/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", size = 2071831, upload_time = "2024-09-16T16:04:48.893Z" }, + { url = "https://files.pythonhosted.org/packages/89/4d/3079d00c47f22c9a9a8220db088b309ad6e600a73d7a69473e3a8e5e3ea3/pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", size = 1917453, upload_time = "2024-09-16T16:04:51.099Z" }, + { url = "https://files.pythonhosted.org/packages/e9/88/9df5b7ce880a4703fcc2d76c8c2d8eb9f861f79d0c56f4b8f5f2607ccec8/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", size = 1968793, upload_time = "2024-09-16T16:04:52.604Z" }, + { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872, upload_time = "2024-09-16T16:04:54.41Z" }, + { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535, upload_time = "2024-09-16T16:04:55.828Z" }, + { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992, upload_time = "2024-09-16T16:04:57.395Z" }, + { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143, upload_time = "2024-09-16T16:04:59.062Z" }, + { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063, upload_time = "2024-09-16T16:05:00.522Z" }, + { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013, upload_time = "2024-09-16T16:05:02.619Z" }, + { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077, upload_time = "2024-09-16T16:05:04.154Z" }, + { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782, upload_time = "2024-09-16T16:05:06.931Z" }, + { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375, upload_time = "2024-09-16T16:05:08.773Z" }, + { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635, upload_time = "2024-09-16T16:05:10.456Z" }, + { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994, upload_time = "2024-09-16T16:05:12.051Z" }, + { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877, upload_time = "2024-09-16T16:05:14.021Z" }, + { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814, upload_time = "2024-09-16T16:05:15.684Z" }, + { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360, upload_time = "2024-09-16T16:05:17.258Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411, upload_time = "2024-09-16T16:05:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135, upload_time = "2024-09-16T16:06:10.45Z" }, + { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583, upload_time = "2024-09-16T16:06:12.298Z" }, + { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637, upload_time = "2024-09-16T16:06:14.092Z" }, + { url = "https://files.pythonhosted.org/packages/29/18/812222b6d18c2d13eebbb0f7cdc170a408d9ced65794fdb86147c77e1982/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", size = 1941963, upload_time = "2024-09-16T16:06:16.757Z" }, + { url = "https://files.pythonhosted.org/packages/0f/36/c1f3642ac3f05e6bb4aec3ffc399fa3f84895d259cf5f0ce3054b7735c29/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", size = 1915332, upload_time = "2024-09-16T16:06:18.677Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ca/9c0854829311fb446020ebb540ee22509731abad886d2859c855dd29b904/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", size = 1957926, upload_time = "2024-09-16T16:06:20.591Z" }, + { url = "https://files.pythonhosted.org/packages/c0/1c/7836b67c42d0cd4441fcd9fafbf6a027ad4b79b6559f80cf11f89fd83648/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", size = 2100342, upload_time = "2024-09-16T16:06:22.888Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344, upload_time = "2024-09-16T16:06:24.849Z" }, +] + +[[package]] +name = "pydantic-settings" +version = "2.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/1d/42628a2c33e93f8e9acbde0d5d735fa0850f3e6a2f8cb1eb6c40b9a732ac/pydantic_settings-2.9.1.tar.gz", hash = "sha256:c509bf79d27563add44e8446233359004ed85066cd096d8b510f715e6ef5d268", size = 163234, upload_time = "2025-04-18T16:44:48.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/5f/d6d641b490fd3ec2c4c13b4244d68deea3a1b970a97be64f34fb5504ff72/pydantic_settings-2.9.1-py3-none-any.whl", hash = "sha256:59b4f431b1defb26fe620c71a7d3968a710d719f5f4cdbbdb7926edeb770f6ef", size = 44356, upload_time = "2025-04-18T16:44:46.617Z" }, +] + +[[package]] +name = "pyflakes" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/45/dc/fd034dc20b4b264b3d015808458391acbf9df40b1e54750ef175d39180b1/pyflakes-3.4.0.tar.gz", hash = "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58", size = 64669, upload_time = "2025-06-20T18:45:27.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f", size = 63551, upload_time = "2025-06-20T18:45:26.937Z" }, +] + +[[package]] +name = "pygments" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905, upload_time = "2024-05-04T13:42:02.013Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513, upload_time = "2024-05-04T13:41:57.345Z" }, +] + +[[package]] +name = "pyjwt" +version = "2.10.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785, upload_time = "2024-11-28T03:43:29.933Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997, upload_time = "2024-11-28T03:43:27.893Z" }, +] + +[[package]] +name = "pymupdf" +version = "1.26.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/d4/70a265e4bcd43e97480ae62da69396ef4507c8f9cfd179005ee731c92a04/pymupdf-1.26.3.tar.gz", hash = "sha256:b7d2c3ffa9870e1e4416d18862f5ccd356af5fe337b4511093bbbce2ca73b7e5", size = 75990308, upload_time = "2025-07-02T21:34:22.243Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/d3/c7af70545cd3097a869fd635bb6222108d3a0fb28c0b8254754a126c4cbb/pymupdf-1.26.3-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ded891963944e5f13b03b88f6d9e982e816a4ec8689fe360876eef000c161f2b", size = 23057205, upload_time = "2025-07-02T21:26:16.326Z" }, + { url = "https://files.pythonhosted.org/packages/04/3d/ec5b69bfeaa5deefa7141fc0b20d77bb20404507cf17196b4eb59f1f2977/pymupdf-1.26.3-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:436a33c738bb10eadf00395d18a6992b801ffb26521ee1f361ae786dd283327a", size = 22406630, upload_time = "2025-07-02T21:27:10.112Z" }, + { url = "https://files.pythonhosted.org/packages/fc/20/661d3894bb05ad75ed6ca103ee2c3fa44d88a458b5c8d4a946b9c0f2569b/pymupdf-1.26.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a2d7a3cd442f12f05103cb3bb1415111517f0a97162547a3720f3bbbc5e0b51c", size = 23450287, upload_time = "2025-07-03T07:22:19.317Z" }, + { url = "https://files.pythonhosted.org/packages/9c/7f/21828f018e65b16a033731d21f7b46d93fa81c6e8257f769ca4a1c2a1cb0/pymupdf-1.26.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:454f38c8cf07eb333eb4646dca10517b6e90f57ce2daa2265a78064109d85555", size = 24057319, upload_time = "2025-07-02T21:28:26.697Z" }, + { url = "https://files.pythonhosted.org/packages/71/5d/e8f88cd5a45b8f5fa6590ce8cef3ce0fad30eac6aac8aea12406f95bee7d/pymupdf-1.26.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:759b75d2f710ff4edf8d097d2e98f60e9ecef47632cead6f949b3412facdb9f0", size = 24261350, upload_time = "2025-07-02T21:29:21.733Z" }, + { url = "https://files.pythonhosted.org/packages/82/22/ecc560e4f281b5dffafbf3a81f023d268b1746d028044f495115b74a2e70/pymupdf-1.26.3-cp39-abi3-win32.whl", hash = "sha256:a839ed44742faa1cd4956bb18068fe5aae435d67ce915e901318646c4e7bbea6", size = 17116371, upload_time = "2025-07-02T21:30:23.253Z" }, + { url = "https://files.pythonhosted.org/packages/4a/26/8c72973b8833a72785cedc3981eb59b8ac7075942718bbb7b69b352cdde4/pymupdf-1.26.3-cp39-abi3-win_amd64.whl", hash = "sha256:b4cd5124d05737944636cf45fc37ce5824f10e707b0342efe109c7b6bd37a9cc", size = 18735124, upload_time = "2025-07-02T21:31:10.992Z" }, +] + +[[package]] +name = "pypdf2" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/bb/18dc3062d37db6c491392007dfd1a7f524bb95886eb956569ac38a23a784/PyPDF2-3.0.1.tar.gz", hash = "sha256:a74408f69ba6271f71b9352ef4ed03dc53a31aa404d29b5d31f53bfecfee1440", size = 227419, upload_time = "2022-12-31T10:36:13.13Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/5e/c86a5643653825d3c913719e788e41386bee415c2b87b4f955432f2de6b2/pypdf2-3.0.1-py3-none-any.whl", hash = "sha256:d16e4205cfee272fbdc0568b68d82be796540b1537508cef59388f839c191928", size = 232572, upload_time = "2022-12-31T10:36:10.327Z" }, +] + +[[package]] +name = "pyphen" +version = "0.17.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/56/e4d7e1bd70d997713649c5ce530b2d15a5fc2245a74ca820fc2d51d89d4d/pyphen-0.17.2.tar.gz", hash = "sha256:f60647a9c9b30ec6c59910097af82bc5dd2d36576b918e44148d8b07ef3b4aa3", size = 2079470, upload_time = "2025-01-20T13:18:36.296Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/1f/c2142d2edf833a90728e5cdeb10bdbdc094dde8dbac078cee0cf33f5e11b/pyphen-0.17.2-py3-none-any.whl", hash = "sha256:3a07fb017cb2341e1d9ff31b8634efb1ae4dc4b130468c7c39dd3d32e7c3affd", size = 2079358, upload_time = "2025-01-20T13:18:29.629Z" }, +] + +[[package]] +name = "pypika" +version = "0.48.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/2c/94ed7b91db81d61d7096ac8f2d325ec562fc75e35f3baea8749c85b28784/PyPika-0.48.9.tar.gz", hash = "sha256:838836a61747e7c8380cd1b7ff638694b7a7335345d0f559b04b2cd832ad5378", size = 67259, upload_time = "2022-03-15T11:22:57.066Z" } + +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228, upload_time = "2024-09-29T09:24:13.293Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload_time = "2024-09-29T09:24:11.978Z" }, +] + +[[package]] +name = "pyreadline3" +version = "3.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/49/4cea918a08f02817aabae639e3d0ac046fef9f9180518a3ad394e22da148/pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7", size = 99839, upload_time = "2024-09-19T02:40:10.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178, upload_time = "2024-09-19T02:40:08.598Z" }, +] + +[[package]] +name = "pytest" +version = "7.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116, upload_time = "2023-12-31T12:00:18.035Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287, upload_time = "2023-12-31T12:00:13.963Z" }, +] + +[[package]] +name = "pytest-cov" +version = "6.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload_time = "2025-06-12T10:47:47.684Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload_time = "2025-06-12T10:47:45.932Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload_time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload_time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-docx" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lxml" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/f7/eddfe33871520adab45aaa1a71f0402a2252050c14c7e3009446c8f4701c/python_docx-1.2.0.tar.gz", hash = "sha256:7bc9d7b7d8a69c9c02ca09216118c86552704edc23bac179283f2e38f86220ce", size = 5723256, upload_time = "2025-06-16T20:46:27.921Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/00/1e03a4989fa5795da308cd774f05b704ace555a70f9bf9d3be057b680bcf/python_docx-1.2.0-py3-none-any.whl", hash = "sha256:3fd478f3250fbbbfd3b94fe1e985955737c145627498896a8a6bf81f4baf66c7", size = 252987, upload_time = "2025-06-16T20:46:22.506Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115, upload_time = "2024-01-23T06:33:00.505Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863, upload_time = "2024-01-23T06:32:58.246Z" }, +] + +[[package]] +name = "python-jose" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ecdsa" }, + { name = "pyasn1" }, + { name = "rsa" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/77/3a1c9039db7124eb039772b935f2244fbb73fc8ee65b9acf2375da1c07bf/python_jose-3.5.0.tar.gz", hash = "sha256:fb4eaa44dbeb1c26dcc69e4bd7ec54a1cb8dd64d3b4d81ef08d90ff453f2b01b", size = 92726, upload_time = "2025-05-28T17:31:54.288Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/c3/0bd11992072e6a1c513b16500a5d07f91a24017c5909b02c72c62d7ad024/python_jose-3.5.0-py2.py3-none-any.whl", hash = "sha256:abd1202f23d34dfad2c3d28cb8617b90acf34132c7afd60abd0b0b7d3cb55771", size = 34624, upload_time = "2025-05-28T17:31:52.802Z" }, +] + +[package.optional-dependencies] +cryptography = [ + { name = "cryptography" }, +] + +[[package]] +name = "python-magic" +version = "0.4.27" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/db/0b3e28ac047452d079d375ec6798bf76a036a08182dbb39ed38116a49130/python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b", size = 14677, upload_time = "2022-06-07T20:16:59.508Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/73/9f872cb81fc5c3bb48f7227872c28975f998f3e7c2b1c16e95e6432bbb90/python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3", size = 13840, upload_time = "2022-06-07T20:16:57.763Z" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload_time = "2024-12-16T19:45:46.972Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload_time = "2024-12-16T19:45:44.423Z" }, +] + +[[package]] +name = "python-pptx" +version = "1.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lxml" }, + { name = "pillow" }, + { name = "typing-extensions" }, + { name = "xlsxwriter" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/a9/0c0db8d37b2b8a645666f7fd8accea4c6224e013c42b1d5c17c93590cd06/python_pptx-1.0.2.tar.gz", hash = "sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095", size = 10109297, upload_time = "2024-08-07T17:33:37.772Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/4f/00be2196329ebbff56ce564aa94efb0fbc828d00de250b1980de1a34ab49/python_pptx-1.0.2-py3-none-any.whl", hash = "sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba", size = 472788, upload_time = "2024-08-07T17:33:28.192Z" }, +] + +[[package]] +name = "pytz" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload_time = "2025-03-25T02:25:00.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload_time = "2025-03-25T02:24:58.468Z" }, +] + +[[package]] +name = "pywin32" +version = "310" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/da/a5f38fffbba2fb99aa4aa905480ac4b8e83ca486659ac8c95bce47fb5276/pywin32-310-cp310-cp310-win32.whl", hash = "sha256:6dd97011efc8bf51d6793a82292419eba2c71cf8e7250cfac03bba284454abc1", size = 8848240, upload_time = "2025-03-17T00:55:46.783Z" }, + { url = "https://files.pythonhosted.org/packages/aa/fe/d873a773324fa565619ba555a82c9dabd677301720f3660a731a5d07e49a/pywin32-310-cp310-cp310-win_amd64.whl", hash = "sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d", size = 9601854, upload_time = "2025-03-17T00:55:48.783Z" }, + { url = "https://files.pythonhosted.org/packages/3c/84/1a8e3d7a15490d28a5d816efa229ecb4999cdc51a7c30dd8914f669093b8/pywin32-310-cp310-cp310-win_arm64.whl", hash = "sha256:33babed0cf0c92a6f94cc6cc13546ab24ee13e3e800e61ed87609ab91e4c8213", size = 8522963, upload_time = "2025-03-17T00:55:50.969Z" }, + { url = "https://files.pythonhosted.org/packages/f7/b1/68aa2986129fb1011dabbe95f0136f44509afaf072b12b8f815905a39f33/pywin32-310-cp311-cp311-win32.whl", hash = "sha256:1e765f9564e83011a63321bb9d27ec456a0ed90d3732c4b2e312b855365ed8bd", size = 8784284, upload_time = "2025-03-17T00:55:53.124Z" }, + { url = "https://files.pythonhosted.org/packages/b3/bd/d1592635992dd8db5bb8ace0551bc3a769de1ac8850200cfa517e72739fb/pywin32-310-cp311-cp311-win_amd64.whl", hash = "sha256:126298077a9d7c95c53823934f000599f66ec9296b09167810eb24875f32689c", size = 9520748, upload_time = "2025-03-17T00:55:55.203Z" }, + { url = "https://files.pythonhosted.org/packages/90/b1/ac8b1ffce6603849eb45a91cf126c0fa5431f186c2e768bf56889c46f51c/pywin32-310-cp311-cp311-win_arm64.whl", hash = "sha256:19ec5fc9b1d51c4350be7bb00760ffce46e6c95eaf2f0b2f1150657b1a43c582", size = 8455941, upload_time = "2025-03-17T00:55:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ec/4fdbe47932f671d6e348474ea35ed94227fb5df56a7c30cbbb42cd396ed0/pywin32-310-cp312-cp312-win32.whl", hash = "sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d", size = 8796239, upload_time = "2025-03-17T00:55:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/e3/e5/b0627f8bb84e06991bea89ad8153a9e50ace40b2e1195d68e9dff6b03d0f/pywin32-310-cp312-cp312-win_amd64.whl", hash = "sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060", size = 9503839, upload_time = "2025-03-17T00:56:00.8Z" }, + { url = "https://files.pythonhosted.org/packages/1f/32/9ccf53748df72301a89713936645a664ec001abd35ecc8578beda593d37d/pywin32-310-cp312-cp312-win_arm64.whl", hash = "sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966", size = 8459470, upload_time = "2025-03-17T00:56:02.601Z" }, + { url = "https://files.pythonhosted.org/packages/1c/09/9c1b978ffc4ae53999e89c19c77ba882d9fce476729f23ef55211ea1c034/pywin32-310-cp313-cp313-win32.whl", hash = "sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab", size = 8794384, upload_time = "2025-03-17T00:56:04.383Z" }, + { url = "https://files.pythonhosted.org/packages/45/3c/b4640f740ffebadd5d34df35fecba0e1cfef8fde9f3e594df91c28ad9b50/pywin32-310-cp313-cp313-win_amd64.whl", hash = "sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e", size = 9503039, upload_time = "2025-03-17T00:56:06.207Z" }, + { url = "https://files.pythonhosted.org/packages/b4/f4/f785020090fb050e7fb6d34b780f2231f302609dc964672f72bfaeb59a28/pywin32-310-cp313-cp313-win_arm64.whl", hash = "sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33", size = 8458152, upload_time = "2025-03-17T00:56:07.819Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload_time = "2024-08-06T20:33:50.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload_time = "2024-08-06T20:31:40.178Z" }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758, upload_time = "2024-08-06T20:31:42.173Z" }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463, upload_time = "2024-08-06T20:31:44.263Z" }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280, upload_time = "2024-08-06T20:31:50.199Z" }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239, upload_time = "2024-08-06T20:31:52.292Z" }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802, upload_time = "2024-08-06T20:31:53.836Z" }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527, upload_time = "2024-08-06T20:31:55.565Z" }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052, upload_time = "2024-08-06T20:31:56.914Z" }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774, upload_time = "2024-08-06T20:31:58.304Z" }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload_time = "2024-08-06T20:32:03.408Z" }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload_time = "2024-08-06T20:32:04.926Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload_time = "2024-08-06T20:32:06.459Z" }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload_time = "2024-08-06T20:32:08.338Z" }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload_time = "2024-08-06T20:32:14.124Z" }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload_time = "2024-08-06T20:32:16.17Z" }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload_time = "2024-08-06T20:32:18.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload_time = "2024-08-06T20:32:19.889Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload_time = "2024-08-06T20:32:21.273Z" }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload_time = "2024-08-06T20:32:25.131Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload_time = "2024-08-06T20:32:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload_time = "2024-08-06T20:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload_time = "2024-08-06T20:32:30.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload_time = "2024-08-06T20:32:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload_time = "2024-08-06T20:32:37.083Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload_time = "2024-08-06T20:32:38.898Z" }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload_time = "2024-08-06T20:32:40.241Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload_time = "2024-08-06T20:32:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload_time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload_time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload_time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload_time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload_time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload_time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload_time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload_time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload_time = "2024-08-06T20:33:04.33Z" }, +] + +[[package]] +name = "qdrant-client" +version = "1.14.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "grpcio" }, + { name = "httpx", extra = ["http2"] }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "portalocker" }, + { name = "protobuf" }, + { name = "pydantic" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/56/3f355f931c239c260b4fe3bd6433ec6c9e6185cd5ae0970fe89d0ca6daee/qdrant_client-1.14.3.tar.gz", hash = "sha256:bb899e3e065b79c04f5e47053d59176150c0a5dabc09d7f476c8ce8e52f4d281", size = 286766, upload_time = "2025-06-16T11:13:47.838Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/5e/8174c845707e60b60b65c58f01e40bbc1d8181b5ff6463f25df470509917/qdrant_client-1.14.3-py3-none-any.whl", hash = "sha256:66faaeae00f9b5326946851fe4ca4ddb1ad226490712e2f05142266f68dfc04d", size = 328969, upload_time = "2025-06-16T11:13:46.636Z" }, +] + +[[package]] +name = "redis" +version = "6.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-timeout", marker = "python_full_version < '3.11.3'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/9a/0551e01ba52b944f97480721656578c8a7c46b51b99d66814f85fe3a4f3e/redis-6.2.0.tar.gz", hash = "sha256:e821f129b75dde6cb99dd35e5c76e8c49512a5a0d8dfdc560b2fbd44b85ca977", size = 4639129, upload_time = "2025-05-28T05:01:18.91Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/67/e60968d3b0e077495a8fee89cf3f2373db98e528288a48f1ee44967f6e8c/redis-6.2.0-py3-none-any.whl", hash = "sha256:c8ddf316ee0aab65f04a11229e94a64b2618451dab7a67cb2f77eb799d872d5e", size = 278659, upload_time = "2025-05-28T05:01:16.955Z" }, +] + +[[package]] +name = "referencing" +version = "0.36.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload_time = "2025-01-25T08:48:16.138Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload_time = "2025-01-25T08:48:14.241Z" }, +] + +[[package]] +name = "regex" +version = "2024.11.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494, upload_time = "2024-11-06T20:12:31.635Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/3c/4651f6b130c6842a8f3df82461a8950f923925db8b6961063e82744bddcc/regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91", size = 482674, upload_time = "2024-11-06T20:08:57.575Z" }, + { url = "https://files.pythonhosted.org/packages/15/51/9f35d12da8434b489c7b7bffc205c474a0a9432a889457026e9bc06a297a/regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0", size = 287684, upload_time = "2024-11-06T20:08:59.787Z" }, + { url = "https://files.pythonhosted.org/packages/bd/18/b731f5510d1b8fb63c6b6d3484bfa9a59b84cc578ac8b5172970e05ae07c/regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e", size = 284589, upload_time = "2024-11-06T20:09:01.896Z" }, + { url = "https://files.pythonhosted.org/packages/78/a2/6dd36e16341ab95e4c6073426561b9bfdeb1a9c9b63ab1b579c2e96cb105/regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde", size = 782511, upload_time = "2024-11-06T20:09:04.062Z" }, + { url = "https://files.pythonhosted.org/packages/1b/2b/323e72d5d2fd8de0d9baa443e1ed70363ed7e7b2fb526f5950c5cb99c364/regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e", size = 821149, upload_time = "2024-11-06T20:09:06.237Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/63373b9ea468fbef8a907fd273e5c329b8c9535fee36fc8dba5fecac475d/regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2", size = 809707, upload_time = "2024-11-06T20:09:07.715Z" }, + { url = "https://files.pythonhosted.org/packages/f2/98/26d3830875b53071f1f0ae6d547f1d98e964dd29ad35cbf94439120bb67a/regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf", size = 781702, upload_time = "2024-11-06T20:09:10.101Z" }, + { url = "https://files.pythonhosted.org/packages/87/55/eb2a068334274db86208ab9d5599ffa63631b9f0f67ed70ea7c82a69bbc8/regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c", size = 771976, upload_time = "2024-11-06T20:09:11.566Z" }, + { url = "https://files.pythonhosted.org/packages/74/c0/be707bcfe98254d8f9d2cff55d216e946f4ea48ad2fd8cf1428f8c5332ba/regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86", size = 697397, upload_time = "2024-11-06T20:09:13.119Z" }, + { url = "https://files.pythonhosted.org/packages/49/dc/bb45572ceb49e0f6509f7596e4ba7031f6819ecb26bc7610979af5a77f45/regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67", size = 768726, upload_time = "2024-11-06T20:09:14.85Z" }, + { url = "https://files.pythonhosted.org/packages/5a/db/f43fd75dc4c0c2d96d0881967897926942e935d700863666f3c844a72ce6/regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d", size = 775098, upload_time = "2024-11-06T20:09:16.504Z" }, + { url = "https://files.pythonhosted.org/packages/99/d7/f94154db29ab5a89d69ff893159b19ada89e76b915c1293e98603d39838c/regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2", size = 839325, upload_time = "2024-11-06T20:09:18.698Z" }, + { url = "https://files.pythonhosted.org/packages/f7/17/3cbfab1f23356fbbf07708220ab438a7efa1e0f34195bf857433f79f1788/regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008", size = 843277, upload_time = "2024-11-06T20:09:21.725Z" }, + { url = "https://files.pythonhosted.org/packages/7e/f2/48b393b51900456155de3ad001900f94298965e1cad1c772b87f9cfea011/regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62", size = 773197, upload_time = "2024-11-06T20:09:24.092Z" }, + { url = "https://files.pythonhosted.org/packages/45/3f/ef9589aba93e084cd3f8471fded352826dcae8489b650d0b9b27bc5bba8a/regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e", size = 261714, upload_time = "2024-11-06T20:09:26.36Z" }, + { url = "https://files.pythonhosted.org/packages/42/7e/5f1b92c8468290c465fd50c5318da64319133231415a8aa6ea5ab995a815/regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519", size = 274042, upload_time = "2024-11-06T20:09:28.762Z" }, + { url = "https://files.pythonhosted.org/packages/58/58/7e4d9493a66c88a7da6d205768119f51af0f684fe7be7bac8328e217a52c/regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638", size = 482669, upload_time = "2024-11-06T20:09:31.064Z" }, + { url = "https://files.pythonhosted.org/packages/34/4c/8f8e631fcdc2ff978609eaeef1d6994bf2f028b59d9ac67640ed051f1218/regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7", size = 287684, upload_time = "2024-11-06T20:09:32.915Z" }, + { url = "https://files.pythonhosted.org/packages/c5/1b/f0e4d13e6adf866ce9b069e191f303a30ab1277e037037a365c3aad5cc9c/regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20", size = 284589, upload_time = "2024-11-06T20:09:35.504Z" }, + { url = "https://files.pythonhosted.org/packages/25/4d/ab21047f446693887f25510887e6820b93f791992994f6498b0318904d4a/regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114", size = 792121, upload_time = "2024-11-06T20:09:37.701Z" }, + { url = "https://files.pythonhosted.org/packages/45/ee/c867e15cd894985cb32b731d89576c41a4642a57850c162490ea34b78c3b/regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3", size = 831275, upload_time = "2024-11-06T20:09:40.371Z" }, + { url = "https://files.pythonhosted.org/packages/b3/12/b0f480726cf1c60f6536fa5e1c95275a77624f3ac8fdccf79e6727499e28/regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f", size = 818257, upload_time = "2024-11-06T20:09:43.059Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ce/0d0e61429f603bac433910d99ef1a02ce45a8967ffbe3cbee48599e62d88/regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0", size = 792727, upload_time = "2024-11-06T20:09:48.19Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c1/243c83c53d4a419c1556f43777ccb552bccdf79d08fda3980e4e77dd9137/regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55", size = 780667, upload_time = "2024-11-06T20:09:49.828Z" }, + { url = "https://files.pythonhosted.org/packages/c5/f4/75eb0dd4ce4b37f04928987f1d22547ddaf6c4bae697623c1b05da67a8aa/regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89", size = 776963, upload_time = "2024-11-06T20:09:51.819Z" }, + { url = "https://files.pythonhosted.org/packages/16/5d/95c568574e630e141a69ff8a254c2f188b4398e813c40d49228c9bbd9875/regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d", size = 784700, upload_time = "2024-11-06T20:09:53.982Z" }, + { url = "https://files.pythonhosted.org/packages/8e/b5/f8495c7917f15cc6fee1e7f395e324ec3e00ab3c665a7dc9d27562fd5290/regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34", size = 848592, upload_time = "2024-11-06T20:09:56.222Z" }, + { url = "https://files.pythonhosted.org/packages/1c/80/6dd7118e8cb212c3c60b191b932dc57db93fb2e36fb9e0e92f72a5909af9/regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d", size = 852929, upload_time = "2024-11-06T20:09:58.642Z" }, + { url = "https://files.pythonhosted.org/packages/11/9b/5a05d2040297d2d254baf95eeeb6df83554e5e1df03bc1a6687fc4ba1f66/regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45", size = 781213, upload_time = "2024-11-06T20:10:00.867Z" }, + { url = "https://files.pythonhosted.org/packages/26/b7/b14e2440156ab39e0177506c08c18accaf2b8932e39fb092074de733d868/regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", size = 261734, upload_time = "2024-11-06T20:10:03.361Z" }, + { url = "https://files.pythonhosted.org/packages/80/32/763a6cc01d21fb3819227a1cc3f60fd251c13c37c27a73b8ff4315433a8e/regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", size = 274052, upload_time = "2024-11-06T20:10:05.179Z" }, + { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781, upload_time = "2024-11-06T20:10:07.07Z" }, + { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455, upload_time = "2024-11-06T20:10:09.117Z" }, + { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759, upload_time = "2024-11-06T20:10:11.155Z" }, + { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976, upload_time = "2024-11-06T20:10:13.24Z" }, + { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077, upload_time = "2024-11-06T20:10:15.37Z" }, + { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160, upload_time = "2024-11-06T20:10:19.027Z" }, + { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896, upload_time = "2024-11-06T20:10:21.85Z" }, + { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997, upload_time = "2024-11-06T20:10:24.329Z" }, + { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725, upload_time = "2024-11-06T20:10:28.067Z" }, + { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481, upload_time = "2024-11-06T20:10:31.612Z" }, + { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896, upload_time = "2024-11-06T20:10:34.054Z" }, + { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138, upload_time = "2024-11-06T20:10:36.142Z" }, + { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692, upload_time = "2024-11-06T20:10:38.394Z" }, + { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135, upload_time = "2024-11-06T20:10:40.367Z" }, + { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567, upload_time = "2024-11-06T20:10:43.467Z" }, + { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525, upload_time = "2024-11-06T20:10:45.19Z" }, + { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324, upload_time = "2024-11-06T20:10:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617, upload_time = "2024-11-06T20:10:49.312Z" }, + { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023, upload_time = "2024-11-06T20:10:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072, upload_time = "2024-11-06T20:10:52.926Z" }, + { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130, upload_time = "2024-11-06T20:10:54.828Z" }, + { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857, upload_time = "2024-11-06T20:10:56.634Z" }, + { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006, upload_time = "2024-11-06T20:10:59.369Z" }, + { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650, upload_time = "2024-11-06T20:11:02.042Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545, upload_time = "2024-11-06T20:11:03.933Z" }, + { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045, upload_time = "2024-11-06T20:11:06.497Z" }, + { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182, upload_time = "2024-11-06T20:11:09.06Z" }, + { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733, upload_time = "2024-11-06T20:11:11.256Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122, upload_time = "2024-11-06T20:11:13.161Z" }, + { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545, upload_time = "2024-11-06T20:11:15Z" }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload_time = "2024-05-29T15:37:49.536Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload_time = "2024-05-29T15:37:47.027Z" }, +] + +[[package]] +name = "requests-oauthlib" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "oauthlib" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/f2/05f29bc3913aea15eb670be136045bf5c5bbf4b99ecb839da9b422bb2c85/requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9", size = 55650, upload_time = "2024-03-22T20:32:29.939Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", size = 24179, upload_time = "2024-03-22T20:32:28.055Z" }, ] [[package]] -name = "pydantic-settings" -version = "2.9.1" +name = "requests-toolbelt" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pydantic" }, - { name = "python-dotenv" }, - { name = "typing-inspection" }, + { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/67/1d/42628a2c33e93f8e9acbde0d5d735fa0850f3e6a2f8cb1eb6c40b9a732ac/pydantic_settings-2.9.1.tar.gz", hash = "sha256:c509bf79d27563add44e8446233359004ed85066cd096d8b510f715e6ef5d268", size = 163234 } +sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888, upload_time = "2023-05-01T04:11:33.229Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/5f/d6d641b490fd3ec2c4c13b4244d68deea3a1b970a97be64f34fb5504ff72/pydantic_settings-2.9.1-py3-none-any.whl", hash = "sha256:59b4f431b1defb26fe620c71a7d3968a710d719f5f4cdbbdb7926edeb770f6ef", size = 44356 }, + { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload_time = "2023-05-01T04:11:28.427Z" }, ] [[package]] -name = "pygments" -version = "2.18.0" +name = "rich" +version = "13.8.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/92/76/40f084cb7db51c9d1fa29a7120717892aeda9a7711f6225692c957a93535/rich-13.8.1.tar.gz", hash = "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a", size = 222080, upload_time = "2024-09-10T12:52:44.779Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, + { url = "https://files.pythonhosted.org/packages/b0/11/dadb85e2bd6b1f1ae56669c3e1f0410797f9605d752d68fb47b77f525b31/rich-13.8.1-py3-none-any.whl", hash = "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06", size = 241608, upload_time = "2024-09-10T12:52:42.714Z" }, ] [[package]] -name = "pyjwt" -version = "2.10.1" +name = "rpds-py" +version = "0.26.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785 } +sdist = { url = "https://files.pythonhosted.org/packages/a5/aa/4456d84bbb54adc6a916fb10c9b374f78ac840337644e4a5eda229c81275/rpds_py-0.26.0.tar.gz", hash = "sha256:20dae58a859b0906f0685642e591056f1e787f3a8b39c8e8749a45dc7d26bdb0", size = 27385, upload_time = "2025-07-01T15:57:13.958Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997 }, + { url = "https://files.pythonhosted.org/packages/b9/31/1459645f036c3dfeacef89e8e5825e430c77dde8489f3b99eaafcd4a60f5/rpds_py-0.26.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:4c70c70f9169692b36307a95f3d8c0a9fcd79f7b4a383aad5eaa0e9718b79b37", size = 372466, upload_time = "2025-07-01T15:53:40.55Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ff/3d0727f35836cc8773d3eeb9a46c40cc405854e36a8d2e951f3a8391c976/rpds_py-0.26.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:777c62479d12395bfb932944e61e915741e364c843afc3196b694db3d669fcd0", size = 357825, upload_time = "2025-07-01T15:53:42.247Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ce/badc5e06120a54099ae287fa96d82cbb650a5f85cf247ffe19c7b157fd1f/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec671691e72dff75817386aa02d81e708b5a7ec0dec6669ec05213ff6b77e1bd", size = 381530, upload_time = "2025-07-01T15:53:43.585Z" }, + { url = "https://files.pythonhosted.org/packages/1e/a5/fa5d96a66c95d06c62d7a30707b6a4cfec696ab8ae280ee7be14e961e118/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a1cb5d6ce81379401bbb7f6dbe3d56de537fb8235979843f0d53bc2e9815a79", size = 396933, upload_time = "2025-07-01T15:53:45.78Z" }, + { url = "https://files.pythonhosted.org/packages/00/a7/7049d66750f18605c591a9db47d4a059e112a0c9ff8de8daf8fa0f446bba/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f789e32fa1fb6a7bf890e0124e7b42d1e60d28ebff57fe806719abb75f0e9a3", size = 513973, upload_time = "2025-07-01T15:53:47.085Z" }, + { url = "https://files.pythonhosted.org/packages/0e/f1/528d02c7d6b29d29fac8fd784b354d3571cc2153f33f842599ef0cf20dd2/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c55b0a669976cf258afd718de3d9ad1b7d1fe0a91cd1ab36f38b03d4d4aeaaf", size = 402293, upload_time = "2025-07-01T15:53:48.117Z" }, + { url = "https://files.pythonhosted.org/packages/15/93/fde36cd6e4685df2cd08508f6c45a841e82f5bb98c8d5ecf05649522acb5/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c70d9ec912802ecfd6cd390dadb34a9578b04f9bcb8e863d0a7598ba5e9e7ccc", size = 383787, upload_time = "2025-07-01T15:53:50.874Z" }, + { url = "https://files.pythonhosted.org/packages/69/f2/5007553aaba1dcae5d663143683c3dfd03d9395289f495f0aebc93e90f24/rpds_py-0.26.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3021933c2cb7def39d927b9862292e0f4c75a13d7de70eb0ab06efed4c508c19", size = 416312, upload_time = "2025-07-01T15:53:52.046Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a7/ce52c75c1e624a79e48a69e611f1c08844564e44c85db2b6f711d76d10ce/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a7898b6ca3b7d6659e55cdac825a2e58c638cbf335cde41f4619e290dd0ad11", size = 558403, upload_time = "2025-07-01T15:53:53.192Z" }, + { url = "https://files.pythonhosted.org/packages/79/d5/e119db99341cc75b538bf4cb80504129fa22ce216672fb2c28e4a101f4d9/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:12bff2ad9447188377f1b2794772f91fe68bb4bbfa5a39d7941fbebdbf8c500f", size = 588323, upload_time = "2025-07-01T15:53:54.336Z" }, + { url = "https://files.pythonhosted.org/packages/93/94/d28272a0b02f5fe24c78c20e13bbcb95f03dc1451b68e7830ca040c60bd6/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:191aa858f7d4902e975d4cf2f2d9243816c91e9605070aeb09c0a800d187e323", size = 554541, upload_time = "2025-07-01T15:53:55.469Z" }, + { url = "https://files.pythonhosted.org/packages/93/e0/8c41166602f1b791da892d976057eba30685486d2e2c061ce234679c922b/rpds_py-0.26.0-cp310-cp310-win32.whl", hash = "sha256:b37a04d9f52cb76b6b78f35109b513f6519efb481d8ca4c321f6a3b9580b3f45", size = 220442, upload_time = "2025-07-01T15:53:56.524Z" }, + { url = "https://files.pythonhosted.org/packages/87/f0/509736bb752a7ab50fb0270c2a4134d671a7b3038030837e5536c3de0e0b/rpds_py-0.26.0-cp310-cp310-win_amd64.whl", hash = "sha256:38721d4c9edd3eb6670437d8d5e2070063f305bfa2d5aa4278c51cedcd508a84", size = 231314, upload_time = "2025-07-01T15:53:57.842Z" }, + { url = "https://files.pythonhosted.org/packages/09/4c/4ee8f7e512030ff79fda1df3243c88d70fc874634e2dbe5df13ba4210078/rpds_py-0.26.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9e8cb77286025bdb21be2941d64ac6ca016130bfdcd228739e8ab137eb4406ed", size = 372610, upload_time = "2025-07-01T15:53:58.844Z" }, + { url = "https://files.pythonhosted.org/packages/fa/9d/3dc16be00f14fc1f03c71b1d67c8df98263ab2710a2fbd65a6193214a527/rpds_py-0.26.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e09330b21d98adc8ccb2dbb9fc6cb434e8908d4c119aeaa772cb1caab5440a0", size = 358032, upload_time = "2025-07-01T15:53:59.985Z" }, + { url = "https://files.pythonhosted.org/packages/e7/5a/7f1bf8f045da2866324a08ae80af63e64e7bfaf83bd31f865a7b91a58601/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c9c1b92b774b2e68d11193dc39620d62fd8ab33f0a3c77ecdabe19c179cdbc1", size = 381525, upload_time = "2025-07-01T15:54:01.162Z" }, + { url = "https://files.pythonhosted.org/packages/45/8a/04479398c755a066ace10e3d158866beb600867cacae194c50ffa783abd0/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:824e6d3503ab990d7090768e4dfd9e840837bae057f212ff9f4f05ec6d1975e7", size = 397089, upload_time = "2025-07-01T15:54:02.319Z" }, + { url = "https://files.pythonhosted.org/packages/72/88/9203f47268db488a1b6d469d69c12201ede776bb728b9d9f29dbfd7df406/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ad7fd2258228bf288f2331f0a6148ad0186b2e3643055ed0db30990e59817a6", size = 514255, upload_time = "2025-07-01T15:54:03.38Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b4/01ce5d1e853ddf81fbbd4311ab1eff0b3cf162d559288d10fd127e2588b5/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dc23bbb3e06ec1ea72d515fb572c1fea59695aefbffb106501138762e1e915e", size = 402283, upload_time = "2025-07-01T15:54:04.923Z" }, + { url = "https://files.pythonhosted.org/packages/34/a2/004c99936997bfc644d590a9defd9e9c93f8286568f9c16cdaf3e14429a7/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d80bf832ac7b1920ee29a426cdca335f96a2b5caa839811803e999b41ba9030d", size = 383881, upload_time = "2025-07-01T15:54:06.482Z" }, + { url = "https://files.pythonhosted.org/packages/05/1b/ef5fba4a8f81ce04c427bfd96223f92f05e6cd72291ce9d7523db3b03a6c/rpds_py-0.26.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0919f38f5542c0a87e7b4afcafab6fd2c15386632d249e9a087498571250abe3", size = 415822, upload_time = "2025-07-01T15:54:07.605Z" }, + { url = "https://files.pythonhosted.org/packages/16/80/5c54195aec456b292f7bd8aa61741c8232964063fd8a75fdde9c1e982328/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d422b945683e409000c888e384546dbab9009bb92f7c0b456e217988cf316107", size = 558347, upload_time = "2025-07-01T15:54:08.591Z" }, + { url = "https://files.pythonhosted.org/packages/f2/1c/1845c1b1fd6d827187c43afe1841d91678d7241cbdb5420a4c6de180a538/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a7711fa562ba2da1aa757e11024ad6d93bad6ad7ede5afb9af144623e5f76a", size = 587956, upload_time = "2025-07-01T15:54:09.963Z" }, + { url = "https://files.pythonhosted.org/packages/2e/ff/9e979329dd131aa73a438c077252ddabd7df6d1a7ad7b9aacf6261f10faa/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238e8c8610cb7c29460e37184f6799547f7e09e6a9bdbdab4e8edb90986a2318", size = 554363, upload_time = "2025-07-01T15:54:11.073Z" }, + { url = "https://files.pythonhosted.org/packages/00/8b/d78cfe034b71ffbe72873a136e71acc7a831a03e37771cfe59f33f6de8a2/rpds_py-0.26.0-cp311-cp311-win32.whl", hash = "sha256:893b022bfbdf26d7bedb083efeea624e8550ca6eb98bf7fea30211ce95b9201a", size = 220123, upload_time = "2025-07-01T15:54:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/94/c1/3c8c94c7dd3905dbfde768381ce98778500a80db9924731d87ddcdb117e9/rpds_py-0.26.0-cp311-cp311-win_amd64.whl", hash = "sha256:87a5531de9f71aceb8af041d72fc4cab4943648d91875ed56d2e629bef6d4c03", size = 231732, upload_time = "2025-07-01T15:54:13.434Z" }, + { url = "https://files.pythonhosted.org/packages/67/93/e936fbed1b734eabf36ccb5d93c6a2e9246fbb13c1da011624b7286fae3e/rpds_py-0.26.0-cp311-cp311-win_arm64.whl", hash = "sha256:de2713f48c1ad57f89ac25b3cb7daed2156d8e822cf0eca9b96a6f990718cc41", size = 221917, upload_time = "2025-07-01T15:54:14.559Z" }, + { url = "https://files.pythonhosted.org/packages/ea/86/90eb87c6f87085868bd077c7a9938006eb1ce19ed4d06944a90d3560fce2/rpds_py-0.26.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:894514d47e012e794f1350f076c427d2347ebf82f9b958d554d12819849a369d", size = 363933, upload_time = "2025-07-01T15:54:15.734Z" }, + { url = "https://files.pythonhosted.org/packages/63/78/4469f24d34636242c924626082b9586f064ada0b5dbb1e9d096ee7a8e0c6/rpds_py-0.26.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc921b96fa95a097add244da36a1d9e4f3039160d1d30f1b35837bf108c21136", size = 350447, upload_time = "2025-07-01T15:54:16.922Z" }, + { url = "https://files.pythonhosted.org/packages/ad/91/c448ed45efdfdade82348d5e7995e15612754826ea640afc20915119734f/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e1157659470aa42a75448b6e943c895be8c70531c43cb78b9ba990778955582", size = 384711, upload_time = "2025-07-01T15:54:18.101Z" }, + { url = "https://files.pythonhosted.org/packages/ec/43/e5c86fef4be7f49828bdd4ecc8931f0287b1152c0bb0163049b3218740e7/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:521ccf56f45bb3a791182dc6b88ae5f8fa079dd705ee42138c76deb1238e554e", size = 400865, upload_time = "2025-07-01T15:54:19.295Z" }, + { url = "https://files.pythonhosted.org/packages/55/34/e00f726a4d44f22d5c5fe2e5ddd3ac3d7fd3f74a175607781fbdd06fe375/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9def736773fd56b305c0eef698be5192c77bfa30d55a0e5885f80126c4831a15", size = 517763, upload_time = "2025-07-01T15:54:20.858Z" }, + { url = "https://files.pythonhosted.org/packages/52/1c/52dc20c31b147af724b16104500fba13e60123ea0334beba7b40e33354b4/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdad4ea3b4513b475e027be79e5a0ceac8ee1c113a1a11e5edc3c30c29f964d8", size = 406651, upload_time = "2025-07-01T15:54:22.508Z" }, + { url = "https://files.pythonhosted.org/packages/2e/77/87d7bfabfc4e821caa35481a2ff6ae0b73e6a391bb6b343db2c91c2b9844/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82b165b07f416bdccf5c84546a484cc8f15137ca38325403864bfdf2b5b72f6a", size = 386079, upload_time = "2025-07-01T15:54:23.987Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d4/7f2200c2d3ee145b65b3cddc4310d51f7da6a26634f3ac87125fd789152a/rpds_py-0.26.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d04cab0a54b9dba4d278fe955a1390da3cf71f57feb78ddc7cb67cbe0bd30323", size = 421379, upload_time = "2025-07-01T15:54:25.073Z" }, + { url = "https://files.pythonhosted.org/packages/ae/13/9fdd428b9c820869924ab62236b8688b122baa22d23efdd1c566938a39ba/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:79061ba1a11b6a12743a2b0f72a46aa2758613d454aa6ba4f5a265cc48850158", size = 562033, upload_time = "2025-07-01T15:54:26.225Z" }, + { url = "https://files.pythonhosted.org/packages/f3/e1/b69686c3bcbe775abac3a4c1c30a164a2076d28df7926041f6c0eb5e8d28/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f405c93675d8d4c5ac87364bb38d06c988e11028a64b52a47158a355079661f3", size = 591639, upload_time = "2025-07-01T15:54:27.424Z" }, + { url = "https://files.pythonhosted.org/packages/5c/c9/1e3d8c8863c84a90197ac577bbc3d796a92502124c27092413426f670990/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dafd4c44b74aa4bed4b250f1aed165b8ef5de743bcca3b88fc9619b6087093d2", size = 557105, upload_time = "2025-07-01T15:54:29.93Z" }, + { url = "https://files.pythonhosted.org/packages/9f/c5/90c569649057622959f6dcc40f7b516539608a414dfd54b8d77e3b201ac0/rpds_py-0.26.0-cp312-cp312-win32.whl", hash = "sha256:3da5852aad63fa0c6f836f3359647870e21ea96cf433eb393ffa45263a170d44", size = 223272, upload_time = "2025-07-01T15:54:31.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/16/19f5d9f2a556cfed454eebe4d354c38d51c20f3db69e7b4ce6cff904905d/rpds_py-0.26.0-cp312-cp312-win_amd64.whl", hash = "sha256:cf47cfdabc2194a669dcf7a8dbba62e37a04c5041d2125fae0233b720da6f05c", size = 234995, upload_time = "2025-07-01T15:54:32.195Z" }, + { url = "https://files.pythonhosted.org/packages/83/f0/7935e40b529c0e752dfaa7880224771b51175fce08b41ab4a92eb2fbdc7f/rpds_py-0.26.0-cp312-cp312-win_arm64.whl", hash = "sha256:20ab1ae4fa534f73647aad289003f1104092890849e0266271351922ed5574f8", size = 223198, upload_time = "2025-07-01T15:54:33.271Z" }, + { url = "https://files.pythonhosted.org/packages/6a/67/bb62d0109493b12b1c6ab00de7a5566aa84c0e44217c2d94bee1bd370da9/rpds_py-0.26.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:696764a5be111b036256c0b18cd29783fab22154690fc698062fc1b0084b511d", size = 363917, upload_time = "2025-07-01T15:54:34.755Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f3/34e6ae1925a5706c0f002a8d2d7f172373b855768149796af87bd65dcdb9/rpds_py-0.26.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1e6c15d2080a63aaed876e228efe4f814bc7889c63b1e112ad46fdc8b368b9e1", size = 350073, upload_time = "2025-07-01T15:54:36.292Z" }, + { url = "https://files.pythonhosted.org/packages/75/83/1953a9d4f4e4de7fd0533733e041c28135f3c21485faaef56a8aadbd96b5/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390e3170babf42462739a93321e657444f0862c6d722a291accc46f9d21ed04e", size = 384214, upload_time = "2025-07-01T15:54:37.469Z" }, + { url = "https://files.pythonhosted.org/packages/48/0e/983ed1b792b3322ea1d065e67f4b230f3b96025f5ce3878cc40af09b7533/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7da84c2c74c0f5bc97d853d9e17bb83e2dcafcff0dc48286916001cc114379a1", size = 400113, upload_time = "2025-07-01T15:54:38.954Z" }, + { url = "https://files.pythonhosted.org/packages/69/7f/36c0925fff6f660a80be259c5b4f5e53a16851f946eb080351d057698528/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c5fe114a6dd480a510b6d3661d09d67d1622c4bf20660a474507aaee7eeeee9", size = 515189, upload_time = "2025-07-01T15:54:40.57Z" }, + { url = "https://files.pythonhosted.org/packages/13/45/cbf07fc03ba7a9b54662c9badb58294ecfb24f828b9732970bd1a431ed5c/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3100b3090269f3a7ea727b06a6080d4eb7439dca4c0e91a07c5d133bb1727ea7", size = 406998, upload_time = "2025-07-01T15:54:43.025Z" }, + { url = "https://files.pythonhosted.org/packages/6c/b0/8fa5e36e58657997873fd6a1cf621285ca822ca75b4b3434ead047daa307/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c03c9b0c64afd0320ae57de4c982801271c0c211aa2d37f3003ff5feb75bb04", size = 385903, upload_time = "2025-07-01T15:54:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f7/b25437772f9f57d7a9fbd73ed86d0dcd76b4c7c6998348c070d90f23e315/rpds_py-0.26.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5963b72ccd199ade6ee493723d18a3f21ba7d5b957017607f815788cef50eaf1", size = 419785, upload_time = "2025-07-01T15:54:46.043Z" }, + { url = "https://files.pythonhosted.org/packages/a7/6b/63ffa55743dfcb4baf2e9e77a0b11f7f97ed96a54558fcb5717a4b2cd732/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da4e873860ad5bab3291438525cae80169daecbfafe5657f7f5fb4d6b3f96b9", size = 561329, upload_time = "2025-07-01T15:54:47.64Z" }, + { url = "https://files.pythonhosted.org/packages/2f/07/1f4f5e2886c480a2346b1e6759c00278b8a69e697ae952d82ae2e6ee5db0/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5afaddaa8e8c7f1f7b4c5c725c0070b6eed0228f705b90a1732a48e84350f4e9", size = 590875, upload_time = "2025-07-01T15:54:48.9Z" }, + { url = "https://files.pythonhosted.org/packages/cc/bc/e6639f1b91c3a55f8c41b47d73e6307051b6e246254a827ede730624c0f8/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4916dc96489616a6f9667e7526af8fa693c0fdb4f3acb0e5d9f4400eb06a47ba", size = 556636, upload_time = "2025-07-01T15:54:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/05/4c/b3917c45566f9f9a209d38d9b54a1833f2bb1032a3e04c66f75726f28876/rpds_py-0.26.0-cp313-cp313-win32.whl", hash = "sha256:2a343f91b17097c546b93f7999976fd6c9d5900617aa848c81d794e062ab302b", size = 222663, upload_time = "2025-07-01T15:54:52.023Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0b/0851bdd6025775aaa2365bb8de0697ee2558184c800bfef8d7aef5ccde58/rpds_py-0.26.0-cp313-cp313-win_amd64.whl", hash = "sha256:0a0b60701f2300c81b2ac88a5fb893ccfa408e1c4a555a77f908a2596eb875a5", size = 234428, upload_time = "2025-07-01T15:54:53.692Z" }, + { url = "https://files.pythonhosted.org/packages/ed/e8/a47c64ed53149c75fb581e14a237b7b7cd18217e969c30d474d335105622/rpds_py-0.26.0-cp313-cp313-win_arm64.whl", hash = "sha256:257d011919f133a4746958257f2c75238e3ff54255acd5e3e11f3ff41fd14256", size = 222571, upload_time = "2025-07-01T15:54:54.822Z" }, + { url = "https://files.pythonhosted.org/packages/89/bf/3d970ba2e2bcd17d2912cb42874107390f72873e38e79267224110de5e61/rpds_py-0.26.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:529c8156d7506fba5740e05da8795688f87119cce330c244519cf706a4a3d618", size = 360475, upload_time = "2025-07-01T15:54:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/82/9f/283e7e2979fc4ec2d8ecee506d5a3675fce5ed9b4b7cb387ea5d37c2f18d/rpds_py-0.26.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f53ec51f9d24e9638a40cabb95078ade8c99251945dad8d57bf4aabe86ecee35", size = 346692, upload_time = "2025-07-01T15:54:58.561Z" }, + { url = "https://files.pythonhosted.org/packages/e3/03/7e50423c04d78daf391da3cc4330bdb97042fc192a58b186f2d5deb7befd/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab504c4d654e4a29558eaa5bb8cea5fdc1703ea60a8099ffd9c758472cf913f", size = 379415, upload_time = "2025-07-01T15:54:59.751Z" }, + { url = "https://files.pythonhosted.org/packages/57/00/d11ee60d4d3b16808432417951c63df803afb0e0fc672b5e8d07e9edaaae/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd0641abca296bc1a00183fe44f7fced8807ed49d501f188faa642d0e4975b83", size = 391783, upload_time = "2025-07-01T15:55:00.898Z" }, + { url = "https://files.pythonhosted.org/packages/08/b3/1069c394d9c0d6d23c5b522e1f6546b65793a22950f6e0210adcc6f97c3e/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b312fecc1d017b5327afa81d4da1480f51c68810963a7336d92203dbb3d4f1", size = 512844, upload_time = "2025-07-01T15:55:02.201Z" }, + { url = "https://files.pythonhosted.org/packages/08/3b/c4fbf0926800ed70b2c245ceca99c49f066456755f5d6eb8863c2c51e6d0/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c741107203954f6fc34d3066d213d0a0c40f7bb5aafd698fb39888af277c70d8", size = 402105, upload_time = "2025-07-01T15:55:03.698Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b0/db69b52ca07413e568dae9dc674627a22297abb144c4d6022c6d78f1e5cc/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc3e55a7db08dc9a6ed5fb7103019d2c1a38a349ac41901f9f66d7f95750942f", size = 383440, upload_time = "2025-07-01T15:55:05.398Z" }, + { url = "https://files.pythonhosted.org/packages/4c/e1/c65255ad5b63903e56b3bb3ff9dcc3f4f5c3badde5d08c741ee03903e951/rpds_py-0.26.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e851920caab2dbcae311fd28f4313c6953993893eb5c1bb367ec69d9a39e7ed", size = 412759, upload_time = "2025-07-01T15:55:08.316Z" }, + { url = "https://files.pythonhosted.org/packages/e4/22/bb731077872377a93c6e93b8a9487d0406c70208985831034ccdeed39c8e/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dfbf280da5f876d0b00c81f26bedce274e72a678c28845453885a9b3c22ae632", size = 556032, upload_time = "2025-07-01T15:55:09.52Z" }, + { url = "https://files.pythonhosted.org/packages/e0/8b/393322ce7bac5c4530fb96fc79cc9ea2f83e968ff5f6e873f905c493e1c4/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1cc81d14ddfa53d7f3906694d35d54d9d3f850ef8e4e99ee68bc0d1e5fed9a9c", size = 585416, upload_time = "2025-07-01T15:55:11.216Z" }, + { url = "https://files.pythonhosted.org/packages/49/ae/769dc372211835bf759319a7aae70525c6eb523e3371842c65b7ef41c9c6/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dca83c498b4650a91efcf7b88d669b170256bf8017a5db6f3e06c2bf031f57e0", size = 554049, upload_time = "2025-07-01T15:55:13.004Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f9/4c43f9cc203d6ba44ce3146246cdc38619d92c7bd7bad4946a3491bd5b70/rpds_py-0.26.0-cp313-cp313t-win32.whl", hash = "sha256:4d11382bcaf12f80b51d790dee295c56a159633a8e81e6323b16e55d81ae37e9", size = 218428, upload_time = "2025-07-01T15:55:14.486Z" }, + { url = "https://files.pythonhosted.org/packages/7e/8b/9286b7e822036a4a977f2f1e851c7345c20528dbd56b687bb67ed68a8ede/rpds_py-0.26.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff110acded3c22c033e637dd8896e411c7d3a11289b2edf041f86663dbc791e9", size = 231524, upload_time = "2025-07-01T15:55:15.745Z" }, + { url = "https://files.pythonhosted.org/packages/55/07/029b7c45db910c74e182de626dfdae0ad489a949d84a468465cd0ca36355/rpds_py-0.26.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:da619979df60a940cd434084355c514c25cf8eb4cf9a508510682f6c851a4f7a", size = 364292, upload_time = "2025-07-01T15:55:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/13/d1/9b3d3f986216b4d1f584878dca15ce4797aaf5d372d738974ba737bf68d6/rpds_py-0.26.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ea89a2458a1a75f87caabefe789c87539ea4e43b40f18cff526052e35bbb4fdf", size = 350334, upload_time = "2025-07-01T15:55:18.922Z" }, + { url = "https://files.pythonhosted.org/packages/18/98/16d5e7bc9ec715fa9668731d0cf97f6b032724e61696e2db3d47aeb89214/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feac1045b3327a45944e7dcbeb57530339f6b17baff154df51ef8b0da34c8c12", size = 384875, upload_time = "2025-07-01T15:55:20.399Z" }, + { url = "https://files.pythonhosted.org/packages/f9/13/aa5e2b1ec5ab0e86a5c464d53514c0467bec6ba2507027d35fc81818358e/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b818a592bd69bfe437ee8368603d4a2d928c34cffcdf77c2e761a759ffd17d20", size = 399993, upload_time = "2025-07-01T15:55:21.729Z" }, + { url = "https://files.pythonhosted.org/packages/17/03/8021810b0e97923abdbab6474c8b77c69bcb4b2c58330777df9ff69dc559/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a8b0dd8648709b62d9372fc00a57466f5fdeefed666afe3fea5a6c9539a0331", size = 516683, upload_time = "2025-07-01T15:55:22.918Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b1/da8e61c87c2f3d836954239fdbbfb477bb7b54d74974d8f6fcb34342d166/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d3498ad0df07d81112aa6ec6c95a7e7b1ae00929fb73e7ebee0f3faaeabad2f", size = 408825, upload_time = "2025-07-01T15:55:24.207Z" }, + { url = "https://files.pythonhosted.org/packages/38/bc/1fc173edaaa0e52c94b02a655db20697cb5fa954ad5a8e15a2c784c5cbdd/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24a4146ccb15be237fdef10f331c568e1b0e505f8c8c9ed5d67759dac58ac246", size = 387292, upload_time = "2025-07-01T15:55:25.554Z" }, + { url = "https://files.pythonhosted.org/packages/7c/eb/3a9bb4bd90867d21916f253caf4f0d0be7098671b6715ad1cead9fe7bab9/rpds_py-0.26.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a9a63785467b2d73635957d32a4f6e73d5e4df497a16a6392fa066b753e87387", size = 420435, upload_time = "2025-07-01T15:55:27.798Z" }, + { url = "https://files.pythonhosted.org/packages/cd/16/e066dcdb56f5632713445271a3f8d3d0b426d51ae9c0cca387799df58b02/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:de4ed93a8c91debfd5a047be327b7cc8b0cc6afe32a716bbbc4aedca9e2a83af", size = 562410, upload_time = "2025-07-01T15:55:29.057Z" }, + { url = "https://files.pythonhosted.org/packages/60/22/ddbdec7eb82a0dc2e455be44c97c71c232983e21349836ce9f272e8a3c29/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:caf51943715b12af827696ec395bfa68f090a4c1a1d2509eb4e2cb69abbbdb33", size = 590724, upload_time = "2025-07-01T15:55:30.719Z" }, + { url = "https://files.pythonhosted.org/packages/2c/b4/95744085e65b7187d83f2fcb0bef70716a1ea0a9e5d8f7f39a86e5d83424/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4a59e5bc386de021f56337f757301b337d7ab58baa40174fb150accd480bc953", size = 558285, upload_time = "2025-07-01T15:55:31.981Z" }, + { url = "https://files.pythonhosted.org/packages/37/37/6309a75e464d1da2559446f9c811aa4d16343cebe3dbb73701e63f760caa/rpds_py-0.26.0-cp314-cp314-win32.whl", hash = "sha256:92c8db839367ef16a662478f0a2fe13e15f2227da3c1430a782ad0f6ee009ec9", size = 223459, upload_time = "2025-07-01T15:55:33.312Z" }, + { url = "https://files.pythonhosted.org/packages/d9/6f/8e9c11214c46098b1d1391b7e02b70bb689ab963db3b19540cba17315291/rpds_py-0.26.0-cp314-cp314-win_amd64.whl", hash = "sha256:b0afb8cdd034150d4d9f53926226ed27ad15b7f465e93d7468caaf5eafae0d37", size = 236083, upload_time = "2025-07-01T15:55:34.933Z" }, + { url = "https://files.pythonhosted.org/packages/47/af/9c4638994dd623d51c39892edd9d08e8be8220a4b7e874fa02c2d6e91955/rpds_py-0.26.0-cp314-cp314-win_arm64.whl", hash = "sha256:ca3f059f4ba485d90c8dc75cb5ca897e15325e4e609812ce57f896607c1c0867", size = 223291, upload_time = "2025-07-01T15:55:36.202Z" }, + { url = "https://files.pythonhosted.org/packages/4d/db/669a241144460474aab03e254326b32c42def83eb23458a10d163cb9b5ce/rpds_py-0.26.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:5afea17ab3a126006dc2f293b14ffc7ef3c85336cf451564a0515ed7648033da", size = 361445, upload_time = "2025-07-01T15:55:37.483Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/133f61cc5807c6c2fd086a46df0eb8f63a23f5df8306ff9f6d0fd168fecc/rpds_py-0.26.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:69f0c0a3df7fd3a7eec50a00396104bb9a843ea6d45fcc31c2d5243446ffd7a7", size = 347206, upload_time = "2025-07-01T15:55:38.828Z" }, + { url = "https://files.pythonhosted.org/packages/05/bf/0e8fb4c05f70273469eecf82f6ccf37248558526a45321644826555db31b/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:801a71f70f9813e82d2513c9a96532551fce1e278ec0c64610992c49c04c2dad", size = 380330, upload_time = "2025-07-01T15:55:40.175Z" }, + { url = "https://files.pythonhosted.org/packages/d4/a8/060d24185d8b24d3923322f8d0ede16df4ade226a74e747b8c7c978e3dd3/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df52098cde6d5e02fa75c1f6244f07971773adb4a26625edd5c18fee906fa84d", size = 392254, upload_time = "2025-07-01T15:55:42.015Z" }, + { url = "https://files.pythonhosted.org/packages/b9/7b/7c2e8a9ee3e6bc0bae26bf29f5219955ca2fbb761dca996a83f5d2f773fe/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bc596b30f86dc6f0929499c9e574601679d0341a0108c25b9b358a042f51bca", size = 516094, upload_time = "2025-07-01T15:55:43.603Z" }, + { url = "https://files.pythonhosted.org/packages/75/d6/f61cafbed8ba1499b9af9f1777a2a199cd888f74a96133d8833ce5eaa9c5/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dfbe56b299cf5875b68eb6f0ebaadc9cac520a1989cac0db0765abfb3709c19", size = 402889, upload_time = "2025-07-01T15:55:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/92/19/c8ac0a8a8df2dd30cdec27f69298a5c13e9029500d6d76718130f5e5be10/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac64f4b2bdb4ea622175c9ab7cf09444e412e22c0e02e906978b3b488af5fde8", size = 384301, upload_time = "2025-07-01T15:55:47.098Z" }, + { url = "https://files.pythonhosted.org/packages/41/e1/6b1859898bc292a9ce5776016c7312b672da00e25cec74d7beced1027286/rpds_py-0.26.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:181ef9b6bbf9845a264f9aa45c31836e9f3c1f13be565d0d010e964c661d1e2b", size = 412891, upload_time = "2025-07-01T15:55:48.412Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b9/ceb39af29913c07966a61367b3c08b4f71fad841e32c6b59a129d5974698/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:49028aa684c144ea502a8e847d23aed5e4c2ef7cadfa7d5eaafcb40864844b7a", size = 557044, upload_time = "2025-07-01T15:55:49.816Z" }, + { url = "https://files.pythonhosted.org/packages/2f/27/35637b98380731a521f8ec4f3fd94e477964f04f6b2f8f7af8a2d889a4af/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e5d524d68a474a9688336045bbf76cb0def88549c1b2ad9dbfec1fb7cfbe9170", size = 585774, upload_time = "2025-07-01T15:55:51.192Z" }, + { url = "https://files.pythonhosted.org/packages/52/d9/3f0f105420fecd18551b678c9a6ce60bd23986098b252a56d35781b3e7e9/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c1851f429b822831bd2edcbe0cfd12ee9ea77868f8d3daf267b189371671c80e", size = 554886, upload_time = "2025-07-01T15:55:52.541Z" }, + { url = "https://files.pythonhosted.org/packages/6b/c5/347c056a90dc8dd9bc240a08c527315008e1b5042e7a4cf4ac027be9d38a/rpds_py-0.26.0-cp314-cp314t-win32.whl", hash = "sha256:7bdb17009696214c3b66bb3590c6d62e14ac5935e53e929bcdbc5a495987a84f", size = 219027, upload_time = "2025-07-01T15:55:53.874Z" }, + { url = "https://files.pythonhosted.org/packages/75/04/5302cea1aa26d886d34cadbf2dc77d90d7737e576c0065f357b96dc7a1a6/rpds_py-0.26.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f14440b9573a6f76b4ee4770c13f0b5921f71dde3b6fcb8dabbefd13b7fe05d7", size = 232821, upload_time = "2025-07-01T15:55:55.167Z" }, + { url = "https://files.pythonhosted.org/packages/ef/9a/1f033b0b31253d03d785b0cd905bc127e555ab496ea6b4c7c2e1f951f2fd/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3c0909c5234543ada2515c05dc08595b08d621ba919629e94427e8e03539c958", size = 373226, upload_time = "2025-07-01T15:56:16.578Z" }, + { url = "https://files.pythonhosted.org/packages/58/29/5f88023fd6aaaa8ca3c4a6357ebb23f6f07da6079093ccf27c99efce87db/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c1fb0cda2abcc0ac62f64e2ea4b4e64c57dfd6b885e693095460c61bde7bb18e", size = 359230, upload_time = "2025-07-01T15:56:17.978Z" }, + { url = "https://files.pythonhosted.org/packages/6c/6c/13eaebd28b439da6964dde22712b52e53fe2824af0223b8e403249d10405/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d142d2d6cf9b31c12aa4878d82ed3b2324226270b89b676ac62ccd7df52d08", size = 382363, upload_time = "2025-07-01T15:56:19.977Z" }, + { url = "https://files.pythonhosted.org/packages/55/fc/3bb9c486b06da19448646f96147796de23c5811ef77cbfc26f17307b6a9d/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a547e21c5610b7e9093d870be50682a6a6cf180d6da0f42c47c306073bfdbbf6", size = 397146, upload_time = "2025-07-01T15:56:21.39Z" }, + { url = "https://files.pythonhosted.org/packages/15/18/9d1b79eb4d18e64ba8bba9e7dec6f9d6920b639f22f07ee9368ca35d4673/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35e9a70a0f335371275cdcd08bc5b8051ac494dd58bff3bbfb421038220dc871", size = 514804, upload_time = "2025-07-01T15:56:22.78Z" }, + { url = "https://files.pythonhosted.org/packages/4f/5a/175ad7191bdbcd28785204621b225ad70e85cdfd1e09cc414cb554633b21/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dfa6115c6def37905344d56fb54c03afc49104e2ca473d5dedec0f6606913b4", size = 402820, upload_time = "2025-07-01T15:56:24.584Z" }, + { url = "https://files.pythonhosted.org/packages/11/45/6a67ecf6d61c4d4aff4bc056e864eec4b2447787e11d1c2c9a0242c6e92a/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:313cfcd6af1a55a286a3c9a25f64af6d0e46cf60bc5798f1db152d97a216ff6f", size = 384567, upload_time = "2025-07-01T15:56:26.064Z" }, + { url = "https://files.pythonhosted.org/packages/a1/ba/16589da828732b46454c61858950a78fe4c931ea4bf95f17432ffe64b241/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f7bf2496fa563c046d05e4d232d7b7fd61346e2402052064b773e5c378bf6f73", size = 416520, upload_time = "2025-07-01T15:56:27.608Z" }, + { url = "https://files.pythonhosted.org/packages/81/4b/00092999fc7c0c266045e984d56b7314734cc400a6c6dc4d61a35f135a9d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:aa81873e2c8c5aa616ab8e017a481a96742fdf9313c40f14338ca7dbf50cb55f", size = 559362, upload_time = "2025-07-01T15:56:29.078Z" }, + { url = "https://files.pythonhosted.org/packages/96/0c/43737053cde1f93ac4945157f7be1428724ab943e2132a0d235a7e161d4e/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:68ffcf982715f5b5b7686bdd349ff75d422e8f22551000c24b30eaa1b7f7ae84", size = 588113, upload_time = "2025-07-01T15:56:30.485Z" }, + { url = "https://files.pythonhosted.org/packages/46/46/8e38f6161466e60a997ed7e9951ae5de131dedc3cf778ad35994b4af823d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6188de70e190847bb6db3dc3981cbadff87d27d6fe9b4f0e18726d55795cee9b", size = 555429, upload_time = "2025-07-01T15:56:31.956Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ac/65da605e9f1dd643ebe615d5bbd11b6efa1d69644fc4bf623ea5ae385a82/rpds_py-0.26.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1c962145c7473723df9722ba4c058de12eb5ebedcb4e27e7d902920aa3831ee8", size = 231950, upload_time = "2025-07-01T15:56:33.337Z" }, + { url = "https://files.pythonhosted.org/packages/51/f2/b5c85b758a00c513bb0389f8fc8e61eb5423050c91c958cdd21843faa3e6/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f61a9326f80ca59214d1cceb0a09bb2ece5b2563d4e0cd37bfd5515c28510674", size = 373505, upload_time = "2025-07-01T15:56:34.716Z" }, + { url = "https://files.pythonhosted.org/packages/23/e0/25db45e391251118e915e541995bb5f5ac5691a3b98fb233020ba53afc9b/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:183f857a53bcf4b1b42ef0f57ca553ab56bdd170e49d8091e96c51c3d69ca696", size = 359468, upload_time = "2025-07-01T15:56:36.219Z" }, + { url = "https://files.pythonhosted.org/packages/0b/73/dd5ee6075bb6491be3a646b301dfd814f9486d924137a5098e61f0487e16/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:941c1cfdf4799d623cf3aa1d326a6b4fdb7a5799ee2687f3516738216d2262fb", size = 382680, upload_time = "2025-07-01T15:56:37.644Z" }, + { url = "https://files.pythonhosted.org/packages/2f/10/84b522ff58763a5c443f5bcedc1820240e454ce4e620e88520f04589e2ea/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72a8d9564a717ee291f554eeb4bfeafe2309d5ec0aa6c475170bdab0f9ee8e88", size = 397035, upload_time = "2025-07-01T15:56:39.241Z" }, + { url = "https://files.pythonhosted.org/packages/06/ea/8667604229a10a520fcbf78b30ccc278977dcc0627beb7ea2c96b3becef0/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:511d15193cbe013619dd05414c35a7dedf2088fcee93c6bbb7c77859765bd4e8", size = 514922, upload_time = "2025-07-01T15:56:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/24/e6/9ed5b625c0661c4882fc8cdf302bf8e96c73c40de99c31e0b95ed37d508c/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aea1f9741b603a8d8fedb0ed5502c2bc0accbc51f43e2ad1337fe7259c2b77a5", size = 402822, upload_time = "2025-07-01T15:56:42.137Z" }, + { url = "https://files.pythonhosted.org/packages/8a/58/212c7b6fd51946047fb45d3733da27e2fa8f7384a13457c874186af691b1/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4019a9d473c708cf2f16415688ef0b4639e07abaa569d72f74745bbeffafa2c7", size = 384336, upload_time = "2025-07-01T15:56:44.239Z" }, + { url = "https://files.pythonhosted.org/packages/aa/f5/a40ba78748ae8ebf4934d4b88e77b98497378bc2c24ba55ebe87a4e87057/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:093d63b4b0f52d98ebae33b8c50900d3d67e0666094b1be7a12fffd7f65de74b", size = 416871, upload_time = "2025-07-01T15:56:46.284Z" }, + { url = "https://files.pythonhosted.org/packages/d5/a6/33b1fc0c9f7dcfcfc4a4353daa6308b3ece22496ceece348b3e7a7559a09/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2abe21d8ba64cded53a2a677e149ceb76dcf44284202d737178afe7ba540c1eb", size = 559439, upload_time = "2025-07-01T15:56:48.549Z" }, + { url = "https://files.pythonhosted.org/packages/71/2d/ceb3f9c12f8cfa56d34995097f6cd99da1325642c60d1b6680dd9df03ed8/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:4feb7511c29f8442cbbc28149a92093d32e815a28aa2c50d333826ad2a20fdf0", size = 588380, upload_time = "2025-07-01T15:56:50.086Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ed/9de62c2150ca8e2e5858acf3f4f4d0d180a38feef9fdab4078bea63d8dba/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e99685fc95d386da368013e7fb4269dd39c30d99f812a8372d62f244f662709c", size = 555334, upload_time = "2025-07-01T15:56:51.703Z" }, ] [[package]] -name = "pytest" -version = "7.4.4" +name = "rsa" +version = "4.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "iniconfig" }, - { name = "packaging" }, - { name = "pluggy" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "pyasn1" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116 } +sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload_time = "2025-04-16T09:51:18.218Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287 }, + { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload_time = "2025-04-16T09:51:17.142Z" }, ] [[package]] -name = "python-dateutil" -version = "2.9.0.post0" +name = "ruff" +version = "0.6.7" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "six" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +sdist = { url = "https://files.pythonhosted.org/packages/8d/7c/3045a526c57cef4b5ec4d5d154692e31429749a49810a53e785de334c4f6/ruff-0.6.7.tar.gz", hash = "sha256:44e52129d82266fa59b587e2cd74def5637b730a69c4542525dfdecfaae38bd5", size = 3073785, upload_time = "2024-09-21T17:35:55.11Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, + { url = "https://files.pythonhosted.org/packages/22/c4/1c5c636f83f905c537785016e9cdd7a36df53c025a2d07940580ecb37bcf/ruff-0.6.7-py3-none-linux_armv6l.whl", hash = "sha256:08277b217534bfdcc2e1377f7f933e1c7957453e8a79764d004e44c40db923f2", size = 10336748, upload_time = "2024-09-21T17:35:12.756Z" }, + { url = "https://files.pythonhosted.org/packages/84/d9/aa15a56be7ad796f4d7625362aff588f9fc013bbb7323a63571628a2cf2d/ruff-0.6.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c6707a32e03b791f4448dc0dce24b636cbcdee4dd5607adc24e5ee73fd86c00a", size = 9958833, upload_time = "2024-09-21T17:35:15.709Z" }, + { url = "https://files.pythonhosted.org/packages/27/25/5dd1c32bfc3ad3136c8ebe84312d1bdd2e6c908ac7f60692ec009b7050a8/ruff-0.6.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:533d66b7774ef224e7cf91506a7dafcc9e8ec7c059263ec46629e54e7b1f90ab", size = 9633369, upload_time = "2024-09-21T17:35:18.503Z" }, + { url = "https://files.pythonhosted.org/packages/0e/3e/01b25484f3cb08fe6fddedf1f55f3f3c0af861a5b5f5082fbe60ab4b2596/ruff-0.6.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17a86aac6f915932d259f7bec79173e356165518859f94649d8c50b81ff087e9", size = 10637415, upload_time = "2024-09-21T17:35:21.178Z" }, + { url = "https://files.pythonhosted.org/packages/8a/c9/5bb9b849e4777e0f961de43edf95d2af0ab34999a5feee957be096887876/ruff-0.6.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3f8822defd260ae2460ea3832b24d37d203c3577f48b055590a426a722d50ef", size = 10097389, upload_time = "2024-09-21T17:35:23.232Z" }, + { url = "https://files.pythonhosted.org/packages/52/cf/e08f1c290c7d848ddfb2ae811f24f445c18e1d3e50e01c38ffa7f5a50494/ruff-0.6.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ba4efe5c6dbbb58be58dd83feedb83b5e95c00091bf09987b4baf510fee5c99", size = 10951440, upload_time = "2024-09-21T17:35:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2d/ca8aa0da5841913c302d8034c6de0ce56c401c685184d8dd23cfdd0003f9/ruff-0.6.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:525201b77f94d2b54868f0cbe5edc018e64c22563da6c5c2e5c107a4e85c1c0d", size = 11708900, upload_time = "2024-09-21T17:35:27.943Z" }, + { url = "https://files.pythonhosted.org/packages/89/fc/9a83c57baee977c82392e19a328b52cebdaf61601af3d99498e278ef5104/ruff-0.6.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8854450839f339e1049fdbe15d875384242b8e85d5c6947bb2faad33c651020b", size = 11258892, upload_time = "2024-09-21T17:35:31.014Z" }, + { url = "https://files.pythonhosted.org/packages/d3/a3/254cc7afef702c68ae9079290c2a1477ae0e81478589baf745026d8a4eb5/ruff-0.6.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f0b62056246234d59cbf2ea66e84812dc9ec4540518e37553513392c171cb18", size = 12367932, upload_time = "2024-09-21T17:35:34.456Z" }, + { url = "https://files.pythonhosted.org/packages/9f/55/53f10c1bd8c3b2ae79aed18e62b22c6346f9296aa0ec80489b8442bd06a9/ruff-0.6.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b1462fa56c832dc0cea5b4041cfc9c97813505d11cce74ebc6d1aae068de36b", size = 10838629, upload_time = "2024-09-21T17:35:37.212Z" }, + { url = "https://files.pythonhosted.org/packages/84/72/fb335c2b25432c63d15383ecbd7bfc1915e68cdf8d086a08042052144255/ruff-0.6.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:02b083770e4cdb1495ed313f5694c62808e71764ec6ee5db84eedd82fd32d8f5", size = 10648824, upload_time = "2024-09-21T17:35:39.249Z" }, + { url = "https://files.pythonhosted.org/packages/92/a8/d57e135a8ad99b6a0c6e2a5c590bcacdd57f44340174f4409c3893368610/ruff-0.6.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c05fd37013de36dfa883a3854fae57b3113aaa8abf5dea79202675991d48624", size = 10174368, upload_time = "2024-09-21T17:35:41.21Z" }, + { url = "https://files.pythonhosted.org/packages/a7/6f/1a30a6e81dcf2fa9ff3f7011eb87fe76c12a3c6bba74db6a1977d763de1f/ruff-0.6.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f49c9caa28d9bbfac4a637ae10327b3db00f47d038f3fbb2195c4d682e925b14", size = 10514383, upload_time = "2024-09-21T17:35:43.244Z" }, + { url = "https://files.pythonhosted.org/packages/0b/25/df6f2575bc9fe43a6dedfd8dee12896f09a94303e2c828d5f85856bb69a0/ruff-0.6.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a0e1655868164e114ba43a908fd2d64a271a23660195017c17691fb6355d59bb", size = 10902340, upload_time = "2024-09-21T17:35:45.839Z" }, + { url = "https://files.pythonhosted.org/packages/68/62/f2c1031e2fb7b94f9bf0603744e73db4ef90081b0eb1b9639a6feefd52ea/ruff-0.6.7-py3-none-win32.whl", hash = "sha256:a939ca435b49f6966a7dd64b765c9df16f1faed0ca3b6f16acdf7731969deb35", size = 8448033, upload_time = "2024-09-21T17:35:48.558Z" }, + { url = "https://files.pythonhosted.org/packages/97/80/193d1604a3f7d75eb1b2a7ce6bf0fdbdbc136889a65caacea6ffb29501b1/ruff-0.6.7-py3-none-win_amd64.whl", hash = "sha256:590445eec5653f36248584579c06252ad2e110a5d1f32db5420de35fb0e1c977", size = 9273543, upload_time = "2024-09-21T17:35:50.551Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a8/4abb5a9f58f51e4b1ea386be5ab2e547035bc1ee57200d1eca2f8909a33e/ruff-0.6.7-py3-none-win_arm64.whl", hash = "sha256:b28f0d5e2f771c1fe3c7a45d3f53916fc74a480698c4b5731f0bea61e52137c8", size = 8618044, upload_time = "2024-09-21T17:35:53.123Z" }, ] [[package]] -name = "python-dotenv" -version = "1.0.1" +name = "safetensors" +version = "0.5.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } +sdist = { url = "https://files.pythonhosted.org/packages/71/7e/2d5d6ee7b40c0682315367ec7475693d110f512922d582fef1bd4a63adc3/safetensors-0.5.3.tar.gz", hash = "sha256:b6b0d6ecacec39a4fdd99cc19f4576f5219ce858e6fd8dbe7609df0b8dc56965", size = 67210, upload_time = "2025-02-26T09:15:13.155Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, + { url = "https://files.pythonhosted.org/packages/18/ae/88f6c49dbd0cc4da0e08610019a3c78a7d390879a919411a410a1876d03a/safetensors-0.5.3-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd20eb133db8ed15b40110b7c00c6df51655a2998132193de2f75f72d99c7073", size = 436917, upload_time = "2025-02-26T09:15:03.702Z" }, + { url = "https://files.pythonhosted.org/packages/b8/3b/11f1b4a2f5d2ab7da34ecc062b0bc301f2be024d110a6466726bec8c055c/safetensors-0.5.3-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:21d01c14ff6c415c485616b8b0bf961c46b3b343ca59110d38d744e577f9cce7", size = 418419, upload_time = "2025-02-26T09:15:01.765Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9a/add3e6fef267658075c5a41573c26d42d80c935cdc992384dfae435feaef/safetensors-0.5.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11bce6164887cd491ca75c2326a113ba934be596e22b28b1742ce27b1d076467", size = 459493, upload_time = "2025-02-26T09:14:51.812Z" }, + { url = "https://files.pythonhosted.org/packages/df/5c/bf2cae92222513cc23b3ff85c4a1bb2811a2c3583ac0f8e8d502751de934/safetensors-0.5.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4a243be3590bc3301c821da7a18d87224ef35cbd3e5f5727e4e0728b8172411e", size = 472400, upload_time = "2025-02-26T09:14:53.549Z" }, + { url = "https://files.pythonhosted.org/packages/58/11/7456afb740bd45782d0f4c8e8e1bb9e572f1bf82899fb6ace58af47b4282/safetensors-0.5.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8bd84b12b1670a6f8e50f01e28156422a2bc07fb16fc4e98bded13039d688a0d", size = 522891, upload_time = "2025-02-26T09:14:55.717Z" }, + { url = "https://files.pythonhosted.org/packages/57/3d/fe73a9d2ace487e7285f6e157afee2383bd1ddb911b7cb44a55cf812eae3/safetensors-0.5.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:391ac8cab7c829452175f871fcaf414aa1e292b5448bd02620f675a7f3e7abb9", size = 537694, upload_time = "2025-02-26T09:14:57.036Z" }, + { url = "https://files.pythonhosted.org/packages/a6/f8/dae3421624fcc87a89d42e1898a798bc7ff72c61f38973a65d60df8f124c/safetensors-0.5.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cead1fa41fc54b1e61089fa57452e8834f798cb1dc7a09ba3524f1eb08e0317a", size = 471642, upload_time = "2025-02-26T09:15:00.544Z" }, + { url = "https://files.pythonhosted.org/packages/ce/20/1fbe16f9b815f6c5a672f5b760951e20e17e43f67f231428f871909a37f6/safetensors-0.5.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1077f3e94182d72618357b04b5ced540ceb71c8a813d3319f1aba448e68a770d", size = 502241, upload_time = "2025-02-26T09:14:58.303Z" }, + { url = "https://files.pythonhosted.org/packages/5f/18/8e108846b506487aa4629fe4116b27db65c3dde922de2c8e0cc1133f3f29/safetensors-0.5.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:799021e78287bac619c7b3f3606730a22da4cda27759ddf55d37c8db7511c74b", size = 638001, upload_time = "2025-02-26T09:15:05.79Z" }, + { url = "https://files.pythonhosted.org/packages/82/5a/c116111d8291af6c8c8a8b40628fe833b9db97d8141c2a82359d14d9e078/safetensors-0.5.3-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:df26da01aaac504334644e1b7642fa000bfec820e7cef83aeac4e355e03195ff", size = 734013, upload_time = "2025-02-26T09:15:07.892Z" }, + { url = "https://files.pythonhosted.org/packages/7d/ff/41fcc4d3b7de837963622e8610d998710705bbde9a8a17221d85e5d0baad/safetensors-0.5.3-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:32c3ef2d7af8b9f52ff685ed0bc43913cdcde135089ae322ee576de93eae5135", size = 670687, upload_time = "2025-02-26T09:15:09.979Z" }, + { url = "https://files.pythonhosted.org/packages/40/ad/2b113098e69c985a3d8fbda4b902778eae4a35b7d5188859b4a63d30c161/safetensors-0.5.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:37f1521be045e56fc2b54c606d4455573e717b2d887c579ee1dbba5f868ece04", size = 643147, upload_time = "2025-02-26T09:15:11.185Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0c/95aeb51d4246bd9a3242d3d8349c1112b4ee7611a4b40f0c5c93b05f001d/safetensors-0.5.3-cp38-abi3-win32.whl", hash = "sha256:cfc0ec0846dcf6763b0ed3d1846ff36008c6e7290683b61616c4b040f6a54ace", size = 296677, upload_time = "2025-02-26T09:15:16.554Z" }, + { url = "https://files.pythonhosted.org/packages/69/e2/b011c38e5394c4c18fb5500778a55ec43ad6106126e74723ffaee246f56e/safetensors-0.5.3-cp38-abi3-win_amd64.whl", hash = "sha256:836cbbc320b47e80acd40e44c8682db0e8ad7123209f69b093def21ec7cafd11", size = 308878, upload_time = "2025-02-26T09:15:14.99Z" }, ] [[package]] -name = "python-multipart" -version = "0.0.20" +name = "scikit-learn" +version = "1.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158 } +dependencies = [ + { name = "joblib" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "scipy", version = "1.16.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/3b/29fa87e76b1d7b3b77cc1fcbe82e6e6b8cd704410705b008822de530277c/scikit_learn-1.7.0.tar.gz", hash = "sha256:c01e869b15aec88e2cdb73d27f15bdbe03bce8e2fb43afbe77c45d399e73a5a3", size = 7178217, upload_time = "2025-06-05T22:02:46.703Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 }, + { url = "https://files.pythonhosted.org/packages/a4/70/e725b1da11e7e833f558eb4d3ea8b7ed7100edda26101df074f1ae778235/scikit_learn-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9fe7f51435f49d97bd41d724bb3e11eeb939882af9c29c931a8002c357e8cdd5", size = 11728006, upload_time = "2025-06-05T22:01:43.007Z" }, + { url = "https://files.pythonhosted.org/packages/32/aa/43874d372e9dc51eb361f5c2f0a4462915c9454563b3abb0d9457c66b7e9/scikit_learn-1.7.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0c93294e1e1acbee2d029b1f2a064f26bd928b284938d51d412c22e0c977eb3", size = 10726255, upload_time = "2025-06-05T22:01:46.082Z" }, + { url = "https://files.pythonhosted.org/packages/f5/1a/da73cc18e00f0b9ae89f7e4463a02fb6e0569778120aeab138d9554ecef0/scikit_learn-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf3755f25f145186ad8c403312f74fb90df82a4dfa1af19dc96ef35f57237a94", size = 12205657, upload_time = "2025-06-05T22:01:48.729Z" }, + { url = "https://files.pythonhosted.org/packages/fb/f6/800cb3243dd0137ca6d98df8c9d539eb567ba0a0a39ecd245c33fab93510/scikit_learn-1.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2726c8787933add436fb66fb63ad18e8ef342dfb39bbbd19dc1e83e8f828a85a", size = 12877290, upload_time = "2025-06-05T22:01:51.073Z" }, + { url = "https://files.pythonhosted.org/packages/4c/bd/99c3ccb49946bd06318fe194a1c54fb7d57ac4fe1c2f4660d86b3a2adf64/scikit_learn-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:e2539bb58886a531b6e86a510c0348afaadd25005604ad35966a85c2ec378800", size = 10713211, upload_time = "2025-06-05T22:01:54.107Z" }, + { url = "https://files.pythonhosted.org/packages/5a/42/c6b41711c2bee01c4800ad8da2862c0b6d2956a399d23ce4d77f2ca7f0c7/scikit_learn-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ef09b1615e1ad04dc0d0054ad50634514818a8eb3ee3dee99af3bffc0ef5007", size = 11719657, upload_time = "2025-06-05T22:01:56.345Z" }, + { url = "https://files.pythonhosted.org/packages/a3/24/44acca76449e391b6b2522e67a63c0454b7c1f060531bdc6d0118fb40851/scikit_learn-1.7.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:7d7240c7b19edf6ed93403f43b0fcb0fe95b53bc0b17821f8fb88edab97085ef", size = 10712636, upload_time = "2025-06-05T22:01:59.093Z" }, + { url = "https://files.pythonhosted.org/packages/9f/1b/fcad1ccb29bdc9b96bcaa2ed8345d56afb77b16c0c47bafe392cc5d1d213/scikit_learn-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80bd3bd4e95381efc47073a720d4cbab485fc483966f1709f1fd559afac57ab8", size = 12242817, upload_time = "2025-06-05T22:02:01.43Z" }, + { url = "https://files.pythonhosted.org/packages/c6/38/48b75c3d8d268a3f19837cb8a89155ead6e97c6892bb64837183ea41db2b/scikit_learn-1.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dbe48d69aa38ecfc5a6cda6c5df5abef0c0ebdb2468e92437e2053f84abb8bc", size = 12873961, upload_time = "2025-06-05T22:02:03.951Z" }, + { url = "https://files.pythonhosted.org/packages/f4/5a/ba91b8c57aa37dbd80d5ff958576a9a8c14317b04b671ae7f0d09b00993a/scikit_learn-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:8fa979313b2ffdfa049ed07252dc94038def3ecd49ea2a814db5401c07f1ecfa", size = 10717277, upload_time = "2025-06-05T22:02:06.77Z" }, + { url = "https://files.pythonhosted.org/packages/70/3a/bffab14e974a665a3ee2d79766e7389572ffcaad941a246931c824afcdb2/scikit_learn-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c2c7243d34aaede0efca7a5a96d67fddaebb4ad7e14a70991b9abee9dc5c0379", size = 11646758, upload_time = "2025-06-05T22:02:09.51Z" }, + { url = "https://files.pythonhosted.org/packages/58/d8/f3249232fa79a70cb40595282813e61453c1e76da3e1a44b77a63dd8d0cb/scikit_learn-1.7.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:9f39f6a811bf3f15177b66c82cbe0d7b1ebad9f190737dcdef77cfca1ea3c19c", size = 10673971, upload_time = "2025-06-05T22:02:12.217Z" }, + { url = "https://files.pythonhosted.org/packages/67/93/eb14c50533bea2f77758abe7d60a10057e5f2e2cdcf0a75a14c6bc19c734/scikit_learn-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63017a5f9a74963d24aac7590287149a8d0f1a0799bbe7173c0d8ba1523293c0", size = 11818428, upload_time = "2025-06-05T22:02:14.947Z" }, + { url = "https://files.pythonhosted.org/packages/08/17/804cc13b22a8663564bb0b55fb89e661a577e4e88a61a39740d58b909efe/scikit_learn-1.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b2f8a0b1e73e9a08b7cc498bb2aeab36cdc1f571f8ab2b35c6e5d1c7115d97d", size = 12505887, upload_time = "2025-06-05T22:02:17.824Z" }, + { url = "https://files.pythonhosted.org/packages/68/c7/4e956281a077f4835458c3f9656c666300282d5199039f26d9de1dabd9be/scikit_learn-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:34cc8d9d010d29fb2b7cbcd5ccc24ffdd80515f65fe9f1e4894ace36b267ce19", size = 10668129, upload_time = "2025-06-05T22:02:20.536Z" }, + { url = "https://files.pythonhosted.org/packages/9a/c3/a85dcccdaf1e807e6f067fa95788a6485b0491d9ea44fd4c812050d04f45/scikit_learn-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5b7974f1f32bc586c90145df51130e02267e4b7e77cab76165c76cf43faca0d9", size = 11559841, upload_time = "2025-06-05T22:02:23.308Z" }, + { url = "https://files.pythonhosted.org/packages/d8/57/eea0de1562cc52d3196eae51a68c5736a31949a465f0b6bb3579b2d80282/scikit_learn-1.7.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:014e07a23fe02e65f9392898143c542a50b6001dbe89cb867e19688e468d049b", size = 10616463, upload_time = "2025-06-05T22:02:26.068Z" }, + { url = "https://files.pythonhosted.org/packages/10/a4/39717ca669296dfc3a62928393168da88ac9d8cbec88b6321ffa62c6776f/scikit_learn-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7e7ced20582d3a5516fb6f405fd1d254e1f5ce712bfef2589f51326af6346e8", size = 11766512, upload_time = "2025-06-05T22:02:28.689Z" }, + { url = "https://files.pythonhosted.org/packages/d5/cd/a19722241d5f7b51e08351e1e82453e0057aeb7621b17805f31fcb57bb6c/scikit_learn-1.7.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1babf2511e6ffd695da7a983b4e4d6de45dce39577b26b721610711081850906", size = 12461075, upload_time = "2025-06-05T22:02:31.233Z" }, + { url = "https://files.pythonhosted.org/packages/f3/bc/282514272815c827a9acacbe5b99f4f1a4bc5961053719d319480aee0812/scikit_learn-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:5abd2acff939d5bd4701283f009b01496832d50ddafa83c90125a4e41c33e314", size = 10652517, upload_time = "2025-06-05T22:02:34.139Z" }, + { url = "https://files.pythonhosted.org/packages/ea/78/7357d12b2e4c6674175f9a09a3ba10498cde8340e622715bcc71e532981d/scikit_learn-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:e39d95a929b112047c25b775035c8c234c5ca67e681ce60d12413afb501129f7", size = 12111822, upload_time = "2025-06-05T22:02:36.904Z" }, + { url = "https://files.pythonhosted.org/packages/d0/0c/9c3715393343f04232f9d81fe540eb3831d0b4ec351135a145855295110f/scikit_learn-1.7.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:0521cb460426c56fee7e07f9365b0f45ec8ca7b2d696534ac98bfb85e7ae4775", size = 11325286, upload_time = "2025-06-05T22:02:39.739Z" }, + { url = "https://files.pythonhosted.org/packages/64/e0/42282ad3dd70b7c1a5f65c412ac3841f6543502a8d6263cae7b466612dc9/scikit_learn-1.7.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:317ca9f83acbde2883bd6bb27116a741bfcb371369706b4f9973cf30e9a03b0d", size = 12380865, upload_time = "2025-06-05T22:02:42.137Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d0/3ef4ab2c6be4aa910445cd09c5ef0b44512e3de2cfb2112a88bb647d2cf7/scikit_learn-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:126c09740a6f016e815ab985b21e3a0656835414521c81fc1a8da78b679bdb75", size = 11549609, upload_time = "2025-06-05T22:02:44.483Z" }, ] [[package]] -name = "pyyaml" -version = "6.0.2" +name = "scipy" +version = "1.15.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, - { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, - { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, - { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, - { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, - { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, - { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, - { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, - { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, - { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, - { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, - { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, - { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, - { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, - { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, - { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +resolution-markers = [ + "python_full_version < '3.11'", ] - -[[package]] -name = "requests" -version = "2.32.3" -source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload_time = "2025-05-08T16:13:05.955Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, + { url = "https://files.pythonhosted.org/packages/78/2f/4966032c5f8cc7e6a60f1b2e0ad686293b9474b65246b0c642e3ef3badd0/scipy-1.15.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c", size = 38702770, upload_time = "2025-05-08T16:04:20.849Z" }, + { url = "https://files.pythonhosted.org/packages/a0/6e/0c3bf90fae0e910c274db43304ebe25a6b391327f3f10b5dcc638c090795/scipy-1.15.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253", size = 30094511, upload_time = "2025-05-08T16:04:27.103Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b1/4deb37252311c1acff7f101f6453f0440794f51b6eacb1aad4459a134081/scipy-1.15.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f", size = 22368151, upload_time = "2025-05-08T16:04:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/f457626e3cd3c29b3a49ca115a304cebb8cc6f31b04678f03b216899d3c6/scipy-1.15.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92", size = 25121732, upload_time = "2025-05-08T16:04:36.596Z" }, + { url = "https://files.pythonhosted.org/packages/db/0a/92b1de4a7adc7a15dcf5bddc6e191f6f29ee663b30511ce20467ef9b82e4/scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82", size = 35547617, upload_time = "2025-05-08T16:04:43.546Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6d/41991e503e51fc1134502694c5fa7a1671501a17ffa12716a4a9151af3df/scipy-1.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40", size = 37662964, upload_time = "2025-05-08T16:04:49.431Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/3df8f83cb15f3500478c889be8fb18700813b95e9e087328230b98d547ff/scipy-1.15.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e", size = 37238749, upload_time = "2025-05-08T16:04:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/b3257cf446f2a3533ed7809757039016b74cd6f38271de91682aa844cfc5/scipy-1.15.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c", size = 40022383, upload_time = "2025-05-08T16:05:01.914Z" }, + { url = "https://files.pythonhosted.org/packages/d1/84/55bc4881973d3f79b479a5a2e2df61c8c9a04fcb986a213ac9c02cfb659b/scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13", size = 41259201, upload_time = "2025-05-08T16:05:08.166Z" }, + { url = "https://files.pythonhosted.org/packages/96/ab/5cc9f80f28f6a7dff646c5756e559823614a42b1939d86dd0ed550470210/scipy-1.15.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:993439ce220d25e3696d1b23b233dd010169b62f6456488567e830654ee37a6b", size = 38714255, upload_time = "2025-05-08T16:05:14.596Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4a/66ba30abe5ad1a3ad15bfb0b59d22174012e8056ff448cb1644deccbfed2/scipy-1.15.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:34716e281f181a02341ddeaad584205bd2fd3c242063bd3423d61ac259ca7eba", size = 30111035, upload_time = "2025-05-08T16:05:20.152Z" }, + { url = "https://files.pythonhosted.org/packages/4b/fa/a7e5b95afd80d24313307f03624acc65801846fa75599034f8ceb9e2cbf6/scipy-1.15.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3b0334816afb8b91dab859281b1b9786934392aa3d527cd847e41bb6f45bee65", size = 22384499, upload_time = "2025-05-08T16:05:24.494Z" }, + { url = "https://files.pythonhosted.org/packages/17/99/f3aaddccf3588bb4aea70ba35328c204cadd89517a1612ecfda5b2dd9d7a/scipy-1.15.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:6db907c7368e3092e24919b5e31c76998b0ce1684d51a90943cb0ed1b4ffd6c1", size = 25152602, upload_time = "2025-05-08T16:05:29.313Z" }, + { url = "https://files.pythonhosted.org/packages/56/c5/1032cdb565f146109212153339f9cb8b993701e9fe56b1c97699eee12586/scipy-1.15.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:721d6b4ef5dc82ca8968c25b111e307083d7ca9091bc38163fb89243e85e3889", size = 35503415, upload_time = "2025-05-08T16:05:34.699Z" }, + { url = "https://files.pythonhosted.org/packages/bd/37/89f19c8c05505d0601ed5650156e50eb881ae3918786c8fd7262b4ee66d3/scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39cb9c62e471b1bb3750066ecc3a3f3052b37751c7c3dfd0fd7e48900ed52982", size = 37652622, upload_time = "2025-05-08T16:05:40.762Z" }, + { url = "https://files.pythonhosted.org/packages/7e/31/be59513aa9695519b18e1851bb9e487de66f2d31f835201f1b42f5d4d475/scipy-1.15.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:795c46999bae845966368a3c013e0e00947932d68e235702b5c3f6ea799aa8c9", size = 37244796, upload_time = "2025-05-08T16:05:48.119Z" }, + { url = "https://files.pythonhosted.org/packages/10/c0/4f5f3eeccc235632aab79b27a74a9130c6c35df358129f7ac8b29f562ac7/scipy-1.15.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:18aaacb735ab38b38db42cb01f6b92a2d0d4b6aabefeb07f02849e47f8fb3594", size = 40047684, upload_time = "2025-05-08T16:05:54.22Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a7/0ddaf514ce8a8714f6ed243a2b391b41dbb65251affe21ee3077ec45ea9a/scipy-1.15.3-cp311-cp311-win_amd64.whl", hash = "sha256:ae48a786a28412d744c62fd7816a4118ef97e5be0bee968ce8f0a2fba7acf3bb", size = 41246504, upload_time = "2025-05-08T16:06:00.437Z" }, + { url = "https://files.pythonhosted.org/packages/37/4b/683aa044c4162e10ed7a7ea30527f2cbd92e6999c10a8ed8edb253836e9c/scipy-1.15.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6ac6310fdbfb7aa6612408bd2f07295bcbd3fda00d2d702178434751fe48e019", size = 38766735, upload_time = "2025-05-08T16:06:06.471Z" }, + { url = "https://files.pythonhosted.org/packages/7b/7e/f30be3d03de07f25dc0ec926d1681fed5c732d759ac8f51079708c79e680/scipy-1.15.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:185cd3d6d05ca4b44a8f1595af87f9c372bb6acf9c808e99aa3e9aa03bd98cf6", size = 30173284, upload_time = "2025-05-08T16:06:11.686Z" }, + { url = "https://files.pythonhosted.org/packages/07/9c/0ddb0d0abdabe0d181c1793db51f02cd59e4901da6f9f7848e1f96759f0d/scipy-1.15.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:05dc6abcd105e1a29f95eada46d4a3f251743cfd7d3ae8ddb4088047f24ea477", size = 22446958, upload_time = "2025-05-08T16:06:15.97Z" }, + { url = "https://files.pythonhosted.org/packages/af/43/0bce905a965f36c58ff80d8bea33f1f9351b05fad4beaad4eae34699b7a1/scipy-1.15.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:06efcba926324df1696931a57a176c80848ccd67ce6ad020c810736bfd58eb1c", size = 25242454, upload_time = "2025-05-08T16:06:20.394Z" }, + { url = "https://files.pythonhosted.org/packages/56/30/a6f08f84ee5b7b28b4c597aca4cbe545535c39fe911845a96414700b64ba/scipy-1.15.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05045d8b9bfd807ee1b9f38761993297b10b245f012b11b13b91ba8945f7e45", size = 35210199, upload_time = "2025-05-08T16:06:26.159Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1f/03f52c282437a168ee2c7c14a1a0d0781a9a4a8962d84ac05c06b4c5b555/scipy-1.15.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271e3713e645149ea5ea3e97b57fdab61ce61333f97cfae392c28ba786f9bb49", size = 37309455, upload_time = "2025-05-08T16:06:32.778Z" }, + { url = "https://files.pythonhosted.org/packages/89/b1/fbb53137f42c4bf630b1ffdfc2151a62d1d1b903b249f030d2b1c0280af8/scipy-1.15.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cfd56fc1a8e53f6e89ba3a7a7251f7396412d655bca2aa5611c8ec9a6784a1e", size = 36885140, upload_time = "2025-05-08T16:06:39.249Z" }, + { url = "https://files.pythonhosted.org/packages/2e/2e/025e39e339f5090df1ff266d021892694dbb7e63568edcfe43f892fa381d/scipy-1.15.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ff17c0bb1cb32952c09217d8d1eed9b53d1463e5f1dd6052c7857f83127d539", size = 39710549, upload_time = "2025-05-08T16:06:45.729Z" }, + { url = "https://files.pythonhosted.org/packages/e6/eb/3bf6ea8ab7f1503dca3a10df2e4b9c3f6b3316df07f6c0ded94b281c7101/scipy-1.15.3-cp312-cp312-win_amd64.whl", hash = "sha256:52092bc0472cfd17df49ff17e70624345efece4e1a12b23783a1ac59a1b728ed", size = 40966184, upload_time = "2025-05-08T16:06:52.623Z" }, + { url = "https://files.pythonhosted.org/packages/73/18/ec27848c9baae6e0d6573eda6e01a602e5649ee72c27c3a8aad673ebecfd/scipy-1.15.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c620736bcc334782e24d173c0fdbb7590a0a436d2fdf39310a8902505008759", size = 38728256, upload_time = "2025-05-08T16:06:58.696Z" }, + { url = "https://files.pythonhosted.org/packages/74/cd/1aef2184948728b4b6e21267d53b3339762c285a46a274ebb7863c9e4742/scipy-1.15.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:7e11270a000969409d37ed399585ee530b9ef6aa99d50c019de4cb01e8e54e62", size = 30109540, upload_time = "2025-05-08T16:07:04.209Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d8/59e452c0a255ec352bd0a833537a3bc1bfb679944c4938ab375b0a6b3a3e/scipy-1.15.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8c9ed3ba2c8a2ce098163a9bdb26f891746d02136995df25227a20e71c396ebb", size = 22383115, upload_time = "2025-05-08T16:07:08.998Z" }, + { url = "https://files.pythonhosted.org/packages/08/f5/456f56bbbfccf696263b47095291040655e3cbaf05d063bdc7c7517f32ac/scipy-1.15.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0bdd905264c0c9cfa74a4772cdb2070171790381a5c4d312c973382fc6eaf730", size = 25163884, upload_time = "2025-05-08T16:07:14.091Z" }, + { url = "https://files.pythonhosted.org/packages/a2/66/a9618b6a435a0f0c0b8a6d0a2efb32d4ec5a85f023c2b79d39512040355b/scipy-1.15.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79167bba085c31f38603e11a267d862957cbb3ce018d8b38f79ac043bc92d825", size = 35174018, upload_time = "2025-05-08T16:07:19.427Z" }, + { url = "https://files.pythonhosted.org/packages/b5/09/c5b6734a50ad4882432b6bb7c02baf757f5b2f256041da5df242e2d7e6b6/scipy-1.15.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9deabd6d547aee2c9a81dee6cc96c6d7e9a9b1953f74850c179f91fdc729cb7", size = 37269716, upload_time = "2025-05-08T16:07:25.712Z" }, + { url = "https://files.pythonhosted.org/packages/77/0a/eac00ff741f23bcabd352731ed9b8995a0a60ef57f5fd788d611d43d69a1/scipy-1.15.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dde4fc32993071ac0c7dd2d82569e544f0bdaff66269cb475e0f369adad13f11", size = 36872342, upload_time = "2025-05-08T16:07:31.468Z" }, + { url = "https://files.pythonhosted.org/packages/fe/54/4379be86dd74b6ad81551689107360d9a3e18f24d20767a2d5b9253a3f0a/scipy-1.15.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f77f853d584e72e874d87357ad70f44b437331507d1c311457bed8ed2b956126", size = 39670869, upload_time = "2025-05-08T16:07:38.002Z" }, + { url = "https://files.pythonhosted.org/packages/87/2e/892ad2862ba54f084ffe8cc4a22667eaf9c2bcec6d2bff1d15713c6c0703/scipy-1.15.3-cp313-cp313-win_amd64.whl", hash = "sha256:b90ab29d0c37ec9bf55424c064312930ca5f4bde15ee8619ee44e69319aab163", size = 40988851, upload_time = "2025-05-08T16:08:33.671Z" }, + { url = "https://files.pythonhosted.org/packages/1b/e9/7a879c137f7e55b30d75d90ce3eb468197646bc7b443ac036ae3fe109055/scipy-1.15.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3ac07623267feb3ae308487c260ac684b32ea35fd81e12845039952f558047b8", size = 38863011, upload_time = "2025-05-08T16:07:44.039Z" }, + { url = "https://files.pythonhosted.org/packages/51/d1/226a806bbd69f62ce5ef5f3ffadc35286e9fbc802f606a07eb83bf2359de/scipy-1.15.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6487aa99c2a3d509a5227d9a5e889ff05830a06b2ce08ec30df6d79db5fcd5c5", size = 30266407, upload_time = "2025-05-08T16:07:49.891Z" }, + { url = "https://files.pythonhosted.org/packages/e5/9b/f32d1d6093ab9eeabbd839b0f7619c62e46cc4b7b6dbf05b6e615bbd4400/scipy-1.15.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:50f9e62461c95d933d5c5ef4a1f2ebf9a2b4e83b0db374cb3f1de104d935922e", size = 22540030, upload_time = "2025-05-08T16:07:54.121Z" }, + { url = "https://files.pythonhosted.org/packages/e7/29/c278f699b095c1a884f29fda126340fcc201461ee8bfea5c8bdb1c7c958b/scipy-1.15.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14ed70039d182f411ffc74789a16df3835e05dc469b898233a245cdfd7f162cb", size = 25218709, upload_time = "2025-05-08T16:07:58.506Z" }, + { url = "https://files.pythonhosted.org/packages/24/18/9e5374b617aba742a990581373cd6b68a2945d65cc588482749ef2e64467/scipy-1.15.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a769105537aa07a69468a0eefcd121be52006db61cdd8cac8a0e68980bbb723", size = 34809045, upload_time = "2025-05-08T16:08:03.929Z" }, + { url = "https://files.pythonhosted.org/packages/e1/fe/9c4361e7ba2927074360856db6135ef4904d505e9b3afbbcb073c4008328/scipy-1.15.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db984639887e3dffb3928d118145ffe40eff2fa40cb241a306ec57c219ebbbb", size = 36703062, upload_time = "2025-05-08T16:08:09.558Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8e/038ccfe29d272b30086b25a4960f757f97122cb2ec42e62b460d02fe98e9/scipy-1.15.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:40e54d5c7e7ebf1aa596c374c49fa3135f04648a0caabcb66c52884b943f02b4", size = 36393132, upload_time = "2025-05-08T16:08:15.34Z" }, + { url = "https://files.pythonhosted.org/packages/10/7e/5c12285452970be5bdbe8352c619250b97ebf7917d7a9a9e96b8a8140f17/scipy-1.15.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5e721fed53187e71d0ccf382b6bf977644c533e506c4d33c3fb24de89f5c3ed5", size = 38979503, upload_time = "2025-05-08T16:08:21.513Z" }, + { url = "https://files.pythonhosted.org/packages/81/06/0a5e5349474e1cbc5757975b21bd4fad0e72ebf138c5592f191646154e06/scipy-1.15.3-cp313-cp313t-win_amd64.whl", hash = "sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca", size = 40308097, upload_time = "2025-05-08T16:08:27.627Z" }, ] [[package]] -name = "rich" -version = "13.8.1" +name = "scipy" +version = "1.16.0" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", + "python_full_version >= '3.13'", +] dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/92/76/40f084cb7db51c9d1fa29a7120717892aeda9a7711f6225692c957a93535/rich-13.8.1.tar.gz", hash = "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a", size = 222080 } +sdist = { url = "https://files.pythonhosted.org/packages/81/18/b06a83f0c5ee8cddbde5e3f3d0bb9b702abfa5136ef6d4620ff67df7eee5/scipy-1.16.0.tar.gz", hash = "sha256:b5ef54021e832869c8cfb03bc3bf20366cbcd426e02a58e8a58d7584dfbb8f62", size = 30581216, upload_time = "2025-06-22T16:27:55.782Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/11/dadb85e2bd6b1f1ae56669c3e1f0410797f9605d752d68fb47b77f525b31/rich-13.8.1-py3-none-any.whl", hash = "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06", size = 241608 }, + { url = "https://files.pythonhosted.org/packages/d9/f8/53fc4884df6b88afd5f5f00240bdc49fee2999c7eff3acf5953eb15bc6f8/scipy-1.16.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:deec06d831b8f6b5fb0b652433be6a09db29e996368ce5911faf673e78d20085", size = 36447362, upload_time = "2025-06-22T16:18:17.817Z" }, + { url = "https://files.pythonhosted.org/packages/c9/25/fad8aa228fa828705142a275fc593d701b1817c98361a2d6b526167d07bc/scipy-1.16.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d30c0fe579bb901c61ab4bb7f3eeb7281f0d4c4a7b52dbf563c89da4fd2949be", size = 28547120, upload_time = "2025-06-22T16:18:24.117Z" }, + { url = "https://files.pythonhosted.org/packages/8d/be/d324ddf6b89fd1c32fecc307f04d095ce84abb52d2e88fab29d0cd8dc7a8/scipy-1.16.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:b2243561b45257f7391d0f49972fca90d46b79b8dbcb9b2cb0f9df928d370ad4", size = 20818922, upload_time = "2025-06-22T16:18:28.035Z" }, + { url = "https://files.pythonhosted.org/packages/cd/e0/cf3f39e399ac83fd0f3ba81ccc5438baba7cfe02176be0da55ff3396f126/scipy-1.16.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:e6d7dfc148135e9712d87c5f7e4f2ddc1304d1582cb3a7d698bbadedb61c7afd", size = 23409695, upload_time = "2025-06-22T16:18:32.497Z" }, + { url = "https://files.pythonhosted.org/packages/5b/61/d92714489c511d3ffd6830ac0eb7f74f243679119eed8b9048e56b9525a1/scipy-1.16.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:90452f6a9f3fe5a2cf3748e7be14f9cc7d9b124dce19667b54f5b429d680d539", size = 33444586, upload_time = "2025-06-22T16:18:37.992Z" }, + { url = "https://files.pythonhosted.org/packages/af/2c/40108915fd340c830aee332bb85a9160f99e90893e58008b659b9f3dddc0/scipy-1.16.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a2f0bf2f58031c8701a8b601df41701d2a7be17c7ffac0a4816aeba89c4cdac8", size = 35284126, upload_time = "2025-06-22T16:18:43.605Z" }, + { url = "https://files.pythonhosted.org/packages/d3/30/e9eb0ad3d0858df35d6c703cba0a7e16a18a56a9e6b211d861fc6f261c5f/scipy-1.16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c4abb4c11fc0b857474241b812ce69ffa6464b4bd8f4ecb786cf240367a36a7", size = 35608257, upload_time = "2025-06-22T16:18:49.09Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ff/950ee3e0d612b375110d8cda211c1f787764b4c75e418a4b71f4a5b1e07f/scipy-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b370f8f6ac6ef99815b0d5c9f02e7ade77b33007d74802efc8316c8db98fd11e", size = 38040541, upload_time = "2025-06-22T16:18:55.077Z" }, + { url = "https://files.pythonhosted.org/packages/8b/c9/750d34788288d64ffbc94fdb4562f40f609d3f5ef27ab4f3a4ad00c9033e/scipy-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:a16ba90847249bedce8aa404a83fb8334b825ec4a8e742ce6012a7a5e639f95c", size = 38570814, upload_time = "2025-06-22T16:19:00.912Z" }, + { url = "https://files.pythonhosted.org/packages/01/c0/c943bc8d2bbd28123ad0f4f1eef62525fa1723e84d136b32965dcb6bad3a/scipy-1.16.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:7eb6bd33cef4afb9fa5f1fb25df8feeb1e52d94f21a44f1d17805b41b1da3180", size = 36459071, upload_time = "2025-06-22T16:19:06.605Z" }, + { url = "https://files.pythonhosted.org/packages/99/0d/270e2e9f1a4db6ffbf84c9a0b648499842046e4e0d9b2275d150711b3aba/scipy-1.16.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:1dbc8fdba23e4d80394ddfab7a56808e3e6489176d559c6c71935b11a2d59db1", size = 28490500, upload_time = "2025-06-22T16:19:11.775Z" }, + { url = "https://files.pythonhosted.org/packages/1c/22/01d7ddb07cff937d4326198ec8d10831367a708c3da72dfd9b7ceaf13028/scipy-1.16.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:7dcf42c380e1e3737b343dec21095c9a9ad3f9cbe06f9c05830b44b1786c9e90", size = 20762345, upload_time = "2025-06-22T16:19:15.813Z" }, + { url = "https://files.pythonhosted.org/packages/34/7f/87fd69856569ccdd2a5873fe5d7b5bbf2ad9289d7311d6a3605ebde3a94b/scipy-1.16.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:26ec28675f4a9d41587266084c626b02899db373717d9312fa96ab17ca1ae94d", size = 23418563, upload_time = "2025-06-22T16:19:20.746Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f1/e4f4324fef7f54160ab749efbab6a4bf43678a9eb2e9817ed71a0a2fd8de/scipy-1.16.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:952358b7e58bd3197cfbd2f2f2ba829f258404bdf5db59514b515a8fe7a36c52", size = 33203951, upload_time = "2025-06-22T16:19:25.813Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f0/b6ac354a956384fd8abee2debbb624648125b298f2c4a7b4f0d6248048a5/scipy-1.16.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03931b4e870c6fef5b5c0970d52c9f6ddd8c8d3e934a98f09308377eba6f3824", size = 35070225, upload_time = "2025-06-22T16:19:31.416Z" }, + { url = "https://files.pythonhosted.org/packages/e5/73/5cbe4a3fd4bc3e2d67ffad02c88b83edc88f381b73ab982f48f3df1a7790/scipy-1.16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:512c4f4f85912767c351a0306824ccca6fd91307a9f4318efe8fdbd9d30562ef", size = 35389070, upload_time = "2025-06-22T16:19:37.387Z" }, + { url = "https://files.pythonhosted.org/packages/86/e8/a60da80ab9ed68b31ea5a9c6dfd3c2f199347429f229bf7f939a90d96383/scipy-1.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e69f798847e9add03d512eaf5081a9a5c9a98757d12e52e6186ed9681247a1ac", size = 37825287, upload_time = "2025-06-22T16:19:43.375Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b5/29fece1a74c6a94247f8a6fb93f5b28b533338e9c34fdcc9cfe7a939a767/scipy-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:adf9b1999323ba335adc5d1dc7add4781cb5a4b0ef1e98b79768c05c796c4e49", size = 38431929, upload_time = "2025-06-22T16:19:49.385Z" }, + { url = "https://files.pythonhosted.org/packages/46/95/0746417bc24be0c2a7b7563946d61f670a3b491b76adede420e9d173841f/scipy-1.16.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:e9f414cbe9ca289a73e0cc92e33a6a791469b6619c240aa32ee18abdce8ab451", size = 36418162, upload_time = "2025-06-22T16:19:56.3Z" }, + { url = "https://files.pythonhosted.org/packages/19/5a/914355a74481b8e4bbccf67259bbde171348a3f160b67b4945fbc5f5c1e5/scipy-1.16.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:bbba55fb97ba3cdef9b1ee973f06b09d518c0c7c66a009c729c7d1592be1935e", size = 28465985, upload_time = "2025-06-22T16:20:01.238Z" }, + { url = "https://files.pythonhosted.org/packages/58/46/63477fc1246063855969cbefdcee8c648ba4b17f67370bd542ba56368d0b/scipy-1.16.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:58e0d4354eacb6004e7aa1cd350e5514bd0270acaa8d5b36c0627bb3bb486974", size = 20737961, upload_time = "2025-06-22T16:20:05.913Z" }, + { url = "https://files.pythonhosted.org/packages/93/86/0fbb5588b73555e40f9d3d6dde24ee6fac7d8e301a27f6f0cab9d8f66ff2/scipy-1.16.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:75b2094ec975c80efc273567436e16bb794660509c12c6a31eb5c195cbf4b6dc", size = 23377941, upload_time = "2025-06-22T16:20:10.668Z" }, + { url = "https://files.pythonhosted.org/packages/ca/80/a561f2bf4c2da89fa631b3cbf31d120e21ea95db71fd9ec00cb0247c7a93/scipy-1.16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b65d232157a380fdd11a560e7e21cde34fdb69d65c09cb87f6cc024ee376351", size = 33196703, upload_time = "2025-06-22T16:20:16.097Z" }, + { url = "https://files.pythonhosted.org/packages/11/6b/3443abcd0707d52e48eb315e33cc669a95e29fc102229919646f5a501171/scipy-1.16.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d8747f7736accd39289943f7fe53a8333be7f15a82eea08e4afe47d79568c32", size = 35083410, upload_time = "2025-06-22T16:20:21.734Z" }, + { url = "https://files.pythonhosted.org/packages/20/ab/eb0fc00e1e48961f1bd69b7ad7e7266896fe5bad4ead91b5fc6b3561bba4/scipy-1.16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb9f147a1b8529bb7fec2a85cf4cf42bdfadf9e83535c309a11fdae598c88e8b", size = 35387829, upload_time = "2025-06-22T16:20:27.548Z" }, + { url = "https://files.pythonhosted.org/packages/57/9e/d6fc64e41fad5d481c029ee5a49eefc17f0b8071d636a02ceee44d4a0de2/scipy-1.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d2b83c37edbfa837a8923d19c749c1935ad3d41cf196006a24ed44dba2ec4358", size = 37841356, upload_time = "2025-06-22T16:20:35.112Z" }, + { url = "https://files.pythonhosted.org/packages/7c/a7/4c94bbe91f12126b8bf6709b2471900577b7373a4fd1f431f28ba6f81115/scipy-1.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:79a3c13d43c95aa80b87328a46031cf52508cf5f4df2767602c984ed1d3c6bbe", size = 38403710, upload_time = "2025-06-22T16:21:54.473Z" }, + { url = "https://files.pythonhosted.org/packages/47/20/965da8497f6226e8fa90ad3447b82ed0e28d942532e92dd8b91b43f100d4/scipy-1.16.0-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:f91b87e1689f0370690e8470916fe1b2308e5b2061317ff76977c8f836452a47", size = 36813833, upload_time = "2025-06-22T16:20:43.925Z" }, + { url = "https://files.pythonhosted.org/packages/28/f4/197580c3dac2d234e948806e164601c2df6f0078ed9f5ad4a62685b7c331/scipy-1.16.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:88a6ca658fb94640079e7a50b2ad3b67e33ef0f40e70bdb7dc22017dae73ac08", size = 28974431, upload_time = "2025-06-22T16:20:51.302Z" }, + { url = "https://files.pythonhosted.org/packages/8a/fc/e18b8550048d9224426e76906694c60028dbdb65d28b1372b5503914b89d/scipy-1.16.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:ae902626972f1bd7e4e86f58fd72322d7f4ec7b0cfc17b15d4b7006efc385176", size = 21246454, upload_time = "2025-06-22T16:20:57.276Z" }, + { url = "https://files.pythonhosted.org/packages/8c/48/07b97d167e0d6a324bfd7484cd0c209cc27338b67e5deadae578cf48e809/scipy-1.16.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:8cb824c1fc75ef29893bc32b3ddd7b11cf9ab13c1127fe26413a05953b8c32ed", size = 23772979, upload_time = "2025-06-22T16:21:03.363Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4f/9efbd3f70baf9582edf271db3002b7882c875ddd37dc97f0f675ad68679f/scipy-1.16.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:de2db7250ff6514366a9709c2cba35cb6d08498e961cba20d7cff98a7ee88938", size = 33341972, upload_time = "2025-06-22T16:21:11.14Z" }, + { url = "https://files.pythonhosted.org/packages/3f/dc/9e496a3c5dbe24e76ee24525155ab7f659c20180bab058ef2c5fa7d9119c/scipy-1.16.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e85800274edf4db8dd2e4e93034f92d1b05c9421220e7ded9988b16976f849c1", size = 35185476, upload_time = "2025-06-22T16:21:19.156Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b3/21001cff985a122ba434c33f2c9d7d1dc3b669827e94f4fc4e1fe8b9dfd8/scipy-1.16.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4f720300a3024c237ace1cb11f9a84c38beb19616ba7c4cdcd771047a10a1706", size = 35570990, upload_time = "2025-06-22T16:21:27.797Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d3/7ba42647d6709251cdf97043d0c107e0317e152fa2f76873b656b509ff55/scipy-1.16.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:aad603e9339ddb676409b104c48a027e9916ce0d2838830691f39552b38a352e", size = 37950262, upload_time = "2025-06-22T16:21:36.976Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c4/231cac7a8385394ebbbb4f1ca662203e9d8c332825ab4f36ffc3ead09a42/scipy-1.16.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f56296fefca67ba605fd74d12f7bd23636267731a72cb3947963e76b8c0a25db", size = 38515076, upload_time = "2025-06-22T16:21:45.694Z" }, ] [[package]] -name = "ruff" -version = "0.6.7" +name = "sentence-transformers" +version = "5.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8d/7c/3045a526c57cef4b5ec4d5d154692e31429749a49810a53e785de334c4f6/ruff-0.6.7.tar.gz", hash = "sha256:44e52129d82266fa59b587e2cd74def5637b730a69c4542525dfdecfaae38bd5", size = 3073785 } +dependencies = [ + { name = "huggingface-hub" }, + { name = "pillow" }, + { name = "scikit-learn" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "scipy", version = "1.16.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "torch" }, + { name = "tqdm" }, + { name = "transformers" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/99/69/2a29773b43a24ee04eb26af492d85d520b30a86cfef22a0885e77e9c4a16/sentence_transformers-5.0.0.tar.gz", hash = "sha256:e5a411845910275fd166bacb01d28b7f79537d3550628ae42309dbdd3d5670d1", size = 366847, upload_time = "2025-07-01T13:01:33.04Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/c4/1c5c636f83f905c537785016e9cdd7a36df53c025a2d07940580ecb37bcf/ruff-0.6.7-py3-none-linux_armv6l.whl", hash = "sha256:08277b217534bfdcc2e1377f7f933e1c7957453e8a79764d004e44c40db923f2", size = 10336748 }, - { url = "https://files.pythonhosted.org/packages/84/d9/aa15a56be7ad796f4d7625362aff588f9fc013bbb7323a63571628a2cf2d/ruff-0.6.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c6707a32e03b791f4448dc0dce24b636cbcdee4dd5607adc24e5ee73fd86c00a", size = 9958833 }, - { url = "https://files.pythonhosted.org/packages/27/25/5dd1c32bfc3ad3136c8ebe84312d1bdd2e6c908ac7f60692ec009b7050a8/ruff-0.6.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:533d66b7774ef224e7cf91506a7dafcc9e8ec7c059263ec46629e54e7b1f90ab", size = 9633369 }, - { url = "https://files.pythonhosted.org/packages/0e/3e/01b25484f3cb08fe6fddedf1f55f3f3c0af861a5b5f5082fbe60ab4b2596/ruff-0.6.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17a86aac6f915932d259f7bec79173e356165518859f94649d8c50b81ff087e9", size = 10637415 }, - { url = "https://files.pythonhosted.org/packages/8a/c9/5bb9b849e4777e0f961de43edf95d2af0ab34999a5feee957be096887876/ruff-0.6.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3f8822defd260ae2460ea3832b24d37d203c3577f48b055590a426a722d50ef", size = 10097389 }, - { url = "https://files.pythonhosted.org/packages/52/cf/e08f1c290c7d848ddfb2ae811f24f445c18e1d3e50e01c38ffa7f5a50494/ruff-0.6.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ba4efe5c6dbbb58be58dd83feedb83b5e95c00091bf09987b4baf510fee5c99", size = 10951440 }, - { url = "https://files.pythonhosted.org/packages/a2/2d/ca8aa0da5841913c302d8034c6de0ce56c401c685184d8dd23cfdd0003f9/ruff-0.6.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:525201b77f94d2b54868f0cbe5edc018e64c22563da6c5c2e5c107a4e85c1c0d", size = 11708900 }, - { url = "https://files.pythonhosted.org/packages/89/fc/9a83c57baee977c82392e19a328b52cebdaf61601af3d99498e278ef5104/ruff-0.6.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8854450839f339e1049fdbe15d875384242b8e85d5c6947bb2faad33c651020b", size = 11258892 }, - { url = "https://files.pythonhosted.org/packages/d3/a3/254cc7afef702c68ae9079290c2a1477ae0e81478589baf745026d8a4eb5/ruff-0.6.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f0b62056246234d59cbf2ea66e84812dc9ec4540518e37553513392c171cb18", size = 12367932 }, - { url = "https://files.pythonhosted.org/packages/9f/55/53f10c1bd8c3b2ae79aed18e62b22c6346f9296aa0ec80489b8442bd06a9/ruff-0.6.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b1462fa56c832dc0cea5b4041cfc9c97813505d11cce74ebc6d1aae068de36b", size = 10838629 }, - { url = "https://files.pythonhosted.org/packages/84/72/fb335c2b25432c63d15383ecbd7bfc1915e68cdf8d086a08042052144255/ruff-0.6.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:02b083770e4cdb1495ed313f5694c62808e71764ec6ee5db84eedd82fd32d8f5", size = 10648824 }, - { url = "https://files.pythonhosted.org/packages/92/a8/d57e135a8ad99b6a0c6e2a5c590bcacdd57f44340174f4409c3893368610/ruff-0.6.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c05fd37013de36dfa883a3854fae57b3113aaa8abf5dea79202675991d48624", size = 10174368 }, - { url = "https://files.pythonhosted.org/packages/a7/6f/1a30a6e81dcf2fa9ff3f7011eb87fe76c12a3c6bba74db6a1977d763de1f/ruff-0.6.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f49c9caa28d9bbfac4a637ae10327b3db00f47d038f3fbb2195c4d682e925b14", size = 10514383 }, - { url = "https://files.pythonhosted.org/packages/0b/25/df6f2575bc9fe43a6dedfd8dee12896f09a94303e2c828d5f85856bb69a0/ruff-0.6.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a0e1655868164e114ba43a908fd2d64a271a23660195017c17691fb6355d59bb", size = 10902340 }, - { url = "https://files.pythonhosted.org/packages/68/62/f2c1031e2fb7b94f9bf0603744e73db4ef90081b0eb1b9639a6feefd52ea/ruff-0.6.7-py3-none-win32.whl", hash = "sha256:a939ca435b49f6966a7dd64b765c9df16f1faed0ca3b6f16acdf7731969deb35", size = 8448033 }, - { url = "https://files.pythonhosted.org/packages/97/80/193d1604a3f7d75eb1b2a7ce6bf0fdbdbc136889a65caacea6ffb29501b1/ruff-0.6.7-py3-none-win_amd64.whl", hash = "sha256:590445eec5653f36248584579c06252ad2e110a5d1f32db5420de35fb0e1c977", size = 9273543 }, - { url = "https://files.pythonhosted.org/packages/8e/a8/4abb5a9f58f51e4b1ea386be5ab2e547035bc1ee57200d1eca2f8909a33e/ruff-0.6.7-py3-none-win_arm64.whl", hash = "sha256:b28f0d5e2f771c1fe3c7a45d3f53916fc74a480698c4b5731f0bea61e52137c8", size = 8618044 }, + { url = "https://files.pythonhosted.org/packages/6f/ff/178f08ea5ebc1f9193d9de7f601efe78c01748347875c8438f66f5cecc19/sentence_transformers-5.0.0-py3-none-any.whl", hash = "sha256:346240f9cc6b01af387393f03e103998190dfb0826a399d0c38a81a05c7a5d76", size = 470191, upload_time = "2025-07-01T13:01:31.619Z" }, ] [[package]] @@ -1236,9 +3999,9 @@ dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c8/28/02c0cd9184f9108e3c52519f9628b215077a3854240e0b17ae845e664855/sentry_sdk-1.45.1.tar.gz", hash = "sha256:a16c997c0f4e3df63c0fc5e4207ccb1ab37900433e0f72fef88315d317829a26", size = 244774 } +sdist = { url = "https://files.pythonhosted.org/packages/c8/28/02c0cd9184f9108e3c52519f9628b215077a3854240e0b17ae845e664855/sentry_sdk-1.45.1.tar.gz", hash = "sha256:a16c997c0f4e3df63c0fc5e4207ccb1ab37900433e0f72fef88315d317829a26", size = 244774, upload_time = "2024-07-26T13:48:32.375Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/9f/105366a122efa93f0cb1914f841747d160788e4d022d0488d2d44c2ba26c/sentry_sdk-1.45.1-py2.py3-none-any.whl", hash = "sha256:608887855ccfe39032bfd03936e3a1c4f4fc99b3a4ac49ced54a4220de61c9c1", size = 267163 }, + { url = "https://files.pythonhosted.org/packages/fe/9f/105366a122efa93f0cb1914f841747d160788e4d022d0488d2d44c2ba26c/sentry_sdk-1.45.1-py2.py3-none-any.whl", hash = "sha256:608887855ccfe39032bfd03936e3a1c4f4fc99b3a4ac49ced54a4220de61c9c1", size = 267163, upload_time = "2024-07-26T13:48:29.38Z" }, ] [package.optional-dependencies] @@ -1246,31 +4009,137 @@ fastapi = [ { name = "fastapi" }, ] +[[package]] +name = "setuptools" +version = "80.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload_time = "2025-05-27T00:56:51.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload_time = "2025-05-27T00:56:49.664Z" }, +] + [[package]] name = "shellingham" version = "1.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload_time = "2023-10-24T04:13:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload_time = "2023-10-24T04:13:38.866Z" }, ] [[package]] name = "six" version = "1.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041, upload_time = "2021-05-05T14:18:18.379Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053, upload_time = "2021-05-05T14:18:17.237Z" }, +] + +[[package]] +name = "smart-open" +version = "7.3.0.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/2b/5e7234c68ed5bc872ad6ae77b8a421c2ed70dcb1190b44dc1abdeed5e347/smart_open-7.3.0.post1.tar.gz", hash = "sha256:ce6a3d9bc1afbf6234ad13c010b77f8cd36d24636811e3c52c3b5160f5214d1e", size = 51557, upload_time = "2025-07-03T10:06:31.271Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, + { url = "https://files.pythonhosted.org/packages/08/5b/a2a3d4514c64818925f4e886d39981f1926eeb5288a4549c6b3c17ed66bb/smart_open-7.3.0.post1-py3-none-any.whl", hash = "sha256:c73661a2c24bf045c1e04e08fffc585b59af023fe783d57896f590489db66fb4", size = 61946, upload_time = "2025-07-03T10:06:29.599Z" }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload_time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload_time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "soupsieve" +version = "2.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload_time = "2025-04-20T18:50:08.518Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload_time = "2025-04-20T18:50:07.196Z" }, +] + +[[package]] +name = "spacy" +version = "3.8.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "catalogue" }, + { name = "cymem" }, + { name = "jinja2" }, + { name = "langcodes" }, + { name = "murmurhash" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "packaging" }, + { name = "preshed" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "setuptools" }, + { name = "spacy-legacy" }, + { name = "spacy-loggers" }, + { name = "srsly" }, + { name = "thinc" }, + { name = "tqdm" }, + { name = "typer" }, + { name = "wasabi" }, + { name = "weasel" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1e/9e/fb4e1cefe3fbd51ea6a243e5a3d2bc629baa9a28930bf4be6fe5672fa1ca/spacy-3.8.7.tar.gz", hash = "sha256:700fd174c6c552276be142c48e70bb53cae24c4dd86003c4432af9cb93e4c908", size = 1316143, upload_time = "2025-05-23T08:55:39.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/2c/bbba614290492c169ee50777e44d3e4325a1e646272379988de8749b9dd4/spacy-3.8.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6ec0368ce96cd775fb14906f04b771c912ea8393ba30f8b35f9c4dc47a420b8e", size = 6613435, upload_time = "2025-05-23T08:54:03.964Z" }, + { url = "https://files.pythonhosted.org/packages/39/a9/c1fdecc11d8855b3df601bbfb5fc4cdb98d79b6a5d166af974354ea658eb/spacy-3.8.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5672f8a0fe7a3847e925544890be60015fbf48a60a838803425f82e849dd4f18", size = 6261550, upload_time = "2025-05-23T08:54:06.984Z" }, + { url = "https://files.pythonhosted.org/packages/39/fe/e8b5a374f2517716f510f0dd6a0b68e88637e66db7c315d4002ba80b2bfe/spacy-3.8.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60cde9fe8b15be04eb1e634c353d9c160187115d825b368cc1975452dd54f264", size = 31215973, upload_time = "2025-05-23T08:54:09.46Z" }, + { url = "https://files.pythonhosted.org/packages/bb/e7/bd1df17add98a5ec3e0d2dd73d4e5884683ffd2e34d3c0e5828f48933787/spacy-3.8.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9cac8e58fb92fb1c5e06328039595fa6589a9d1403681266f8f5e454d15319c", size = 31504596, upload_time = "2025-05-23T08:54:12.684Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fa/5fd95749f390478a31a806500e829c5a8d97312ea18129494d255e231c00/spacy-3.8.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1456245a4ed04bc882db2d89a27ca1b6dc0b947b643bedaeaa5da11d9f7e22ec", size = 30527369, upload_time = "2025-05-23T08:54:15.467Z" }, + { url = "https://files.pythonhosted.org/packages/7a/74/f4708260fc135f8de15eb1d0ecfe00fd7b53f4b1d4927f90a33d48dff637/spacy-3.8.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bb98f85d467963d17c7c660884069ba948bde71c07280c91ee3235e554375308", size = 31357330, upload_time = "2025-05-23T08:54:18.342Z" }, + { url = "https://files.pythonhosted.org/packages/53/a6/3086859d2bfb5b6f97b17e19f51da0983eb11b07f63c24dced6506cdb370/spacy-3.8.7-cp310-cp310-win_amd64.whl", hash = "sha256:b0df50d69e6691e97eae228733b321971607dbbb799e59d8470f2e70b8b27a8e", size = 14929267, upload_time = "2025-05-23T08:54:21.365Z" }, + { url = "https://files.pythonhosted.org/packages/29/c5/5fbb3a4e694d4855a5bab87af9664377c48b89691f180ad3cde4faeaf35c/spacy-3.8.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bdff8b9b556468a6dd527af17f0ddf9fb0b0bee92ee7703339ddf542361cff98", size = 6746140, upload_time = "2025-05-23T08:54:23.483Z" }, + { url = "https://files.pythonhosted.org/packages/03/2a/43afac516eb82409ca47d7206f982beaf265d2ba06a72ca07cf06b290c20/spacy-3.8.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9194b7cf015ed9b4450ffb162da49c8a9305e76b468de036b0948abdfc748a37", size = 6392440, upload_time = "2025-05-23T08:54:25.12Z" }, + { url = "https://files.pythonhosted.org/packages/6f/83/2ea68c18e2b1b9a6f6b30ef63eb9d07e979626b9595acfdb5394f18923c4/spacy-3.8.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7dc38b78d48b9c2a80a3eea95f776304993f63fc307f07cdd104441442f92f1e", size = 32699126, upload_time = "2025-05-23T08:54:27.385Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0a/bb90e9aa0b3c527876627567d82517aabab08006ccf63796c33b0242254d/spacy-3.8.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e43bd70772751b8fc7a14f338d087a3d297195d43d171832923ef66204b23ab", size = 33008865, upload_time = "2025-05-23T08:54:30.248Z" }, + { url = "https://files.pythonhosted.org/packages/39/dd/8e906ba378457107ab0394976ea9f7b12fdb2cad682ef1a2ccf473d61e5f/spacy-3.8.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c402bf5dcf345fd96d202378c54bc345219681e3531f911d99567d569328c45f", size = 31933169, upload_time = "2025-05-23T08:54:33.199Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b5/42df07eb837a923fbb42509864d5c7c2072d010de933dccdfb3c655b3a76/spacy-3.8.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4234189861e486d86f1269e50542d87e8a6391a1ee190652479cf1a793db115f", size = 32776322, upload_time = "2025-05-23T08:54:36.891Z" }, + { url = "https://files.pythonhosted.org/packages/92/e7/8176484801c67dcd814f141991fe0a3c9b5b4a3583ea30c2062e93d1aa6b/spacy-3.8.7-cp311-cp311-win_amd64.whl", hash = "sha256:e9d12e2eb7f36bc11dd9edae011032fe49ea100d63e83177290d3cbd80eaa650", size = 14938936, upload_time = "2025-05-23T08:54:40.322Z" }, + { url = "https://files.pythonhosted.org/packages/a5/10/89852f40f926e0902c11c34454493ba0d15530b322711e754b89a6d7dfe6/spacy-3.8.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:88b397e37793cea51df298e6c651a763e49877a25bead5ba349761531a456687", size = 6265335, upload_time = "2025-05-23T08:54:42.876Z" }, + { url = "https://files.pythonhosted.org/packages/16/fb/b5d54522969a632c06f4af354763467553b66d5bf0671ac39f3cceb3fd54/spacy-3.8.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f70b676955fa6959347ca86ed6edd8ff0d6eb2ba20561fdfec76924bd3e540f9", size = 5906035, upload_time = "2025-05-23T08:54:44.824Z" }, + { url = "https://files.pythonhosted.org/packages/3a/03/70f06753fd65081404ade30408535eb69f627a36ffce2107116d1aa16239/spacy-3.8.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4b5a624797ade30c25b5b69daa35a93ee24bcc56bd79b0884b2565f76f35d6", size = 33420084, upload_time = "2025-05-23T08:54:46.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/19/b60e1ebf4985ee2b33d85705b89a5024942b65dad04dbdc3fb46f168b410/spacy-3.8.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9d83e006df66decccefa3872fa958b3756228fb216d83783595444cf42ca10c", size = 33922188, upload_time = "2025-05-23T08:54:49.781Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a3/1fb1a49dc6d982d96fffc30c3a31bb431526008eea72ac3773f6518720a6/spacy-3.8.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dca25deba54f3eb5dcfbf63bf16e613e6c601da56f91c4a902d38533c098941", size = 31939285, upload_time = "2025-05-23T08:54:53.162Z" }, + { url = "https://files.pythonhosted.org/packages/2d/55/6cf1aff8e5c01ee683e828f3ccd9282d2aff7ca1143a9349ee3d0c1291ff/spacy-3.8.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5eef3f805a1c118d9b709a23e2d378f5f20da5a0d6258c9cfdc87c4cb234b4fc", size = 32988845, upload_time = "2025-05-23T08:54:57.776Z" }, + { url = "https://files.pythonhosted.org/packages/8c/47/c17ee61b51aa8497d8af0999224b4b62485111a55ec105a06886685b2c68/spacy-3.8.7-cp312-cp312-win_amd64.whl", hash = "sha256:25d7a68e445200c9e9dc0044f8b7278ec0ef01ccc7cb5a95d1de2bd8e3ed6be2", size = 13918682, upload_time = "2025-05-23T08:55:00.387Z" }, + { url = "https://files.pythonhosted.org/packages/2a/95/7125bea6d432c601478bf922f7a568762c8be425bbde5b66698260ab0358/spacy-3.8.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dda7d57f42ec57c19fbef348095a9c82504e4777bca7b8db4b0d8318ba280fc7", size = 6235950, upload_time = "2025-05-23T08:55:02.92Z" }, + { url = "https://files.pythonhosted.org/packages/96/c3/d2362846154d4d341136774831605df02d61f49ac637524a15f4f2794874/spacy-3.8.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:de0e0bddb810ed05bce44bcb91460eabe52bc56323da398d2ca74288a906da35", size = 5878106, upload_time = "2025-05-23T08:55:04.496Z" }, + { url = "https://files.pythonhosted.org/packages/50/b6/b2943acfbfc4fc12642dac9feb571e712dd1569ab481db8f3daedee045fe/spacy-3.8.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a2e58f92b684465777a7c1a65d5578b1dc36fe55c48d9964fb6d46cc9449768", size = 33085866, upload_time = "2025-05-23T08:55:06.65Z" }, + { url = "https://files.pythonhosted.org/packages/65/98/c4415cbb217ac0b502dbb3372136015c699dd16a0c47cd6d338cd15f4bed/spacy-3.8.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46330da2eb357d6979f40ea8fc16ee5776ee75cd0c70aac2a4ea10c80364b8f3", size = 33398424, upload_time = "2025-05-23T08:55:10.477Z" }, + { url = "https://files.pythonhosted.org/packages/12/45/12a198858f1f11c21844876e039ba90df59d550527c72996d418c1faf78d/spacy-3.8.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:86b6a6ad23ca5440ef9d29c2b1e3125e28722c927db612ae99e564d49202861c", size = 31530066, upload_time = "2025-05-23T08:55:13.329Z" }, + { url = "https://files.pythonhosted.org/packages/9c/df/80524f99822eb96c9649200042ec5912357eec100cf0cd678a2e9ef0ecb3/spacy-3.8.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ccfe468cbb370888153df145ce3693af8e54dae551940df49057258081b2112f", size = 32613343, upload_time = "2025-05-23T08:55:16.711Z" }, + { url = "https://files.pythonhosted.org/packages/02/99/881f6f24c279a5a70b8d69aaf8266fd411a0a58fd1c8848112aaa348f6f6/spacy-3.8.7-cp313-cp313-win_amd64.whl", hash = "sha256:ca81e416ff35209769e8b5dd5d13acc52e4f57dd9d028364bccbbe157c2ae86b", size = 13911250, upload_time = "2025-05-23T08:55:19.606Z" }, +] + +[[package]] +name = "spacy-legacy" +version = "3.0.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d9/79/91f9d7cc8db5642acad830dcc4b49ba65a7790152832c4eceb305e46d681/spacy-legacy-3.0.12.tar.gz", hash = "sha256:b37d6e0c9b6e1d7ca1cf5bc7152ab64a4c4671f59c85adaf7a3fcb870357a774", size = 23806, upload_time = "2023-01-23T09:04:15.104Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/55/12e842c70ff8828e34e543a2c7176dac4da006ca6901c9e8b43efab8bc6b/spacy_legacy-3.0.12-py2.py3-none-any.whl", hash = "sha256:476e3bd0d05f8c339ed60f40986c07387c0a71479245d6d0f4298dbd52cda55f", size = 29971, upload_time = "2023-01-23T09:04:13.45Z" }, +] + +[[package]] +name = "spacy-loggers" +version = "1.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/67/3d/926db774c9c98acf66cb4ed7faf6c377746f3e00b84b700d0868b95d0712/spacy-loggers-1.0.5.tar.gz", hash = "sha256:d60b0bdbf915a60e516cc2e653baeff946f0cfc461b452d11a4d5458c6fe5f24", size = 20811, upload_time = "2023-09-11T12:26:52.323Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + { url = "https://files.pythonhosted.org/packages/33/78/d1a1a026ef3af911159398c939b1509d5c36fe524c7b644f34a5146c4e16/spacy_loggers-1.0.5-py3-none-any.whl", hash = "sha256:196284c9c446cc0cdb944005384270d775fdeaf4f494d8e269466cfa497ef645", size = 22343, upload_time = "2023-09-11T12:26:50.586Z" }, ] [[package]] @@ -1281,33 +4150,33 @@ dependencies = [ { name = "greenlet", marker = "(python_full_version < '3.13' and platform_machine == 'AMD64') or (python_full_version < '3.13' and platform_machine == 'WIN32') or (python_full_version < '3.13' and platform_machine == 'aarch64') or (python_full_version < '3.13' and platform_machine == 'amd64') or (python_full_version < '3.13' and platform_machine == 'ppc64le') or (python_full_version < '3.13' and platform_machine == 'win32') or (python_full_version < '3.13' and platform_machine == 'x86_64')" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/36/48/4f190a83525f5cefefa44f6adc9e6386c4de5218d686c27eda92eb1f5424/sqlalchemy-2.0.35.tar.gz", hash = "sha256:e11d7ea4d24f0a262bccf9a7cd6284c976c5369dac21db237cff59586045ab9f", size = 9562798 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1a/61/19395d0ae78c94f6f80c8adf39a142f3fe56cfb2235d8f2317d6dae1bf0e/SQLAlchemy-2.0.35-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:67219632be22f14750f0d1c70e62f204ba69d28f62fd6432ba05ab295853de9b", size = 2090086 }, - { url = "https://files.pythonhosted.org/packages/e6/82/06b5fcbe5d49043e40cf4e01e3b33c471c8d9292d478420b08538cae8928/SQLAlchemy-2.0.35-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4668bd8faf7e5b71c0319407b608f278f279668f358857dbfd10ef1954ac9f90", size = 2081278 }, - { url = "https://files.pythonhosted.org/packages/68/d1/7fb7ee46949a5fb34005795b1fc06a8fef67587a66da731c14e545f7eb5b/SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb8bea573863762bbf45d1e13f87c2d2fd32cee2dbd50d050f83f87429c9e1ea", size = 3063763 }, - { url = "https://files.pythonhosted.org/packages/7e/ff/a1eacd78b31e52a5073e9924fb4722ecc2a72f093ca8181ed81fc61aed2e/SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f552023710d4b93d8fb29a91fadf97de89c5926c6bd758897875435f2a939f33", size = 3072032 }, - { url = "https://files.pythonhosted.org/packages/21/ae/ddfecf149a6d16af87408bca7bd108eef7ef23d376cc8464317efb3cea3f/SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:016b2e665f778f13d3c438651dd4de244214b527a275e0acf1d44c05bc6026a9", size = 3028092 }, - { url = "https://files.pythonhosted.org/packages/cc/51/3e84d42121662a160bacd311cfacb29c1e6a229d59dd8edb09caa8ab283b/SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7befc148de64b6060937231cbff8d01ccf0bfd75aa26383ffdf8d82b12ec04ff", size = 3053543 }, - { url = "https://files.pythonhosted.org/packages/3e/7a/039c78105958da3fc361887f0a82c974cb6fa5bba965c1689ec778be1c01/SQLAlchemy-2.0.35-cp310-cp310-win32.whl", hash = "sha256:22b83aed390e3099584b839b93f80a0f4a95ee7f48270c97c90acd40ee646f0b", size = 2062372 }, - { url = "https://files.pythonhosted.org/packages/a2/50/f31e927d32f9729f69d150ffe47e7cf51e3e0bb2148fc400b3e93a92ca4c/SQLAlchemy-2.0.35-cp310-cp310-win_amd64.whl", hash = "sha256:a29762cd3d116585278ffb2e5b8cc311fb095ea278b96feef28d0b423154858e", size = 2086485 }, - { url = "https://files.pythonhosted.org/packages/c3/46/9215a35bf98c3a2528e987791e6180eb51624d2c7d5cb8e2d96a6450b657/SQLAlchemy-2.0.35-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e21f66748ab725ade40fa7af8ec8b5019c68ab00b929f6643e1b1af461eddb60", size = 2091274 }, - { url = "https://files.pythonhosted.org/packages/1e/69/919673c5101a0c633658d58b11b454b251ca82300941fba801201434755d/SQLAlchemy-2.0.35-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8a6219108a15fc6d24de499d0d515c7235c617b2540d97116b663dade1a54d62", size = 2081672 }, - { url = "https://files.pythonhosted.org/packages/67/ea/a6b0597cbda12796be2302153369dbbe90573fdab3bc4885f8efac499247/SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:042622a5306c23b972192283f4e22372da3b8ddf5f7aac1cc5d9c9b222ab3ff6", size = 3200083 }, - { url = "https://files.pythonhosted.org/packages/8c/d6/97bdc8d714fb21762f2092511f380f18cdb2d985d516071fa925bb433a90/SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:627dee0c280eea91aed87b20a1f849e9ae2fe719d52cbf847c0e0ea34464b3f7", size = 3200080 }, - { url = "https://files.pythonhosted.org/packages/87/d2/8c2adaf2ade4f6f1b725acd0b0be9210bb6a2df41024729a8eec6a86fe5a/SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4fdcd72a789c1c31ed242fd8c1bcd9ea186a98ee8e5408a50e610edfef980d71", size = 3137108 }, - { url = "https://files.pythonhosted.org/packages/7e/ae/ea05d0bfa8f2b25ae34591895147152854fc950f491c4ce362ae06035db8/SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:89b64cd8898a3a6f642db4eb7b26d1b28a497d4022eccd7717ca066823e9fb01", size = 3157437 }, - { url = "https://files.pythonhosted.org/packages/fe/5d/8ad6df01398388a766163d27960b3365f1bbd8bb7b05b5cad321a8b69b25/SQLAlchemy-2.0.35-cp311-cp311-win32.whl", hash = "sha256:6a93c5a0dfe8d34951e8a6f499a9479ffb9258123551fa007fc708ae2ac2bc5e", size = 2061935 }, - { url = "https://files.pythonhosted.org/packages/ff/68/8557efc0c32c8e2c147cb6512237448b8ed594a57cd015fda67f8e56bb3f/SQLAlchemy-2.0.35-cp311-cp311-win_amd64.whl", hash = "sha256:c68fe3fcde03920c46697585620135b4ecfdfc1ed23e75cc2c2ae9f8502c10b8", size = 2087281 }, - { url = "https://files.pythonhosted.org/packages/2f/2b/fff87e6db0da31212c98bbc445f83fb608ea92b96bda3f3f10e373bac76c/SQLAlchemy-2.0.35-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eb60b026d8ad0c97917cb81d3662d0b39b8ff1335e3fabb24984c6acd0c900a2", size = 2089790 }, - { url = "https://files.pythonhosted.org/packages/68/92/4bb761bd82764d5827bf6b6095168c40fb5dbbd23670203aef2f96ba6bc6/SQLAlchemy-2.0.35-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6921ee01caf375363be5e9ae70d08ce7ca9d7e0e8983183080211a062d299468", size = 2080266 }, - { url = "https://files.pythonhosted.org/packages/22/46/068a65db6dc253c6f25a7598d99e0a1d60b14f661f9d09ef6c73c718fa4e/SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cdf1a0dbe5ced887a9b127da4ffd7354e9c1a3b9bb330dce84df6b70ccb3a8d", size = 3229760 }, - { url = "https://files.pythonhosted.org/packages/6e/36/59830dafe40dda592304debd4cd86e583f63472f3a62c9e2695a5795e786/SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93a71c8601e823236ac0e5d087e4f397874a421017b3318fd92c0b14acf2b6db", size = 3240649 }, - { url = "https://files.pythonhosted.org/packages/00/50/844c50c6996f9c7f000c959dd1a7436a6c94e449ee113046a1d19e470089/SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e04b622bb8a88f10e439084486f2f6349bf4d50605ac3e445869c7ea5cf0fa8c", size = 3176138 }, - { url = "https://files.pythonhosted.org/packages/df/d2/336b18cac68eecb67de474fc15c85f13be4e615c6f5bae87ea38c6734ce0/SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1b56961e2d31389aaadf4906d453859f35302b4eb818d34a26fab72596076bb8", size = 3202753 }, - { url = "https://files.pythonhosted.org/packages/f0/f3/ee1e62fabdc10910b5ef720ae08e59bc785f26652876af3a50b89b97b412/SQLAlchemy-2.0.35-cp312-cp312-win32.whl", hash = "sha256:0f9f3f9a3763b9c4deb8c5d09c4cc52ffe49f9876af41cc1b2ad0138878453cf", size = 2060113 }, - { url = "https://files.pythonhosted.org/packages/60/63/a3cef44a52979169d884f3583d0640e64b3c28122c096474a1d7cfcaf1f3/SQLAlchemy-2.0.35-cp312-cp312-win_amd64.whl", hash = "sha256:25b0f63e7fcc2a6290cb5f7f5b4fc4047843504983a28856ce9b35d8f7de03cc", size = 2085839 }, - { url = "https://files.pythonhosted.org/packages/0e/c6/33c706449cdd92b1b6d756b247761e27d32230fd6b2de5f44c4c3e5632b2/SQLAlchemy-2.0.35-py3-none-any.whl", hash = "sha256:2ab3f0336c0387662ce6221ad30ab3a5e6499aab01b9790879b6578fd9b8faa1", size = 1881276 }, +sdist = { url = "https://files.pythonhosted.org/packages/36/48/4f190a83525f5cefefa44f6adc9e6386c4de5218d686c27eda92eb1f5424/sqlalchemy-2.0.35.tar.gz", hash = "sha256:e11d7ea4d24f0a262bccf9a7cd6284c976c5369dac21db237cff59586045ab9f", size = 9562798, upload_time = "2024-09-16T20:30:05.964Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/61/19395d0ae78c94f6f80c8adf39a142f3fe56cfb2235d8f2317d6dae1bf0e/SQLAlchemy-2.0.35-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:67219632be22f14750f0d1c70e62f204ba69d28f62fd6432ba05ab295853de9b", size = 2090086, upload_time = "2024-09-16T21:29:05.376Z" }, + { url = "https://files.pythonhosted.org/packages/e6/82/06b5fcbe5d49043e40cf4e01e3b33c471c8d9292d478420b08538cae8928/SQLAlchemy-2.0.35-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4668bd8faf7e5b71c0319407b608f278f279668f358857dbfd10ef1954ac9f90", size = 2081278, upload_time = "2024-09-16T21:29:07.224Z" }, + { url = "https://files.pythonhosted.org/packages/68/d1/7fb7ee46949a5fb34005795b1fc06a8fef67587a66da731c14e545f7eb5b/SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb8bea573863762bbf45d1e13f87c2d2fd32cee2dbd50d050f83f87429c9e1ea", size = 3063763, upload_time = "2024-09-17T01:18:12.769Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ff/a1eacd78b31e52a5073e9924fb4722ecc2a72f093ca8181ed81fc61aed2e/SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f552023710d4b93d8fb29a91fadf97de89c5926c6bd758897875435f2a939f33", size = 3072032, upload_time = "2024-09-16T21:23:30.311Z" }, + { url = "https://files.pythonhosted.org/packages/21/ae/ddfecf149a6d16af87408bca7bd108eef7ef23d376cc8464317efb3cea3f/SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:016b2e665f778f13d3c438651dd4de244214b527a275e0acf1d44c05bc6026a9", size = 3028092, upload_time = "2024-09-17T01:18:16.133Z" }, + { url = "https://files.pythonhosted.org/packages/cc/51/3e84d42121662a160bacd311cfacb29c1e6a229d59dd8edb09caa8ab283b/SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7befc148de64b6060937231cbff8d01ccf0bfd75aa26383ffdf8d82b12ec04ff", size = 3053543, upload_time = "2024-09-16T21:23:32.274Z" }, + { url = "https://files.pythonhosted.org/packages/3e/7a/039c78105958da3fc361887f0a82c974cb6fa5bba965c1689ec778be1c01/SQLAlchemy-2.0.35-cp310-cp310-win32.whl", hash = "sha256:22b83aed390e3099584b839b93f80a0f4a95ee7f48270c97c90acd40ee646f0b", size = 2062372, upload_time = "2024-09-16T21:03:04.722Z" }, + { url = "https://files.pythonhosted.org/packages/a2/50/f31e927d32f9729f69d150ffe47e7cf51e3e0bb2148fc400b3e93a92ca4c/SQLAlchemy-2.0.35-cp310-cp310-win_amd64.whl", hash = "sha256:a29762cd3d116585278ffb2e5b8cc311fb095ea278b96feef28d0b423154858e", size = 2086485, upload_time = "2024-09-16T21:03:06.66Z" }, + { url = "https://files.pythonhosted.org/packages/c3/46/9215a35bf98c3a2528e987791e6180eb51624d2c7d5cb8e2d96a6450b657/SQLAlchemy-2.0.35-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e21f66748ab725ade40fa7af8ec8b5019c68ab00b929f6643e1b1af461eddb60", size = 2091274, upload_time = "2024-09-16T21:07:13.344Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/919673c5101a0c633658d58b11b454b251ca82300941fba801201434755d/SQLAlchemy-2.0.35-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8a6219108a15fc6d24de499d0d515c7235c617b2540d97116b663dade1a54d62", size = 2081672, upload_time = "2024-09-16T21:07:14.807Z" }, + { url = "https://files.pythonhosted.org/packages/67/ea/a6b0597cbda12796be2302153369dbbe90573fdab3bc4885f8efac499247/SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:042622a5306c23b972192283f4e22372da3b8ddf5f7aac1cc5d9c9b222ab3ff6", size = 3200083, upload_time = "2024-09-16T22:45:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d6/97bdc8d714fb21762f2092511f380f18cdb2d985d516071fa925bb433a90/SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:627dee0c280eea91aed87b20a1f849e9ae2fe719d52cbf847c0e0ea34464b3f7", size = 3200080, upload_time = "2024-09-16T21:18:19.033Z" }, + { url = "https://files.pythonhosted.org/packages/87/d2/8c2adaf2ade4f6f1b725acd0b0be9210bb6a2df41024729a8eec6a86fe5a/SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4fdcd72a789c1c31ed242fd8c1bcd9ea186a98ee8e5408a50e610edfef980d71", size = 3137108, upload_time = "2024-09-16T22:45:19.167Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ae/ea05d0bfa8f2b25ae34591895147152854fc950f491c4ce362ae06035db8/SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:89b64cd8898a3a6f642db4eb7b26d1b28a497d4022eccd7717ca066823e9fb01", size = 3157437, upload_time = "2024-09-16T21:18:21.988Z" }, + { url = "https://files.pythonhosted.org/packages/fe/5d/8ad6df01398388a766163d27960b3365f1bbd8bb7b05b5cad321a8b69b25/SQLAlchemy-2.0.35-cp311-cp311-win32.whl", hash = "sha256:6a93c5a0dfe8d34951e8a6f499a9479ffb9258123551fa007fc708ae2ac2bc5e", size = 2061935, upload_time = "2024-09-16T20:54:10.564Z" }, + { url = "https://files.pythonhosted.org/packages/ff/68/8557efc0c32c8e2c147cb6512237448b8ed594a57cd015fda67f8e56bb3f/SQLAlchemy-2.0.35-cp311-cp311-win_amd64.whl", hash = "sha256:c68fe3fcde03920c46697585620135b4ecfdfc1ed23e75cc2c2ae9f8502c10b8", size = 2087281, upload_time = "2024-09-16T20:54:13.429Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2b/fff87e6db0da31212c98bbc445f83fb608ea92b96bda3f3f10e373bac76c/SQLAlchemy-2.0.35-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eb60b026d8ad0c97917cb81d3662d0b39b8ff1335e3fabb24984c6acd0c900a2", size = 2089790, upload_time = "2024-09-16T21:07:16.161Z" }, + { url = "https://files.pythonhosted.org/packages/68/92/4bb761bd82764d5827bf6b6095168c40fb5dbbd23670203aef2f96ba6bc6/SQLAlchemy-2.0.35-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6921ee01caf375363be5e9ae70d08ce7ca9d7e0e8983183080211a062d299468", size = 2080266, upload_time = "2024-09-16T21:07:18.277Z" }, + { url = "https://files.pythonhosted.org/packages/22/46/068a65db6dc253c6f25a7598d99e0a1d60b14f661f9d09ef6c73c718fa4e/SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cdf1a0dbe5ced887a9b127da4ffd7354e9c1a3b9bb330dce84df6b70ccb3a8d", size = 3229760, upload_time = "2024-09-16T22:45:20.863Z" }, + { url = "https://files.pythonhosted.org/packages/6e/36/59830dafe40dda592304debd4cd86e583f63472f3a62c9e2695a5795e786/SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93a71c8601e823236ac0e5d087e4f397874a421017b3318fd92c0b14acf2b6db", size = 3240649, upload_time = "2024-09-16T21:18:23.996Z" }, + { url = "https://files.pythonhosted.org/packages/00/50/844c50c6996f9c7f000c959dd1a7436a6c94e449ee113046a1d19e470089/SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e04b622bb8a88f10e439084486f2f6349bf4d50605ac3e445869c7ea5cf0fa8c", size = 3176138, upload_time = "2024-09-16T22:45:22.518Z" }, + { url = "https://files.pythonhosted.org/packages/df/d2/336b18cac68eecb67de474fc15c85f13be4e615c6f5bae87ea38c6734ce0/SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1b56961e2d31389aaadf4906d453859f35302b4eb818d34a26fab72596076bb8", size = 3202753, upload_time = "2024-09-16T21:18:25.966Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f3/ee1e62fabdc10910b5ef720ae08e59bc785f26652876af3a50b89b97b412/SQLAlchemy-2.0.35-cp312-cp312-win32.whl", hash = "sha256:0f9f3f9a3763b9c4deb8c5d09c4cc52ffe49f9876af41cc1b2ad0138878453cf", size = 2060113, upload_time = "2024-09-16T20:54:15.16Z" }, + { url = "https://files.pythonhosted.org/packages/60/63/a3cef44a52979169d884f3583d0640e64b3c28122c096474a1d7cfcaf1f3/SQLAlchemy-2.0.35-cp312-cp312-win_amd64.whl", hash = "sha256:25b0f63e7fcc2a6290cb5f7f5b4fc4047843504983a28856ce9b35d8f7de03cc", size = 2085839, upload_time = "2024-09-16T20:54:17.11Z" }, + { url = "https://files.pythonhosted.org/packages/0e/c6/33c706449cdd92b1b6d756b247761e27d32230fd6b2de5f44c4c3e5632b2/SQLAlchemy-2.0.35-py3-none-any.whl", hash = "sha256:2ab3f0336c0387662ce6221ad30ab3a5e6499aab01b9790879b6578fd9b8faa1", size = 1881276, upload_time = "2024-09-16T23:14:28.324Z" }, ] [[package]] @@ -1318,9 +4187,48 @@ dependencies = [ { name = "pydantic" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/86/4b/c2ad0496f5bdc6073d9b4cef52be9c04f2b37a5773441cc6600b1857648b/sqlmodel-0.0.24.tar.gz", hash = "sha256:cc5c7613c1a5533c9c7867e1aab2fd489a76c9e8a061984da11b4e613c182423", size = 116780 } +sdist = { url = "https://files.pythonhosted.org/packages/86/4b/c2ad0496f5bdc6073d9b4cef52be9c04f2b37a5773441cc6600b1857648b/sqlmodel-0.0.24.tar.gz", hash = "sha256:cc5c7613c1a5533c9c7867e1aab2fd489a76c9e8a061984da11b4e613c182423", size = 116780, upload_time = "2025-03-07T05:43:32.887Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/91/484cd2d05569892b7fef7f5ceab3bc89fb0f8a8c0cde1030d383dbc5449c/sqlmodel-0.0.24-py3-none-any.whl", hash = "sha256:6778852f09370908985b667d6a3ab92910d0d5ec88adcaf23dbc242715ff7193", size = 28622, upload_time = "2025-03-07T05:43:30.37Z" }, +] + +[[package]] +name = "srsly" +version = "2.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "catalogue" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/e8/eb51b1349f50bac0222398af0942613fdc9d1453ae67cbe4bf9936a1a54b/srsly-2.5.1.tar.gz", hash = "sha256:ab1b4bf6cf3e29da23dae0493dd1517fb787075206512351421b89b4fc27c77e", size = 466464, upload_time = "2025-01-17T09:26:26.919Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/91/484cd2d05569892b7fef7f5ceab3bc89fb0f8a8c0cde1030d383dbc5449c/sqlmodel-0.0.24-py3-none-any.whl", hash = "sha256:6778852f09370908985b667d6a3ab92910d0d5ec88adcaf23dbc242715ff7193", size = 28622 }, + { url = "https://files.pythonhosted.org/packages/37/08/448bcc87bb93bc19fccf70c2f0f993ac42aa41d5f44a19c60d00186aea09/srsly-2.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d0cda6f65cc0dd1daf47e856b0d6c5d51db8a9343c5007723ca06903dcfe367d", size = 636045, upload_time = "2025-01-17T09:25:04.605Z" }, + { url = "https://files.pythonhosted.org/packages/03/8a/379dd9014e56460e71346cf512632fb8cbc89aa6dfebe31dff21c9eb37ba/srsly-2.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf643e6f45c266cfacea54997a1f9cfe0113fadac1ac21a1ec5b200cfe477ba0", size = 634425, upload_time = "2025-01-17T09:25:07.957Z" }, + { url = "https://files.pythonhosted.org/packages/95/69/46e672941b5f4403b0e2b14918d8e1393ca48e3338e2c01e549113261cdf/srsly-2.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:467ed25ddab09ca9404fda92519a317c803b5ea0849f846e74ba8b7843557df5", size = 1085032, upload_time = "2025-01-17T09:25:11.291Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d8/1039e663b87a06d2450148ebadc07eaf6f8b7dd7f7d5e2f4221050ce6702/srsly-2.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f8113d202664b7d31025bdbe40b9d3536e8d7154d09520b6a1955818fa6d622", size = 1089469, upload_time = "2025-01-17T09:25:15.913Z" }, + { url = "https://files.pythonhosted.org/packages/e9/62/f819ac665ecca2659343a6c79174c582fe292829f481899f05e7a7301988/srsly-2.5.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:794d39fccd2b333d24f1b445acc78daf90f3f37d3c0f6f0167f25c56961804e7", size = 1052673, upload_time = "2025-01-17T09:25:17.658Z" }, + { url = "https://files.pythonhosted.org/packages/a8/69/321a41fe4d549b96dd010b6a77657e84eb181034f9d125e2feebcd8f2e5c/srsly-2.5.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:df7fd77457c4d6c630f700b1019a8ad173e411e7cf7cfdea70e5ed86b608083b", size = 1062650, upload_time = "2025-01-17T09:25:20.704Z" }, + { url = "https://files.pythonhosted.org/packages/d5/b8/3dfed2db5c7ecf275aaddb775e2ae17c576b09c848873188fce91e410129/srsly-2.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:1a4dddb2edb8f7974c9aa5ec46dc687a75215b3bbdc815ce3fc9ea68fe1e94b5", size = 632267, upload_time = "2025-01-17T09:25:23.713Z" }, + { url = "https://files.pythonhosted.org/packages/df/9c/a248bb49de499fe0990e3cb0fb341c2373d8863ef9a8b5799353cade5731/srsly-2.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58f0736794ce00a71d62a39cbba1d62ea8d5be4751df956e802d147da20ecad7", size = 635917, upload_time = "2025-01-17T09:25:25.109Z" }, + { url = "https://files.pythonhosted.org/packages/41/47/1bdaad84502df973ecb8ca658117234cf7fb20e1dec60da71dce82de993f/srsly-2.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8269c40859806d71920396d185f4f38dc985cdb6a28d3a326a701e29a5f629", size = 634374, upload_time = "2025-01-17T09:25:26.609Z" }, + { url = "https://files.pythonhosted.org/packages/e5/2a/d73c71989fcf2a6d1fa518d75322aff4db01a8763f167f8c5e00aac11097/srsly-2.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:889905900401fefc1032e22b73aecbed8b4251aa363f632b2d1f86fc16f1ad8e", size = 1108390, upload_time = "2025-01-17T09:25:29.32Z" }, + { url = "https://files.pythonhosted.org/packages/35/a3/9eda9997a8bd011caed18fdaa5ce606714eb06d8dab587ed0522b3e92ab1/srsly-2.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf454755f22589df49c25dc799d8af7b47dce3d861dded35baf0f0b6ceab4422", size = 1110712, upload_time = "2025-01-17T09:25:31.051Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ef/4b50bc05d06349f905b27f824cc23b652098efd4be19aead3af4981df647/srsly-2.5.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cc0607c8a59013a51dde5c1b4e465558728e9e0a35dcfa73c7cbefa91a0aad50", size = 1081244, upload_time = "2025-01-17T09:25:32.611Z" }, + { url = "https://files.pythonhosted.org/packages/90/af/d4a2512d9a5048d2b18efead39d4c4404bddd4972935bbc68211292a736c/srsly-2.5.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d5421ba3ab3c790e8b41939c51a1d0f44326bfc052d7a0508860fb79a47aee7f", size = 1091692, upload_time = "2025-01-17T09:25:34.15Z" }, + { url = "https://files.pythonhosted.org/packages/bb/da/657a685f63028dcb00ccdc4ac125ed347c8bff6fa0dab6a9eb3dc45f3223/srsly-2.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:b96ea5a9a0d0379a79c46d255464a372fb14c30f59a8bc113e4316d131a530ab", size = 632627, upload_time = "2025-01-17T09:25:37.36Z" }, + { url = "https://files.pythonhosted.org/packages/fb/f6/bebc20d75bd02121fc0f65ad8c92a5dd2570e870005e940faa55a263e61a/srsly-2.5.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:683b54ed63d7dfee03bc2abc4b4a5f2152f81ec217bbadbac01ef1aaf2a75790", size = 636717, upload_time = "2025-01-17T09:25:40.236Z" }, + { url = "https://files.pythonhosted.org/packages/b6/e8/9372317a4742c70b87b413335adfcdfb2bee4f88f3faba89fabb9e6abf21/srsly-2.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:459d987130e57e83ce9e160899afbeb871d975f811e6958158763dd9a8a20f23", size = 634697, upload_time = "2025-01-17T09:25:43.605Z" }, + { url = "https://files.pythonhosted.org/packages/d5/00/c6a7b99ab27b051a27bd26fe1a8c1885225bb8980282bf9cb99f70610368/srsly-2.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:184e3c98389aab68ff04aab9095bd5f1a8e5a72cc5edcba9d733bac928f5cf9f", size = 1134655, upload_time = "2025-01-17T09:25:45.238Z" }, + { url = "https://files.pythonhosted.org/packages/c2/e6/861459e8241ec3b78c111081bd5efa414ef85867e17c45b6882954468d6e/srsly-2.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c2a3e4856e63b7efd47591d049aaee8e5a250e098917f50d93ea68853fab78", size = 1143544, upload_time = "2025-01-17T09:25:47.485Z" }, + { url = "https://files.pythonhosted.org/packages/2d/85/8448fe874dd2042a4eceea5315cfff3af03ac77ff5073812071852c4e7e2/srsly-2.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:366b4708933cd8d6025c13c2cea3331f079c7bb5c25ec76fca392b6fc09818a0", size = 1098330, upload_time = "2025-01-17T09:25:52.55Z" }, + { url = "https://files.pythonhosted.org/packages/ef/7e/04d0e1417da140b2ac4053a3d4fcfc86cd59bf4829f69d370bb899f74d5d/srsly-2.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c8a0b03c64eb6e150d772c5149befbadd981cc734ab13184b0561c17c8cef9b1", size = 1110670, upload_time = "2025-01-17T09:25:54.02Z" }, + { url = "https://files.pythonhosted.org/packages/96/1a/a8cd627eaa81a91feb6ceab50155f4ceff3eef6107916cb87ef796958427/srsly-2.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:7952538f6bba91b9d8bf31a642ac9e8b9ccc0ccbb309feb88518bfb84bb0dc0d", size = 632598, upload_time = "2025-01-17T09:25:55.499Z" }, + { url = "https://files.pythonhosted.org/packages/42/94/cab36845aad6e2c22ecee1178accaa365657296ff87305b805648fd41118/srsly-2.5.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84b372f7ef1604b4a5b3cee1571993931f845a5b58652ac01bcb32c52586d2a8", size = 634883, upload_time = "2025-01-17T09:25:58.363Z" }, + { url = "https://files.pythonhosted.org/packages/67/8b/501f51f4eaee7e1fd7327764799cb0a42f5d0de042a97916d30dbff770fc/srsly-2.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6ac3944c112acb3347a39bfdc2ebfc9e2d4bace20fe1c0b764374ac5b83519f2", size = 632842, upload_time = "2025-01-17T09:25:59.777Z" }, + { url = "https://files.pythonhosted.org/packages/07/be/5b8fce4829661e070a7d3e262d2e533f0e297b11b8993d57240da67d7330/srsly-2.5.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6118f9c4b221cde0a990d06a42c8a4845218d55b425d8550746fe790acf267e9", size = 1118516, upload_time = "2025-01-17T09:26:01.234Z" }, + { url = "https://files.pythonhosted.org/packages/91/60/a34e97564eac352c0e916c98f44b6f566b7eb6a9fb60bcd60ffa98530762/srsly-2.5.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7481460110d9986781d9e4ac0f5f991f1d6839284a80ad268625f9a23f686950", size = 1127974, upload_time = "2025-01-17T09:26:04.007Z" }, + { url = "https://files.pythonhosted.org/packages/70/a2/f642334db0cabd187fa86b8773257ee6993c6009338a6831d4804e2c5b3c/srsly-2.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e57b8138082f09e35db60f99757e16652489e9e3692471d8e0c39aa95180688", size = 1086098, upload_time = "2025-01-17T09:26:05.612Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9b/be48e185c5a010e71b5135e4cdf317ff56b8ac4bc08f394bbf882ac13b05/srsly-2.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bab90b85a63a1fe0bbc74d373c8bb9bb0499ddfa89075e0ebe8d670f12d04691", size = 1100354, upload_time = "2025-01-17T09:26:07.215Z" }, + { url = "https://files.pythonhosted.org/packages/3a/e2/745aeba88a8513017fbac2fd2f9f07b8a36065e51695f818541eb795ec0c/srsly-2.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:e73712be1634b5e1de6f81c273a7d47fe091ad3c79dc779c03d3416a5c117cee", size = 630634, upload_time = "2025-01-17T09:26:10.018Z" }, ] [[package]] @@ -1330,27 +4238,294 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/b4/e25c3b688ef703d85e55017c6edd0cbf38e5770ab748234363d54ff0251a/starlette-0.38.6.tar.gz", hash = "sha256:863a1588f5574e70a821dadefb41e4881ea451a47a3cd1b4df359d4ffefe5ead", size = 2569491 } +sdist = { url = "https://files.pythonhosted.org/packages/42/b4/e25c3b688ef703d85e55017c6edd0cbf38e5770ab748234363d54ff0251a/starlette-0.38.6.tar.gz", hash = "sha256:863a1588f5574e70a821dadefb41e4881ea451a47a3cd1b4df359d4ffefe5ead", size = 2569491, upload_time = "2024-09-22T17:01:45.422Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/9c/93f7bc03ff03199074e81974cc148908ead60dcf189f68ba1761a0ee35cf/starlette-0.38.6-py3-none-any.whl", hash = "sha256:4517a1409e2e73ee4951214ba012052b9e16f60e90d73cfb06192c19203bbb05", size = 71451, upload_time = "2024-09-22T17:01:43.076Z" }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload_time = "2025-04-27T18:05:01.611Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/9c/93f7bc03ff03199074e81974cc148908ead60dcf189f68ba1761a0ee35cf/starlette-0.38.6-py3-none-any.whl", hash = "sha256:4517a1409e2e73ee4951214ba012052b9e16f60e90d73cfb06192c19203bbb05", size = 71451 }, + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload_time = "2025-04-27T18:04:59.103Z" }, ] [[package]] name = "tenacity" version = "8.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a3/4d/6a19536c50b849338fcbe9290d562b52cbdcf30d8963d3588a68a4107df1/tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78", size = 47309 } +sdist = { url = "https://files.pythonhosted.org/packages/a3/4d/6a19536c50b849338fcbe9290d562b52cbdcf30d8963d3588a68a4107df1/tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78", size = 47309, upload_time = "2024-07-05T07:25:31.836Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687", size = 28165, upload_time = "2024-07-05T07:25:29.591Z" }, +] + +[[package]] +name = "textstat" +version = "0.7.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cmudict" }, + { name = "pyphen" }, + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/a9/5999c082bd57df27634434fd130e043a8b0f5711562dbf1df81a59cbea71/textstat-0.7.7.tar.gz", hash = "sha256:290034cd7d3144f3b967b70fb70820bdc5531a7831baebfd7d0347d3422f48c7", size = 137297, upload_time = "2025-05-11T09:51:57.837Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/7c/c5506dab41cc67acef5e6554bdac0bc9953e7f3e91cf6103cbdff200d1c5/textstat-0.7.7-py3-none-any.whl", hash = "sha256:103296f6a6f7451a4f56f78a5fd2ff184574a80e63886229f988cb4cc688270b", size = 175336, upload_time = "2025-05-11T09:51:56.191Z" }, +] + +[[package]] +name = "thinc" +version = "8.3.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "blis" }, + { name = "catalogue" }, + { name = "confection" }, + { name = "cymem" }, + { name = "murmurhash" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "packaging" }, + { name = "preshed" }, + { name = "pydantic" }, + { name = "setuptools" }, + { name = "srsly" }, + { name = "wasabi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/f4/7607f76c2e156a34b1961a941eb8407b84da4f515cc0903b44d44edf4f45/thinc-8.3.6.tar.gz", hash = "sha256:49983f9b7ddc4343a9532694a9118dd216d7a600520a21849a43b6c268ec6cad", size = 194218, upload_time = "2025-04-04T11:50:45.751Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/36/92233344b30caab56c2d8b0fc92472ec37402a5088f4f89ced96821e1638/thinc-8.3.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f4abec5a35e5945a6573b62bf0f423709467ba321fea9d00770b4c5282a8257d", size = 894690, upload_time = "2025-04-04T11:49:38.682Z" }, + { url = "https://files.pythonhosted.org/packages/e9/7e/ce6acadb3ae92836ed9eef2359fd2bd5f9257d22c422b44dd9c1cbc2b5c8/thinc-8.3.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ba7ced4bfc5890dd8f4be2978f8d491a07e80c9d9a7fffae9f57970b55db01bd", size = 844882, upload_time = "2025-04-04T11:49:45.947Z" }, + { url = "https://files.pythonhosted.org/packages/9d/88/26ca6b5d097d7958451fb4f6e67bcce6dfe31e73f21c16fd905315806f2a/thinc-8.3.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e645517d87f71e92137a1aef028094d134223885e15b8472bfcdc09665973ed", size = 4072032, upload_time = "2025-04-04T11:49:47.636Z" }, + { url = "https://files.pythonhosted.org/packages/c0/eb/12681892dbcaa45eedeb37dcf40251ea47e22e97413e6d4209fa4db2b9f2/thinc-8.3.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d8451dd08386d6bbde8160fd0e5e057e04a330c168837d3e0f278fa8738eea", size = 4136573, upload_time = "2025-04-04T11:49:49.106Z" }, + { url = "https://files.pythonhosted.org/packages/5f/76/98dd4983efbd7eebdd5d5964c566c8e5c10782db1599fc694610ba49ba75/thinc-8.3.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0e913f120fde25aea9f052e8cd45dd9cd36553ff1903e312b7302dd91000125a", size = 4949592, upload_time = "2025-04-04T11:49:50.64Z" }, + { url = "https://files.pythonhosted.org/packages/cd/7f/d867c7bcb22cd6022d9931f625340b26e86fd9cf25905adc408bc7393799/thinc-8.3.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:03706680bc0ea92036ac2e00f46bc86116ac6dccb6212b0c632e835176f666b2", size = 5165689, upload_time = "2025-04-04T11:49:52.385Z" }, + { url = "https://files.pythonhosted.org/packages/ed/8c/d6000d6d19cc1fc800ceb073b44403ce27a3414248cede691b5c49cbfb22/thinc-8.3.6-cp310-cp310-win_amd64.whl", hash = "sha256:0902314ecb83a225f41ab6121ceaf139b5da8bb6ada9e58031bad6c46134b8d4", size = 1773832, upload_time = "2025-04-04T11:49:54.259Z" }, + { url = "https://files.pythonhosted.org/packages/23/b4/b4ed217679327849ad796dc8ced307447a05e9f607bb12f290b2ec99fb35/thinc-8.3.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7c7c44f8736f27d1cced216246c00e219fb5734e6bc3b8a78c09157c011aae59", size = 895694, upload_time = "2025-04-04T11:49:56.102Z" }, + { url = "https://files.pythonhosted.org/packages/f0/53/5f9eeb725c2ca94adef76a2cd0289bc530728b0a035eed815c766a9291ef/thinc-8.3.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:92b3c38bdfdf81d0485685a6261b8a6ea40e03120b08ced418c8400f5e186b2d", size = 845256, upload_time = "2025-04-04T11:49:57.401Z" }, + { url = "https://files.pythonhosted.org/packages/89/8e/fae78ba63b1b0fb9017fd51d0aeffdc22e837807a93d55100c92e6d30570/thinc-8.3.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853eb187b1f77057adada1a72e7f6ea3f38643930363681cfd5de285dab4b09b", size = 4402142, upload_time = "2025-04-04T11:49:59.144Z" }, + { url = "https://files.pythonhosted.org/packages/ae/7e/6b1bb6eba9c25a5911e1624c0da33ca007d7697b41ee11c059f3d23d8bbc/thinc-8.3.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c12bf75a375b3b1f7c32a26cbd69255b177daa693c986a27faaf2027439c7ef", size = 4463797, upload_time = "2025-04-04T11:50:00.647Z" }, + { url = "https://files.pythonhosted.org/packages/42/39/c5f48785f76cd97a79e83b1acd3dab7d0835e4b560c9d7add846b47ea984/thinc-8.3.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5bf1708c22fb54e7846e8e743a9e6a43a22cbe24cab0081ba4e6362b4437a53f", size = 5313270, upload_time = "2025-04-04T11:50:02.241Z" }, + { url = "https://files.pythonhosted.org/packages/a3/32/ce8e7827ed0a1f86eab864e6b0b8ae79118e4e5c40ffd8b21938f8961e23/thinc-8.3.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:169d7c5779f6f1a78fa91b2bc3a6485f7bbe4341bd8064576f8e067b67b6a0b5", size = 5508338, upload_time = "2025-04-04T11:50:04.18Z" }, + { url = "https://files.pythonhosted.org/packages/94/40/7e5e840ac2e835fbf5d87e3ab94df7d678d846aaf28b12d46538ed36bf7f/thinc-8.3.6-cp311-cp311-win_amd64.whl", hash = "sha256:59c244ce11a3359b9a33b4c3bbc9ba94f7174214356ed88c16a41e39f31fe372", size = 1775998, upload_time = "2025-04-04T11:50:05.744Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c8/a9250944fb9a0a4c65b5d456f3a87ee6c249b53962757d77c28df8fadb46/thinc-8.3.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c54705e45a710e49758192592a3e0a80482edfdf5c61fc99f5d27ae822f652c5", size = 890177, upload_time = "2025-04-04T11:50:07.543Z" }, + { url = "https://files.pythonhosted.org/packages/3b/89/1ac54b18d4de79872c633302a10825695a36cd2e552cb8d4fea820b7a357/thinc-8.3.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:91acdbf3041c0ac1775ede570535a779cdf1312c317cd054d7b9d200da685c23", size = 839410, upload_time = "2025-04-04T11:50:09.26Z" }, + { url = "https://files.pythonhosted.org/packages/37/76/e1a76ab42e4637c4b8988d59784cdc1169a532d3043c36d2faf1a8d95228/thinc-8.3.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5a1db861614f91ff127feecce681c2213777b2d3d1ee6644bcc8a886acf0595", size = 4195748, upload_time = "2025-04-04T11:50:10.92Z" }, + { url = "https://files.pythonhosted.org/packages/00/a9/c59ac3260e7aff6b9dc80f495f1846a80b490595db06d040b05205d1f7f8/thinc-8.3.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:512e461989df8a30558367061d63ae6f1a6b4abe3c016a3360ee827e824254e0", size = 4261270, upload_time = "2025-04-04T11:50:12.953Z" }, + { url = "https://files.pythonhosted.org/packages/e0/8e/e86c5cbc6ebe238aa747ef9e20a969f6faba9ebbe1cbce059119f9614dd6/thinc-8.3.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a087aea2a63e6b9ccde61163d5922553b58908e96f8ad49cd0fd2edeb43e063f", size = 5067567, upload_time = "2025-04-04T11:50:18.317Z" }, + { url = "https://files.pythonhosted.org/packages/fe/8a/16670e4de36231aab5b052c734ad716be29aab2c0d2f3d8dd9c8dd27fafc/thinc-8.3.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1d85dd5d94bb75006864c7d99fd5b75d05b1602d571e7fcdb42d4521f962048", size = 5309405, upload_time = "2025-04-04T11:50:20.075Z" }, + { url = "https://files.pythonhosted.org/packages/58/08/5439dd15b661610d8a3b919f18065ebf0d664b6a54a3794206622a74c910/thinc-8.3.6-cp312-cp312-win_amd64.whl", hash = "sha256:1170d85294366127d97a27dd5896f4abe90e2a5ea2b7988de9a5bb8e1128d222", size = 1749275, upload_time = "2025-04-04T11:50:21.769Z" }, + { url = "https://files.pythonhosted.org/packages/a6/03/0ba9bec3057f4a9c0b7ba53839aebcbbbc28de3b91330cb8de74a885b8f6/thinc-8.3.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d8743ee8ad2d59fda018b57e5da102d6098bbeb0f70476f3fd8ceb9d215d88b9", size = 883375, upload_time = "2025-04-04T11:50:23.273Z" }, + { url = "https://files.pythonhosted.org/packages/ae/79/ac31cd25d1d973b824de10ebbc56788688aecdd8f56800daf8edfff45097/thinc-8.3.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:89dbeb2ca94f1033e90999a70e2bc9dd5390d5341dc1a3a4b8793d03855265c3", size = 832654, upload_time = "2025-04-04T11:50:24.871Z" }, + { url = "https://files.pythonhosted.org/packages/f8/0d/fb5e8e49dfb53cc02ce907f81002031c6f4fe7e7aa44b1004ea695630017/thinc-8.3.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89a5460695067aa6e4182515cfd2018263db77cc17b7031d50ed696e990797a8", size = 4158592, upload_time = "2025-04-04T11:50:26.403Z" }, + { url = "https://files.pythonhosted.org/packages/e5/42/c87990ca214b9910f33b110d3b1ac213407388d35376bc955ad45e5de764/thinc-8.3.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0aa8e32f49234569fd10c35b562ee2f9c0d51225365a6e604a5a67396a49f2c1", size = 4236211, upload_time = "2025-04-04T11:50:27.943Z" }, + { url = "https://files.pythonhosted.org/packages/fa/10/9975bcee4dd4634bfb87df0447d7fa86d6c9b2d9228e56d4adb98cc19cbc/thinc-8.3.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f432158b80cf75a096980470b790b51d81daf9c2822598adebfc3cb58588fd6c", size = 5049197, upload_time = "2025-04-04T11:50:29.583Z" }, + { url = "https://files.pythonhosted.org/packages/9b/34/e1b384009eb8ad2192770157961cd0c2e2712fedf49e1dfd902e3d9b9973/thinc-8.3.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:61fb33a22aba40366fa9018ab34580f74fc40be821ab8af77ac1fdbeac17243b", size = 5278543, upload_time = "2025-04-04T11:50:31.524Z" }, + { url = "https://files.pythonhosted.org/packages/f0/26/f77ef4bd174bfeac491237a4ca3f74ba2ee2f672004f76cff90f8407a489/thinc-8.3.6-cp313-cp313-win_amd64.whl", hash = "sha256:ddd7041946a427f6a9b0b49419353d02ad7eb43fe16724bfcc3bdeb9562040b1", size = 1746883, upload_time = "2025-04-04T11:50:33.038Z" }, +] + +[[package]] +name = "threadpoolctl" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload_time = "2025-03-13T13:49:23.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload_time = "2025-03-13T13:49:21.846Z" }, +] + +[[package]] +name = "tiktoken" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "regex" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/cf/756fedf6981e82897f2d570dd25fa597eb3f4459068ae0572d7e888cfd6f/tiktoken-0.9.0.tar.gz", hash = "sha256:d02a5ca6a938e0490e1ff957bc48c8b078c88cb83977be1625b1fd8aac792c5d", size = 35991, upload_time = "2025-02-14T06:03:01.003Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/f3/50ec5709fad61641e4411eb1b9ac55b99801d71f1993c29853f256c726c9/tiktoken-0.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:586c16358138b96ea804c034b8acf3f5d3f0258bd2bc3b0227af4af5d622e382", size = 1065770, upload_time = "2025-02-14T06:02:01.251Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f8/5a9560a422cf1755b6e0a9a436e14090eeb878d8ec0f80e0cd3d45b78bf4/tiktoken-0.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9c59ccc528c6c5dd51820b3474402f69d9a9e1d656226848ad68a8d5b2e5108", size = 1009314, upload_time = "2025-02-14T06:02:02.869Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/3ed4cfff8f809cb902900ae686069e029db74567ee10d017cb254df1d598/tiktoken-0.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0968d5beeafbca2a72c595e8385a1a1f8af58feaebb02b227229b69ca5357fd", size = 1143140, upload_time = "2025-02-14T06:02:04.165Z" }, + { url = "https://files.pythonhosted.org/packages/f1/95/cc2c6d79df8f113bdc6c99cdec985a878768120d87d839a34da4bd3ff90a/tiktoken-0.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92a5fb085a6a3b7350b8fc838baf493317ca0e17bd95e8642f95fc69ecfed1de", size = 1197860, upload_time = "2025-02-14T06:02:06.268Z" }, + { url = "https://files.pythonhosted.org/packages/c7/6c/9c1a4cc51573e8867c9381db1814223c09ebb4716779c7f845d48688b9c8/tiktoken-0.9.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15a2752dea63d93b0332fb0ddb05dd909371ededa145fe6a3242f46724fa7990", size = 1259661, upload_time = "2025-02-14T06:02:08.889Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4c/22eb8e9856a2b1808d0a002d171e534eac03f96dbe1161978d7389a59498/tiktoken-0.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:26113fec3bd7a352e4b33dbaf1bd8948de2507e30bd95a44e2b1156647bc01b4", size = 894026, upload_time = "2025-02-14T06:02:12.841Z" }, + { url = "https://files.pythonhosted.org/packages/4d/ae/4613a59a2a48e761c5161237fc850eb470b4bb93696db89da51b79a871f1/tiktoken-0.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f32cc56168eac4851109e9b5d327637f15fd662aa30dd79f964b7c39fbadd26e", size = 1065987, upload_time = "2025-02-14T06:02:14.174Z" }, + { url = "https://files.pythonhosted.org/packages/3f/86/55d9d1f5b5a7e1164d0f1538a85529b5fcba2b105f92db3622e5d7de6522/tiktoken-0.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:45556bc41241e5294063508caf901bf92ba52d8ef9222023f83d2483a3055348", size = 1009155, upload_time = "2025-02-14T06:02:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/03/58/01fb6240df083b7c1916d1dcb024e2b761213c95d576e9f780dfb5625a76/tiktoken-0.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03935988a91d6d3216e2ec7c645afbb3d870b37bcb67ada1943ec48678e7ee33", size = 1142898, upload_time = "2025-02-14T06:02:16.666Z" }, + { url = "https://files.pythonhosted.org/packages/b1/73/41591c525680cd460a6becf56c9b17468d3711b1df242c53d2c7b2183d16/tiktoken-0.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b3d80aad8d2c6b9238fc1a5524542087c52b860b10cbf952429ffb714bc1136", size = 1197535, upload_time = "2025-02-14T06:02:18.595Z" }, + { url = "https://files.pythonhosted.org/packages/7d/7c/1069f25521c8f01a1a182f362e5c8e0337907fae91b368b7da9c3e39b810/tiktoken-0.9.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b2a21133be05dc116b1d0372af051cd2c6aa1d2188250c9b553f9fa49301b336", size = 1259548, upload_time = "2025-02-14T06:02:20.729Z" }, + { url = "https://files.pythonhosted.org/packages/6f/07/c67ad1724b8e14e2b4c8cca04b15da158733ac60136879131db05dda7c30/tiktoken-0.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:11a20e67fdf58b0e2dea7b8654a288e481bb4fc0289d3ad21291f8d0849915fb", size = 893895, upload_time = "2025-02-14T06:02:22.67Z" }, + { url = "https://files.pythonhosted.org/packages/cf/e5/21ff33ecfa2101c1bb0f9b6df750553bd873b7fb532ce2cb276ff40b197f/tiktoken-0.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e88f121c1c22b726649ce67c089b90ddda8b9662545a8aeb03cfef15967ddd03", size = 1065073, upload_time = "2025-02-14T06:02:24.768Z" }, + { url = "https://files.pythonhosted.org/packages/8e/03/a95e7b4863ee9ceec1c55983e4cc9558bcfd8f4f80e19c4f8a99642f697d/tiktoken-0.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a6600660f2f72369acb13a57fb3e212434ed38b045fd8cc6cdd74947b4b5d210", size = 1008075, upload_time = "2025-02-14T06:02:26.92Z" }, + { url = "https://files.pythonhosted.org/packages/40/10/1305bb02a561595088235a513ec73e50b32e74364fef4de519da69bc8010/tiktoken-0.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95e811743b5dfa74f4b227927ed86cbc57cad4df859cb3b643be797914e41794", size = 1140754, upload_time = "2025-02-14T06:02:28.124Z" }, + { url = "https://files.pythonhosted.org/packages/1b/40/da42522018ca496432ffd02793c3a72a739ac04c3794a4914570c9bb2925/tiktoken-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99376e1370d59bcf6935c933cb9ba64adc29033b7e73f5f7569f3aad86552b22", size = 1196678, upload_time = "2025-02-14T06:02:29.845Z" }, + { url = "https://files.pythonhosted.org/packages/5c/41/1e59dddaae270ba20187ceb8aa52c75b24ffc09f547233991d5fd822838b/tiktoken-0.9.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:badb947c32739fb6ddde173e14885fb3de4d32ab9d8c591cbd013c22b4c31dd2", size = 1259283, upload_time = "2025-02-14T06:02:33.838Z" }, + { url = "https://files.pythonhosted.org/packages/5b/64/b16003419a1d7728d0d8c0d56a4c24325e7b10a21a9dd1fc0f7115c02f0a/tiktoken-0.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:5a62d7a25225bafed786a524c1b9f0910a1128f4232615bf3f8257a73aaa3b16", size = 894897, upload_time = "2025-02-14T06:02:36.265Z" }, + { url = "https://files.pythonhosted.org/packages/7a/11/09d936d37f49f4f494ffe660af44acd2d99eb2429d60a57c71318af214e0/tiktoken-0.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2b0e8e05a26eda1249e824156d537015480af7ae222ccb798e5234ae0285dbdb", size = 1064919, upload_time = "2025-02-14T06:02:37.494Z" }, + { url = "https://files.pythonhosted.org/packages/80/0e/f38ba35713edb8d4197ae602e80837d574244ced7fb1b6070b31c29816e0/tiktoken-0.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:27d457f096f87685195eea0165a1807fae87b97b2161fe8c9b1df5bd74ca6f63", size = 1007877, upload_time = "2025-02-14T06:02:39.516Z" }, + { url = "https://files.pythonhosted.org/packages/fe/82/9197f77421e2a01373e27a79dd36efdd99e6b4115746ecc553318ecafbf0/tiktoken-0.9.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cf8ded49cddf825390e36dd1ad35cd49589e8161fdcb52aa25f0583e90a3e01", size = 1140095, upload_time = "2025-02-14T06:02:41.791Z" }, + { url = "https://files.pythonhosted.org/packages/f2/bb/4513da71cac187383541facd0291c4572b03ec23c561de5811781bbd988f/tiktoken-0.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc156cb314119a8bb9748257a2eaebd5cc0753b6cb491d26694ed42fc7cb3139", size = 1195649, upload_time = "2025-02-14T06:02:43Z" }, + { url = "https://files.pythonhosted.org/packages/fa/5c/74e4c137530dd8504e97e3a41729b1103a4ac29036cbfd3250b11fd29451/tiktoken-0.9.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cd69372e8c9dd761f0ab873112aba55a0e3e506332dd9f7522ca466e817b1b7a", size = 1258465, upload_time = "2025-02-14T06:02:45.046Z" }, + { url = "https://files.pythonhosted.org/packages/de/a8/8f499c179ec900783ffe133e9aab10044481679bb9aad78436d239eee716/tiktoken-0.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:5ea0edb6f83dc56d794723286215918c1cde03712cbbafa0348b33448faf5b95", size = 894669, upload_time = "2025-02-14T06:02:47.341Z" }, +] + +[[package]] +name = "tokenizers" +version = "0.21.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/2d/b0fce2b8201635f60e8c95990080f58461cc9ca3d5026de2e900f38a7f21/tokenizers-0.21.2.tar.gz", hash = "sha256:fdc7cffde3e2113ba0e6cc7318c40e3438a4d74bbc62bf04bcc63bdfb082ac77", size = 351545, upload_time = "2025-06-24T10:24:52.449Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/3f/8ba87d9e287b9d385a02a7114ddcef61b26f86411e121c9003eb509a1773/tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687", size = 28165 }, + { url = "https://files.pythonhosted.org/packages/1d/cc/2936e2d45ceb130a21d929743f1e9897514691bec123203e10837972296f/tokenizers-0.21.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:342b5dfb75009f2255ab8dec0041287260fed5ce00c323eb6bab639066fef8ec", size = 2875206, upload_time = "2025-06-24T10:24:42.755Z" }, + { url = "https://files.pythonhosted.org/packages/6c/e6/33f41f2cc7861faeba8988e7a77601407bf1d9d28fc79c5903f8f77df587/tokenizers-0.21.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:126df3205d6f3a93fea80c7a8a266a78c1bd8dd2fe043386bafdd7736a23e45f", size = 2732655, upload_time = "2025-06-24T10:24:41.56Z" }, + { url = "https://files.pythonhosted.org/packages/33/2b/1791eb329c07122a75b01035b1a3aa22ad139f3ce0ece1b059b506d9d9de/tokenizers-0.21.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a32cd81be21168bd0d6a0f0962d60177c447a1aa1b1e48fa6ec9fc728ee0b12", size = 3019202, upload_time = "2025-06-24T10:24:31.791Z" }, + { url = "https://files.pythonhosted.org/packages/05/15/fd2d8104faa9f86ac68748e6f7ece0b5eb7983c7efc3a2c197cb98c99030/tokenizers-0.21.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8bd8999538c405133c2ab999b83b17c08b7fc1b48c1ada2469964605a709ef91", size = 2934539, upload_time = "2025-06-24T10:24:34.567Z" }, + { url = "https://files.pythonhosted.org/packages/a5/2e/53e8fd053e1f3ffbe579ca5f9546f35ac67cf0039ed357ad7ec57f5f5af0/tokenizers-0.21.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e9944e61239b083a41cf8fc42802f855e1dca0f499196df37a8ce219abac6eb", size = 3248665, upload_time = "2025-06-24T10:24:39.024Z" }, + { url = "https://files.pythonhosted.org/packages/00/15/79713359f4037aa8f4d1f06ffca35312ac83629da062670e8830917e2153/tokenizers-0.21.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:514cd43045c5d546f01142ff9c79a96ea69e4b5cda09e3027708cb2e6d5762ab", size = 3451305, upload_time = "2025-06-24T10:24:36.133Z" }, + { url = "https://files.pythonhosted.org/packages/38/5f/959f3a8756fc9396aeb704292777b84f02a5c6f25c3fc3ba7530db5feb2c/tokenizers-0.21.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1b9405822527ec1e0f7d8d2fdb287a5730c3a6518189c968254a8441b21faae", size = 3214757, upload_time = "2025-06-24T10:24:37.784Z" }, + { url = "https://files.pythonhosted.org/packages/c5/74/f41a432a0733f61f3d21b288de6dfa78f7acff309c6f0f323b2833e9189f/tokenizers-0.21.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed9a4d51c395103ad24f8e7eb976811c57fbec2af9f133df471afcd922e5020", size = 3121887, upload_time = "2025-06-24T10:24:40.293Z" }, + { url = "https://files.pythonhosted.org/packages/3c/6a/bc220a11a17e5d07b0dfb3b5c628621d4dcc084bccd27cfaead659963016/tokenizers-0.21.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2c41862df3d873665ec78b6be36fcc30a26e3d4902e9dd8608ed61d49a48bc19", size = 9091965, upload_time = "2025-06-24T10:24:44.431Z" }, + { url = "https://files.pythonhosted.org/packages/6c/bd/ac386d79c4ef20dc6f39c4706640c24823dca7ebb6f703bfe6b5f0292d88/tokenizers-0.21.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:ed21dc7e624e4220e21758b2e62893be7101453525e3d23264081c9ef9a6d00d", size = 9053372, upload_time = "2025-06-24T10:24:46.455Z" }, + { url = "https://files.pythonhosted.org/packages/63/7b/5440bf203b2a5358f074408f7f9c42884849cd9972879e10ee6b7a8c3b3d/tokenizers-0.21.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:0e73770507e65a0e0e2a1affd6b03c36e3bc4377bd10c9ccf51a82c77c0fe365", size = 9298632, upload_time = "2025-06-24T10:24:48.446Z" }, + { url = "https://files.pythonhosted.org/packages/a4/d2/faa1acac3f96a7427866e94ed4289949b2524f0c1878512516567d80563c/tokenizers-0.21.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:106746e8aa9014a12109e58d540ad5465b4c183768ea96c03cbc24c44d329958", size = 9470074, upload_time = "2025-06-24T10:24:50.378Z" }, + { url = "https://files.pythonhosted.org/packages/d8/a5/896e1ef0707212745ae9f37e84c7d50269411aef2e9ccd0de63623feecdf/tokenizers-0.21.2-cp39-abi3-win32.whl", hash = "sha256:cabda5a6d15d620b6dfe711e1af52205266d05b379ea85a8a301b3593c60e962", size = 2330115, upload_time = "2025-06-24T10:24:55.069Z" }, + { url = "https://files.pythonhosted.org/packages/13/c3/cc2755ee10be859c4338c962a35b9a663788c0c0b50c0bdd8078fb6870cf/tokenizers-0.21.2-cp39-abi3-win_amd64.whl", hash = "sha256:58747bb898acdb1007f37a7bbe614346e98dc28708ffb66a3fd50ce169ac6c98", size = 2509918, upload_time = "2025-06-24T10:24:53.71Z" }, ] [[package]] name = "tomli" version = "2.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164 } +sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164, upload_time = "2022-02-08T10:54:04.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757, upload_time = "2022-02-08T10:54:02.017Z" }, +] + +[[package]] +name = "torch" +version = "2.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "networkx", version = "3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufile-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "setuptools", marker = "python_full_version >= '3.12'" }, + { name = "sympy" }, + { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/27/2e06cb52adf89fe6e020963529d17ed51532fc73c1e6d1b18420ef03338c/torch-2.7.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:a103b5d782af5bd119b81dbcc7ffc6fa09904c423ff8db397a1e6ea8fd71508f", size = 99089441, upload_time = "2025-06-04T17:38:48.268Z" }, + { url = "https://files.pythonhosted.org/packages/0a/7c/0a5b3aee977596459ec45be2220370fde8e017f651fecc40522fd478cb1e/torch-2.7.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:fe955951bdf32d182ee8ead6c3186ad54781492bf03d547d31771a01b3d6fb7d", size = 821154516, upload_time = "2025-06-04T17:36:28.556Z" }, + { url = "https://files.pythonhosted.org/packages/f9/91/3d709cfc5e15995fb3fe7a6b564ce42280d3a55676dad672205e94f34ac9/torch-2.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:885453d6fba67d9991132143bf7fa06b79b24352f4506fd4d10b309f53454162", size = 216093147, upload_time = "2025-06-04T17:39:38.132Z" }, + { url = "https://files.pythonhosted.org/packages/92/f6/5da3918414e07da9866ecb9330fe6ffdebe15cb9a4c5ada7d4b6e0a6654d/torch-2.7.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:d72acfdb86cee2a32c0ce0101606f3758f0d8bb5f8f31e7920dc2809e963aa7c", size = 68630914, upload_time = "2025-06-04T17:39:31.162Z" }, + { url = "https://files.pythonhosted.org/packages/11/56/2eae3494e3d375533034a8e8cf0ba163363e996d85f0629441fa9d9843fe/torch-2.7.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:236f501f2e383f1cb861337bdf057712182f910f10aeaf509065d54d339e49b2", size = 99093039, upload_time = "2025-06-04T17:39:06.963Z" }, + { url = "https://files.pythonhosted.org/packages/e5/94/34b80bd172d0072c9979708ccd279c2da2f55c3ef318eceec276ab9544a4/torch-2.7.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:06eea61f859436622e78dd0cdd51dbc8f8c6d76917a9cf0555a333f9eac31ec1", size = 821174704, upload_time = "2025-06-04T17:37:03.799Z" }, + { url = "https://files.pythonhosted.org/packages/50/9e/acf04ff375b0b49a45511c55d188bcea5c942da2aaf293096676110086d1/torch-2.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:8273145a2e0a3c6f9fd2ac36762d6ee89c26d430e612b95a99885df083b04e52", size = 216095937, upload_time = "2025-06-04T17:39:24.83Z" }, + { url = "https://files.pythonhosted.org/packages/5b/2b/d36d57c66ff031f93b4fa432e86802f84991477e522adcdffd314454326b/torch-2.7.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:aea4fc1bf433d12843eb2c6b2204861f43d8364597697074c8d38ae2507f8730", size = 68640034, upload_time = "2025-06-04T17:39:17.989Z" }, + { url = "https://files.pythonhosted.org/packages/87/93/fb505a5022a2e908d81fe9a5e0aa84c86c0d5f408173be71c6018836f34e/torch-2.7.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:27ea1e518df4c9de73af7e8a720770f3628e7f667280bce2be7a16292697e3fa", size = 98948276, upload_time = "2025-06-04T17:39:12.852Z" }, + { url = "https://files.pythonhosted.org/packages/56/7e/67c3fe2b8c33f40af06326a3d6ae7776b3e3a01daa8f71d125d78594d874/torch-2.7.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c33360cfc2edd976c2633b3b66c769bdcbbf0e0b6550606d188431c81e7dd1fc", size = 821025792, upload_time = "2025-06-04T17:34:58.747Z" }, + { url = "https://files.pythonhosted.org/packages/a1/37/a37495502bc7a23bf34f89584fa5a78e25bae7b8da513bc1b8f97afb7009/torch-2.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:d8bf6e1856ddd1807e79dc57e54d3335f2b62e6f316ed13ed3ecfe1fc1df3d8b", size = 216050349, upload_time = "2025-06-04T17:38:59.709Z" }, + { url = "https://files.pythonhosted.org/packages/3a/60/04b77281c730bb13460628e518c52721257814ac6c298acd25757f6a175c/torch-2.7.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:787687087412c4bd68d315e39bc1223f08aae1d16a9e9771d95eabbb04ae98fb", size = 68645146, upload_time = "2025-06-04T17:38:52.97Z" }, + { url = "https://files.pythonhosted.org/packages/66/81/e48c9edb655ee8eb8c2a6026abdb6f8d2146abd1f150979ede807bb75dcb/torch-2.7.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:03563603d931e70722dce0e11999d53aa80a375a3d78e6b39b9f6805ea0a8d28", size = 98946649, upload_time = "2025-06-04T17:38:43.031Z" }, + { url = "https://files.pythonhosted.org/packages/3a/24/efe2f520d75274fc06b695c616415a1e8a1021d87a13c68ff9dce733d088/torch-2.7.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:d632f5417b6980f61404a125b999ca6ebd0b8b4bbdbb5fbbba44374ab619a412", size = 821033192, upload_time = "2025-06-04T17:38:09.146Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d9/9c24d230333ff4e9b6807274f6f8d52a864210b52ec794c5def7925f4495/torch-2.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:23660443e13995ee93e3d844786701ea4ca69f337027b05182f5ba053ce43b38", size = 216055668, upload_time = "2025-06-04T17:38:36.253Z" }, + { url = "https://files.pythonhosted.org/packages/95/bf/e086ee36ddcef9299f6e708d3b6c8487c1651787bb9ee2939eb2a7f74911/torch-2.7.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:0da4f4dba9f65d0d203794e619fe7ca3247a55ffdcbd17ae8fb83c8b2dc9b585", size = 68925988, upload_time = "2025-06-04T17:38:29.273Z" }, + { url = "https://files.pythonhosted.org/packages/69/6a/67090dcfe1cf9048448b31555af6efb149f7afa0a310a366adbdada32105/torch-2.7.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:e08d7e6f21a617fe38eeb46dd2213ded43f27c072e9165dc27300c9ef9570934", size = 99028857, upload_time = "2025-06-04T17:37:50.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/1c/48b988870823d1cc381f15ec4e70ed3d65e043f43f919329b0045ae83529/torch-2.7.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:30207f672328a42df4f2174b8f426f354b2baa0b7cca3a0adb3d6ab5daf00dc8", size = 821098066, upload_time = "2025-06-04T17:37:33.939Z" }, + { url = "https://files.pythonhosted.org/packages/7b/eb/10050d61c9d5140c5dc04a89ed3257ef1a6b93e49dd91b95363d757071e0/torch-2.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:79042feca1c634aaf6603fe6feea8c6b30dfa140a6bbc0b973e2260c7e79a22e", size = 216336310, upload_time = "2025-06-04T17:36:09.862Z" }, + { url = "https://files.pythonhosted.org/packages/b1/29/beb45cdf5c4fc3ebe282bf5eafc8dfd925ead7299b3c97491900fe5ed844/torch-2.7.1-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:988b0cbc4333618a1056d2ebad9eb10089637b659eb645434d0809d8d937b946", size = 68645708, upload_time = "2025-06-04T17:34:39.852Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/89/c72771c81d25d53fe33e3dca61c233b665b2780f21820ba6fd2c6793c12b/tornado-6.5.1.tar.gz", hash = "sha256:84ceece391e8eb9b2b95578db65e920d2a61070260594819589609ba9bc6308c", size = 509934, upload_time = "2025-05-22T18:15:38.788Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/89/f4532dee6843c9e0ebc4e28d4be04c67f54f60813e4bf73d595fe7567452/tornado-6.5.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d50065ba7fd11d3bd41bcad0825227cc9a95154bad83239357094c36708001f7", size = 441948, upload_time = "2025-05-22T18:15:20.862Z" }, + { url = "https://files.pythonhosted.org/packages/15/9a/557406b62cffa395d18772e0cdcf03bed2fff03b374677348eef9f6a3792/tornado-6.5.1-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9e9ca370f717997cb85606d074b0e5b247282cf5e2e1611568b8821afe0342d6", size = 440112, upload_time = "2025-05-22T18:15:22.591Z" }, + { url = "https://files.pythonhosted.org/packages/55/82/7721b7319013a3cf881f4dffa4f60ceff07b31b394e459984e7a36dc99ec/tornado-6.5.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b77e9dfa7ed69754a54c89d82ef746398be82f749df69c4d3abe75c4d1ff4888", size = 443672, upload_time = "2025-05-22T18:15:24.027Z" }, + { url = "https://files.pythonhosted.org/packages/7d/42/d11c4376e7d101171b94e03cef0cbce43e823ed6567ceda571f54cf6e3ce/tornado-6.5.1-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253b76040ee3bab8bcf7ba9feb136436a3787208717a1fb9f2c16b744fba7331", size = 443019, upload_time = "2025-05-22T18:15:25.735Z" }, + { url = "https://files.pythonhosted.org/packages/7d/f7/0c48ba992d875521ac761e6e04b0a1750f8150ae42ea26df1852d6a98942/tornado-6.5.1-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:308473f4cc5a76227157cdf904de33ac268af770b2c5f05ca6c1161d82fdd95e", size = 443252, upload_time = "2025-05-22T18:15:27.499Z" }, + { url = "https://files.pythonhosted.org/packages/89/46/d8d7413d11987e316df4ad42e16023cd62666a3c0dfa1518ffa30b8df06c/tornado-6.5.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:caec6314ce8a81cf69bd89909f4b633b9f523834dc1a352021775d45e51d9401", size = 443930, upload_time = "2025-05-22T18:15:29.299Z" }, + { url = "https://files.pythonhosted.org/packages/78/b2/f8049221c96a06df89bed68260e8ca94beca5ea532ffc63b1175ad31f9cc/tornado-6.5.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:13ce6e3396c24e2808774741331638ee6c2f50b114b97a55c5b442df65fd9692", size = 443351, upload_time = "2025-05-22T18:15:31.038Z" }, + { url = "https://files.pythonhosted.org/packages/76/ff/6a0079e65b326cc222a54720a748e04a4db246870c4da54ece4577bfa702/tornado-6.5.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5cae6145f4cdf5ab24744526cc0f55a17d76f02c98f4cff9daa08ae9a217448a", size = 443328, upload_time = "2025-05-22T18:15:32.426Z" }, + { url = "https://files.pythonhosted.org/packages/49/18/e3f902a1d21f14035b5bc6246a8c0f51e0eef562ace3a2cea403c1fb7021/tornado-6.5.1-cp39-abi3-win32.whl", hash = "sha256:e0a36e1bc684dca10b1aa75a31df8bdfed656831489bc1e6a6ebed05dc1ec365", size = 444396, upload_time = "2025-05-22T18:15:34.205Z" }, + { url = "https://files.pythonhosted.org/packages/7b/09/6526e32bf1049ee7de3bebba81572673b19a2a8541f795d887e92af1a8bc/tornado-6.5.1-cp39-abi3-win_amd64.whl", hash = "sha256:908e7d64567cecd4c2b458075589a775063453aeb1d2a1853eedb806922f568b", size = 444840, upload_time = "2025-05-22T18:15:36.1Z" }, + { url = "https://files.pythonhosted.org/packages/55/a7/535c44c7bea4578e48281d83c615219f3ab19e6abc67625ef637c73987be/tornado-6.5.1-cp39-abi3-win_arm64.whl", hash = "sha256:02420a0eb7bf617257b9935e2b754d1b63897525d8a289c9d65690d580b4dcf7", size = 443596, upload_time = "2025-05-22T18:15:37.433Z" }, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload_time = "2024-11-24T20:12:22.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload_time = "2024-11-24T20:12:19.698Z" }, +] + +[[package]] +name = "transformers" +version = "4.53.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "huggingface-hub" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "regex" }, + { name = "requests" }, + { name = "safetensors" }, + { name = "tokenizers" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/2c/68a0024c311db41bb92d4ec17d22e90b7406a4d28aa18d87662f2bbebcd9/transformers-4.53.1.tar.gz", hash = "sha256:da5a9f66ad480bc2a7f75bc32eaf735fd20ac56af4325ca4ce994021ceb37710", size = 9192189, upload_time = "2025-07-04T08:28:40.571Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/10/8cef2288810a3210659eb3a20711e8387cc35a881a7762ae387806e2d651/transformers-4.53.1-py3-none-any.whl", hash = "sha256:c84f3c3e41c71fdf2c60c8a893e1cd31191b0cb463385f4c276302d2052d837b", size = 10825681, upload_time = "2025-07-04T08:28:37.318Z" }, +] + +[[package]] +name = "triton" +version = "3.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, +] wheels = [ - { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757 }, + { url = "https://files.pythonhosted.org/packages/8d/a9/549e51e9b1b2c9b854fd761a1d23df0ba2fbc60bd0c13b489ffa518cfcb7/triton-3.3.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b74db445b1c562844d3cfad6e9679c72e93fdfb1a90a24052b03bb5c49d1242e", size = 155600257, upload_time = "2025-05-29T23:39:36.085Z" }, + { url = "https://files.pythonhosted.org/packages/21/2f/3e56ea7b58f80ff68899b1dbe810ff257c9d177d288c6b0f55bf2fe4eb50/triton-3.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b31e3aa26f8cb3cc5bf4e187bf737cbacf17311e1112b781d4a059353dfd731b", size = 155689937, upload_time = "2025-05-29T23:39:44.182Z" }, + { url = "https://files.pythonhosted.org/packages/24/5f/950fb373bf9c01ad4eb5a8cd5eaf32cdf9e238c02f9293557a2129b9c4ac/triton-3.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9999e83aba21e1a78c1f36f21bce621b77bcaa530277a50484a7cb4a822f6e43", size = 155669138, upload_time = "2025-05-29T23:39:51.771Z" }, + { url = "https://files.pythonhosted.org/packages/74/1f/dfb531f90a2d367d914adfee771babbd3f1a5b26c3f5fbc458dee21daa78/triton-3.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b89d846b5a4198317fec27a5d3a609ea96b6d557ff44b56c23176546023c4240", size = 155673035, upload_time = "2025-05-29T23:40:02.468Z" }, + { url = "https://files.pythonhosted.org/packages/28/71/bd20ffcb7a64c753dc2463489a61bf69d531f308e390ad06390268c4ea04/triton-3.3.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3198adb9d78b77818a5388bff89fa72ff36f9da0bc689db2f0a651a67ce6a42", size = 155735832, upload_time = "2025-05-29T23:40:10.522Z" }, ] [[package]] @@ -1363,27 +4538,27 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c5/58/a79003b91ac2c6890fc5d90145c662fd5771c6f11447f116b63300436bc9/typer-0.12.5.tar.gz", hash = "sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722", size = 98953 } +sdist = { url = "https://files.pythonhosted.org/packages/c5/58/a79003b91ac2c6890fc5d90145c662fd5771c6f11447f116b63300436bc9/typer-0.12.5.tar.gz", hash = "sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722", size = 98953, upload_time = "2024-08-24T21:17:57.346Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/2b/886d13e742e514f704c33c4caa7df0f3b89e5a25ef8db02aa9ca3d9535d5/typer-0.12.5-py3-none-any.whl", hash = "sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b", size = 47288 }, + { url = "https://files.pythonhosted.org/packages/a8/2b/886d13e742e514f704c33c4caa7df0f3b89e5a25ef8db02aa9ca3d9535d5/typer-0.12.5-py3-none-any.whl", hash = "sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b", size = 47288, upload_time = "2024-08-24T21:17:55.451Z" }, ] [[package]] name = "types-passlib" version = "1.7.7.20240819" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d3/19/5041c4bce2909c67fc3f9471ad67972d94c31cb591a970a8faf1220a3717/types-passlib-1.7.7.20240819.tar.gz", hash = "sha256:8fc8df71623845032293d5cf7f8091f0adfeba02d387a2888684b8413f14b3d0", size = 18386 } +sdist = { url = "https://files.pythonhosted.org/packages/d3/19/5041c4bce2909c67fc3f9471ad67972d94c31cb591a970a8faf1220a3717/types-passlib-1.7.7.20240819.tar.gz", hash = "sha256:8fc8df71623845032293d5cf7f8091f0adfeba02d387a2888684b8413f14b3d0", size = 18386, upload_time = "2024-08-19T02:32:53.107Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/4b/606ac25e89908e4577cd1aa19ffbebe55a6720cff69303db68701f3cc388/types_passlib-1.7.7.20240819-py3-none-any.whl", hash = "sha256:c4d299083497b66e12258c7b77c08952574213fdf7009da3135d8181a6a25f23", size = 33240 }, + { url = "https://files.pythonhosted.org/packages/f1/4b/606ac25e89908e4577cd1aa19ffbebe55a6720cff69303db68701f3cc388/types_passlib-1.7.7.20240819-py3-none-any.whl", hash = "sha256:c4d299083497b66e12258c7b77c08952574213fdf7009da3135d8181a6a25f23", size = 33240, upload_time = "2024-08-19T02:32:51.874Z" }, ] [[package]] name = "typing-extensions" version = "4.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload_time = "2024-06-07T18:52:15.995Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload_time = "2024-06-07T18:52:13.582Z" }, ] [[package]] @@ -1393,27 +4568,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222 } +sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload_time = "2025-02-25T17:27:59.638Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125 }, + { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload_time = "2025-02-25T17:27:57.754Z" }, ] [[package]] name = "tzdata" -version = "2024.1" +version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/74/5b/e025d02cb3b66b7b76093404392d4b44343c69101cc85f4d180dd5784717/tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd", size = 190559 } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload_time = "2025-03-23T13:54:43.652Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/65/58/f9c9e6be752e9fcb8b6a0ee9fb87e6e7a1f6bcab2cdc73f02bb7ba91ada0/tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252", size = 345370 }, + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload_time = "2025-03-23T13:54:41.845Z" }, ] [[package]] name = "urllib3" version = "2.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677, upload_time = "2024-09-12T10:52:18.401Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, + { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338, upload_time = "2024-09-12T10:52:16.589Z" }, ] [[package]] @@ -1425,9 +4600,9 @@ dependencies = [ { name = "h11" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5a/01/5e637e7aa9dd031be5376b9fb749ec20b86f5a5b6a49b87fabd374d5fa9f/uvicorn-0.30.6.tar.gz", hash = "sha256:4b15decdda1e72be08209e860a1e10e92439ad5b97cf44cc945fcbee66fc5788", size = 42825 } +sdist = { url = "https://files.pythonhosted.org/packages/5a/01/5e637e7aa9dd031be5376b9fb749ec20b86f5a5b6a49b87fabd374d5fa9f/uvicorn-0.30.6.tar.gz", hash = "sha256:4b15decdda1e72be08209e860a1e10e92439ad5b97cf44cc945fcbee66fc5788", size = 42825, upload_time = "2024-08-13T09:27:35.098Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f5/8e/cdc7d6263db313030e4c257dd5ba3909ebc4e4fb53ad62d5f09b1a2f5458/uvicorn-0.30.6-py3-none-any.whl", hash = "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5", size = 62835 }, + { url = "https://files.pythonhosted.org/packages/f5/8e/cdc7d6263db313030e4c257dd5ba3909ebc4e4fb53ad62d5f09b1a2f5458/uvicorn-0.30.6-py3-none-any.whl", hash = "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5", size = 62835, upload_time = "2024-08-13T09:27:33.536Z" }, ] [package.optional-dependencies] @@ -1445,26 +4620,35 @@ standard = [ name = "uvloop" version = "0.20.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bc/f1/dc9577455e011ad43d9379e836ee73f40b4f99c02946849a44f7ae64835e/uvloop-0.20.0.tar.gz", hash = "sha256:4603ca714a754fc8d9b197e325db25b2ea045385e8a3ad05d3463de725fdf469", size = 2329938 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/69/cc1ad125ea8ce4a4d3ba7d9836062c3fc9063cf163ddf0f168e73f3268e3/uvloop-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9ebafa0b96c62881d5cafa02d9da2e44c23f9f0cd829f3a32a6aff771449c996", size = 1363922 }, - { url = "https://files.pythonhosted.org/packages/f7/45/5a3f7a32372e4a90dfd83f30507183ec38990b8c5930ed7e36c6a15af47b/uvloop-0.20.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:35968fc697b0527a06e134999eef859b4034b37aebca537daeb598b9d45a137b", size = 760386 }, - { url = "https://files.pythonhosted.org/packages/9e/a5/9e973b25ade12c938940751bce71d0cb36efee3489014471f7d9c0a3c379/uvloop-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b16696f10e59d7580979b420eedf6650010a4a9c3bd8113f24a103dfdb770b10", size = 3432586 }, - { url = "https://files.pythonhosted.org/packages/a9/e0/0bec8a25b2e9cf14fdfcf0229637b437c923b4e5ca22f8e988363c49bb51/uvloop-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b04d96188d365151d1af41fa2d23257b674e7ead68cfd61c725a422764062ae", size = 3431802 }, - { url = "https://files.pythonhosted.org/packages/95/3b/14cef46dcec6237d858666a4a1fdb171361528c70fcd930bfc312920e7a9/uvloop-0.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94707205efbe809dfa3a0d09c08bef1352f5d3d6612a506f10a319933757c006", size = 4144444 }, - { url = "https://files.pythonhosted.org/packages/9d/5a/0ac516562ff783f760cab3b061f10fdeb4a9f985ad4b44e7e4564ff11691/uvloop-0.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:89e8d33bb88d7263f74dc57d69f0063e06b5a5ce50bb9a6b32f5fcbe655f9e73", size = 4147039 }, - { url = "https://files.pythonhosted.org/packages/64/bf/45828beccf685b7ed9638d9b77ef382b470c6ca3b5bff78067e02ffd5663/uvloop-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e50289c101495e0d1bb0bfcb4a60adde56e32f4449a67216a1ab2750aa84f037", size = 1320593 }, - { url = "https://files.pythonhosted.org/packages/27/c0/3c24e50bee7802a2add96ca9f0d5eb0ebab07e0a5615539d38aeb89499b9/uvloop-0.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e237f9c1e8a00e7d9ddaa288e535dc337a39bcbf679f290aee9d26df9e72bce9", size = 736676 }, - { url = "https://files.pythonhosted.org/packages/83/ce/ffa3c72954eae36825acfafd2b6a9221d79abd2670c0d25e04d6ef4a2007/uvloop-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:746242cd703dc2b37f9d8b9f173749c15e9a918ddb021575a0205ec29a38d31e", size = 3494573 }, - { url = "https://files.pythonhosted.org/packages/46/6d/4caab3a36199ba52b98d519feccfcf48921d7a6649daf14a93c7e77497e9/uvloop-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82edbfd3df39fb3d108fc079ebc461330f7c2e33dbd002d146bf7c445ba6e756", size = 3489932 }, - { url = "https://files.pythonhosted.org/packages/e4/4f/49c51595bd794945c88613df88922c38076eae2d7653f4624aa6f4980b07/uvloop-0.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:80dc1b139516be2077b3e57ce1cb65bfed09149e1d175e0478e7a987863b68f0", size = 4185596 }, - { url = "https://files.pythonhosted.org/packages/b8/94/7e256731260d313f5049717d1c4582d52a3b132424c95e16954a50ab95d3/uvloop-0.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4f44af67bf39af25db4c1ac27e82e9665717f9c26af2369c404be865c8818dcf", size = 4185746 }, - { url = "https://files.pythonhosted.org/packages/2d/64/31cbd379d6e260ac8de3f672f904e924f09715c3f192b09f26cc8e9f574c/uvloop-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4b75f2950ddb6feed85336412b9a0c310a2edbcf4cf931aa5cfe29034829676d", size = 1324302 }, - { url = "https://files.pythonhosted.org/packages/1e/6b/9207e7177ff30f78299401f2e1163ea41130d4fd29bcdc6d12572c06b728/uvloop-0.20.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:77fbc69c287596880ecec2d4c7a62346bef08b6209749bf6ce8c22bbaca0239e", size = 738105 }, - { url = "https://files.pythonhosted.org/packages/c1/ba/b64b10f577519d875992dc07e2365899a1a4c0d28327059ce1e1bdfb6854/uvloop-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6462c95f48e2d8d4c993a2950cd3d31ab061864d1c226bbf0ee2f1a8f36674b9", size = 4090658 }, - { url = "https://files.pythonhosted.org/packages/0a/f8/5ceea6876154d926604f10c1dd896adf9bce6d55a55911364337b8a5ed8d/uvloop-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:649c33034979273fa71aa25d0fe120ad1777c551d8c4cd2c0c9851d88fcb13ab", size = 4173357 }, - { url = "https://files.pythonhosted.org/packages/18/b2/117ab6bfb18274753fbc319607bf06e216bd7eea8be81d5bac22c912d6a7/uvloop-0.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a609780e942d43a275a617c0839d85f95c334bad29c4c0918252085113285b5", size = 4029868 }, - { url = "https://files.pythonhosted.org/packages/6f/52/deb4be09060637ef4752adaa0b75bf770c20c823e8108705792f99cd4a6f/uvloop-0.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aea15c78e0d9ad6555ed201344ae36db5c63d428818b4b2a42842b3870127c00", size = 4115980 }, +sdist = { url = "https://files.pythonhosted.org/packages/bc/f1/dc9577455e011ad43d9379e836ee73f40b4f99c02946849a44f7ae64835e/uvloop-0.20.0.tar.gz", hash = "sha256:4603ca714a754fc8d9b197e325db25b2ea045385e8a3ad05d3463de725fdf469", size = 2329938, upload_time = "2024-08-15T19:36:29.28Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/69/cc1ad125ea8ce4a4d3ba7d9836062c3fc9063cf163ddf0f168e73f3268e3/uvloop-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9ebafa0b96c62881d5cafa02d9da2e44c23f9f0cd829f3a32a6aff771449c996", size = 1363922, upload_time = "2024-08-15T19:35:38.135Z" }, + { url = "https://files.pythonhosted.org/packages/f7/45/5a3f7a32372e4a90dfd83f30507183ec38990b8c5930ed7e36c6a15af47b/uvloop-0.20.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:35968fc697b0527a06e134999eef859b4034b37aebca537daeb598b9d45a137b", size = 760386, upload_time = "2024-08-15T19:35:39.68Z" }, + { url = "https://files.pythonhosted.org/packages/9e/a5/9e973b25ade12c938940751bce71d0cb36efee3489014471f7d9c0a3c379/uvloop-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b16696f10e59d7580979b420eedf6650010a4a9c3bd8113f24a103dfdb770b10", size = 3432586, upload_time = "2024-08-15T19:35:41.513Z" }, + { url = "https://files.pythonhosted.org/packages/a9/e0/0bec8a25b2e9cf14fdfcf0229637b437c923b4e5ca22f8e988363c49bb51/uvloop-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b04d96188d365151d1af41fa2d23257b674e7ead68cfd61c725a422764062ae", size = 3431802, upload_time = "2024-08-15T19:35:43.263Z" }, + { url = "https://files.pythonhosted.org/packages/95/3b/14cef46dcec6237d858666a4a1fdb171361528c70fcd930bfc312920e7a9/uvloop-0.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94707205efbe809dfa3a0d09c08bef1352f5d3d6612a506f10a319933757c006", size = 4144444, upload_time = "2024-08-15T19:35:45.083Z" }, + { url = "https://files.pythonhosted.org/packages/9d/5a/0ac516562ff783f760cab3b061f10fdeb4a9f985ad4b44e7e4564ff11691/uvloop-0.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:89e8d33bb88d7263f74dc57d69f0063e06b5a5ce50bb9a6b32f5fcbe655f9e73", size = 4147039, upload_time = "2024-08-15T19:35:46.821Z" }, + { url = "https://files.pythonhosted.org/packages/64/bf/45828beccf685b7ed9638d9b77ef382b470c6ca3b5bff78067e02ffd5663/uvloop-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e50289c101495e0d1bb0bfcb4a60adde56e32f4449a67216a1ab2750aa84f037", size = 1320593, upload_time = "2024-08-15T19:35:48.431Z" }, + { url = "https://files.pythonhosted.org/packages/27/c0/3c24e50bee7802a2add96ca9f0d5eb0ebab07e0a5615539d38aeb89499b9/uvloop-0.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e237f9c1e8a00e7d9ddaa288e535dc337a39bcbf679f290aee9d26df9e72bce9", size = 736676, upload_time = "2024-08-15T19:35:50.296Z" }, + { url = "https://files.pythonhosted.org/packages/83/ce/ffa3c72954eae36825acfafd2b6a9221d79abd2670c0d25e04d6ef4a2007/uvloop-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:746242cd703dc2b37f9d8b9f173749c15e9a918ddb021575a0205ec29a38d31e", size = 3494573, upload_time = "2024-08-15T19:35:52.011Z" }, + { url = "https://files.pythonhosted.org/packages/46/6d/4caab3a36199ba52b98d519feccfcf48921d7a6649daf14a93c7e77497e9/uvloop-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82edbfd3df39fb3d108fc079ebc461330f7c2e33dbd002d146bf7c445ba6e756", size = 3489932, upload_time = "2024-08-15T19:35:53.599Z" }, + { url = "https://files.pythonhosted.org/packages/e4/4f/49c51595bd794945c88613df88922c38076eae2d7653f4624aa6f4980b07/uvloop-0.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:80dc1b139516be2077b3e57ce1cb65bfed09149e1d175e0478e7a987863b68f0", size = 4185596, upload_time = "2024-08-15T19:35:55.416Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/7e256731260d313f5049717d1c4582d52a3b132424c95e16954a50ab95d3/uvloop-0.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4f44af67bf39af25db4c1ac27e82e9665717f9c26af2369c404be865c8818dcf", size = 4185746, upload_time = "2024-08-15T19:35:56.96Z" }, + { url = "https://files.pythonhosted.org/packages/2d/64/31cbd379d6e260ac8de3f672f904e924f09715c3f192b09f26cc8e9f574c/uvloop-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4b75f2950ddb6feed85336412b9a0c310a2edbcf4cf931aa5cfe29034829676d", size = 1324302, upload_time = "2024-08-15T19:35:58.384Z" }, + { url = "https://files.pythonhosted.org/packages/1e/6b/9207e7177ff30f78299401f2e1163ea41130d4fd29bcdc6d12572c06b728/uvloop-0.20.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:77fbc69c287596880ecec2d4c7a62346bef08b6209749bf6ce8c22bbaca0239e", size = 738105, upload_time = "2024-08-15T19:36:00.106Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ba/b64b10f577519d875992dc07e2365899a1a4c0d28327059ce1e1bdfb6854/uvloop-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6462c95f48e2d8d4c993a2950cd3d31ab061864d1c226bbf0ee2f1a8f36674b9", size = 4090658, upload_time = "2024-08-15T19:36:01.423Z" }, + { url = "https://files.pythonhosted.org/packages/0a/f8/5ceea6876154d926604f10c1dd896adf9bce6d55a55911364337b8a5ed8d/uvloop-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:649c33034979273fa71aa25d0fe120ad1777c551d8c4cd2c0c9851d88fcb13ab", size = 4173357, upload_time = "2024-08-15T19:36:03.367Z" }, + { url = "https://files.pythonhosted.org/packages/18/b2/117ab6bfb18274753fbc319607bf06e216bd7eea8be81d5bac22c912d6a7/uvloop-0.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a609780e942d43a275a617c0839d85f95c334bad29c4c0918252085113285b5", size = 4029868, upload_time = "2024-08-15T19:36:05.035Z" }, + { url = "https://files.pythonhosted.org/packages/6f/52/deb4be09060637ef4752adaa0b75bf770c20c823e8108705792f99cd4a6f/uvloop-0.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aea15c78e0d9ad6555ed201344ae36db5c63d428818b4b2a42842b3870127c00", size = 4115980, upload_time = "2024-08-15T19:36:07.376Z" }, +] + +[[package]] +name = "vine" +version = "5.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/e4/d07b5f29d283596b9727dd5275ccbceb63c44a1a82aa9e4bfd20426762ac/vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0", size = 48980, upload_time = "2023-11-05T08:46:53.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/ff/7c0c86c43b3cbb927e0ccc0255cb4057ceba4799cd44ae95174ce8e8b5b2/vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc", size = 9636, upload_time = "2023-11-05T08:46:51.205Z" }, ] [[package]] @@ -1476,9 +4660,21 @@ dependencies = [ { name = "filelock" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/4c/66ce54c8736ff164e85117ca36b02a1e14c042a6963f85eeda82664fda4e/virtualenv-20.26.5.tar.gz", hash = "sha256:ce489cac131aa58f4b25e321d6d186171f78e6cb13fafbf32a840cee67733ff4", size = 9371932 } +sdist = { url = "https://files.pythonhosted.org/packages/bf/4c/66ce54c8736ff164e85117ca36b02a1e14c042a6963f85eeda82664fda4e/virtualenv-20.26.5.tar.gz", hash = "sha256:ce489cac131aa58f4b25e321d6d186171f78e6cb13fafbf32a840cee67733ff4", size = 9371932, upload_time = "2024-09-17T21:48:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/1d/e1a44fdd6d30829ba21fc58b5d98a67e7aae8f4165f11d091e53aec12560/virtualenv-20.26.5-py3-none-any.whl", hash = "sha256:4f3ac17b81fba3ce3bd6f4ead2749a72da5929c01774948e243db9ba41df4ff6", size = 5999288, upload_time = "2024-09-17T21:48:51.283Z" }, +] + +[[package]] +name = "wasabi" +version = "1.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/f9/054e6e2f1071e963b5e746b48d1e3727470b2a490834d18ad92364929db3/wasabi-1.1.3.tar.gz", hash = "sha256:4bb3008f003809db0c3e28b4daf20906ea871a2bb43f9914197d540f4f2e0878", size = 30391, upload_time = "2024-05-31T16:56:18.99Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/1d/e1a44fdd6d30829ba21fc58b5d98a67e7aae8f4165f11d091e53aec12560/virtualenv-20.26.5-py3-none-any.whl", hash = "sha256:4f3ac17b81fba3ce3bd6f4ead2749a72da5929c01774948e243db9ba41df4ff6", size = 5999288 }, + { url = "https://files.pythonhosted.org/packages/06/7c/34330a89da55610daa5f245ddce5aab81244321101614751e7537f125133/wasabi-1.1.3-py3-none-any.whl", hash = "sha256:f76e16e8f7e79f8c4c8be49b4024ac725713ab10cd7f19350ad18a8e3f71728c", size = 27880, upload_time = "2024-05-31T16:56:16.699Z" }, ] [[package]] @@ -1488,119 +4684,314 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c8/27/2ba23c8cc85796e2d41976439b08d52f691655fdb9401362099502d1f0cf/watchfiles-0.24.0.tar.gz", hash = "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1", size = 37870 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/a1/631c12626378b9f1538664aa221feb5c60dfafbd7f60b451f8d0bdbcdedd/watchfiles-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0", size = 375096 }, - { url = "https://files.pythonhosted.org/packages/f7/5c/f27c979c8a10aaa2822286c1bffdce3db731cd1aa4224b9f86623e94bbfe/watchfiles-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c", size = 367425 }, - { url = "https://files.pythonhosted.org/packages/74/0d/1889e5649885484d29f6c792ef274454d0a26b20d6ed5fdba5409335ccb6/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361", size = 437705 }, - { url = "https://files.pythonhosted.org/packages/85/8a/01d9a22e839f0d1d547af11b1fcac6ba6f889513f1b2e6f221d9d60d9585/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3", size = 433636 }, - { url = "https://files.pythonhosted.org/packages/62/32/a93db78d340c7ef86cde469deb20e36c6b2a873edee81f610e94bbba4e06/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571", size = 451069 }, - { url = "https://files.pythonhosted.org/packages/99/c2/e9e2754fae3c2721c9a7736f92dab73723f1968ed72535fff29e70776008/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd", size = 469306 }, - { url = "https://files.pythonhosted.org/packages/4c/45/f317d9e3affb06c3c27c478de99f7110143e87f0f001f0f72e18d0e1ddce/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a", size = 476187 }, - { url = "https://files.pythonhosted.org/packages/ac/d3/f1f37248abe0114916921e638f71c7d21fe77e3f2f61750e8057d0b68ef2/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e", size = 425743 }, - { url = "https://files.pythonhosted.org/packages/2b/e8/c7037ea38d838fd81a59cd25761f106ee3ef2cfd3261787bee0c68908171/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c", size = 612327 }, - { url = "https://files.pythonhosted.org/packages/a0/c5/0e6e228aafe01a7995fbfd2a4edb221bb11a2744803b65a5663fb85e5063/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188", size = 595096 }, - { url = "https://files.pythonhosted.org/packages/63/d5/4780e8bf3de3b4b46e7428a29654f7dc041cad6b19fd86d083e4b6f64bbe/watchfiles-0.24.0-cp310-none-win32.whl", hash = "sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735", size = 264149 }, - { url = "https://files.pythonhosted.org/packages/fe/1b/5148898ba55fc9c111a2a4a5fb67ad3fa7eb2b3d7f0618241ed88749313d/watchfiles-0.24.0-cp310-none-win_amd64.whl", hash = "sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04", size = 277542 }, - { url = "https://files.pythonhosted.org/packages/85/02/366ae902cd81ca5befcd1854b5c7477b378f68861597cef854bd6dc69fbe/watchfiles-0.24.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428", size = 375579 }, - { url = "https://files.pythonhosted.org/packages/bc/67/d8c9d256791fe312fea118a8a051411337c948101a24586e2df237507976/watchfiles-0.24.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c", size = 367726 }, - { url = "https://files.pythonhosted.org/packages/b1/dc/a8427b21ef46386adf824a9fec4be9d16a475b850616cfd98cf09a97a2ef/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43", size = 437735 }, - { url = "https://files.pythonhosted.org/packages/3a/21/0b20bef581a9fbfef290a822c8be645432ceb05fb0741bf3c032e0d90d9a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327", size = 433644 }, - { url = "https://files.pythonhosted.org/packages/1c/e8/d5e5f71cc443c85a72e70b24269a30e529227986096abe091040d6358ea9/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5", size = 450928 }, - { url = "https://files.pythonhosted.org/packages/61/ee/bf17f5a370c2fcff49e1fec987a6a43fd798d8427ea754ce45b38f9e117a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61", size = 469072 }, - { url = "https://files.pythonhosted.org/packages/a3/34/03b66d425986de3fc6077e74a74c78da298f8cb598887f664a4485e55543/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15", size = 475517 }, - { url = "https://files.pythonhosted.org/packages/70/eb/82f089c4f44b3171ad87a1b433abb4696f18eb67292909630d886e073abe/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823", size = 425480 }, - { url = "https://files.pythonhosted.org/packages/53/20/20509c8f5291e14e8a13104b1808cd7cf5c44acd5feaecb427a49d387774/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab", size = 612322 }, - { url = "https://files.pythonhosted.org/packages/df/2b/5f65014a8cecc0a120f5587722068a975a692cadbe9fe4ea56b3d8e43f14/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec", size = 595094 }, - { url = "https://files.pythonhosted.org/packages/18/98/006d8043a82c0a09d282d669c88e587b3a05cabdd7f4900e402250a249ac/watchfiles-0.24.0-cp311-none-win32.whl", hash = "sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d", size = 264191 }, - { url = "https://files.pythonhosted.org/packages/8a/8b/badd9247d6ec25f5f634a9b3d0d92e39c045824ec7e8afcedca8ee52c1e2/watchfiles-0.24.0-cp311-none-win_amd64.whl", hash = "sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c", size = 277527 }, - { url = "https://files.pythonhosted.org/packages/af/19/35c957c84ee69d904299a38bae3614f7cede45f07f174f6d5a2f4dbd6033/watchfiles-0.24.0-cp311-none-win_arm64.whl", hash = "sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633", size = 266253 }, - { url = "https://files.pythonhosted.org/packages/35/82/92a7bb6dc82d183e304a5f84ae5437b59ee72d48cee805a9adda2488b237/watchfiles-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a", size = 374137 }, - { url = "https://files.pythonhosted.org/packages/87/91/49e9a497ddaf4da5e3802d51ed67ff33024597c28f652b8ab1e7c0f5718b/watchfiles-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370", size = 367733 }, - { url = "https://files.pythonhosted.org/packages/0d/d8/90eb950ab4998effea2df4cf3a705dc594f6bc501c5a353073aa990be965/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6", size = 437322 }, - { url = "https://files.pythonhosted.org/packages/6c/a2/300b22e7bc2a222dd91fce121cefa7b49aa0d26a627b2777e7bdfcf1110b/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b", size = 433409 }, - { url = "https://files.pythonhosted.org/packages/99/44/27d7708a43538ed6c26708bcccdde757da8b7efb93f4871d4cc39cffa1cc/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e", size = 452142 }, - { url = "https://files.pythonhosted.org/packages/b0/ec/c4e04f755be003129a2c5f3520d2c47026f00da5ecb9ef1e4f9449637571/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea", size = 469414 }, - { url = "https://files.pythonhosted.org/packages/c5/4e/cdd7de3e7ac6432b0abf282ec4c1a1a2ec62dfe423cf269b86861667752d/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f", size = 472962 }, - { url = "https://files.pythonhosted.org/packages/27/69/e1da9d34da7fc59db358424f5d89a56aaafe09f6961b64e36457a80a7194/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234", size = 425705 }, - { url = "https://files.pythonhosted.org/packages/e8/c1/24d0f7357be89be4a43e0a656259676ea3d7a074901f47022f32e2957798/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef", size = 612851 }, - { url = "https://files.pythonhosted.org/packages/c7/af/175ba9b268dec56f821639c9893b506c69fd999fe6a2e2c51de420eb2f01/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968", size = 594868 }, - { url = "https://files.pythonhosted.org/packages/44/81/1f701323a9f70805bc81c74c990137123344a80ea23ab9504a99492907f8/watchfiles-0.24.0-cp312-none-win32.whl", hash = "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444", size = 264109 }, - { url = "https://files.pythonhosted.org/packages/b4/0b/32cde5bc2ebd9f351be326837c61bdeb05ad652b793f25c91cac0b48a60b/watchfiles-0.24.0-cp312-none-win_amd64.whl", hash = "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896", size = 277055 }, - { url = "https://files.pythonhosted.org/packages/4b/81/daade76ce33d21dbec7a15afd7479de8db786e5f7b7d249263b4ea174e08/watchfiles-0.24.0-cp312-none-win_arm64.whl", hash = "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418", size = 266169 }, - { url = "https://files.pythonhosted.org/packages/30/dc/6e9f5447ae14f645532468a84323a942996d74d5e817837a5c8ce9d16c69/watchfiles-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48", size = 373764 }, - { url = "https://files.pythonhosted.org/packages/79/c0/c3a9929c372816c7fc87d8149bd722608ea58dc0986d3ef7564c79ad7112/watchfiles-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90", size = 367873 }, - { url = "https://files.pythonhosted.org/packages/2e/11/ff9a4445a7cfc1c98caf99042df38964af12eed47d496dd5d0d90417349f/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94", size = 438381 }, - { url = "https://files.pythonhosted.org/packages/48/a3/763ba18c98211d7bb6c0f417b2d7946d346cdc359d585cc28a17b48e964b/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e", size = 432809 }, - { url = "https://files.pythonhosted.org/packages/30/4c/616c111b9d40eea2547489abaf4ffc84511e86888a166d3a4522c2ba44b5/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827", size = 451801 }, - { url = "https://files.pythonhosted.org/packages/b6/be/d7da83307863a422abbfeb12903a76e43200c90ebe5d6afd6a59d158edea/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df", size = 468886 }, - { url = "https://files.pythonhosted.org/packages/1d/d3/3dfe131ee59d5e90b932cf56aba5c996309d94dafe3d02d204364c23461c/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab", size = 472973 }, - { url = "https://files.pythonhosted.org/packages/42/6c/279288cc5653a289290d183b60a6d80e05f439d5bfdfaf2d113738d0f932/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f", size = 425282 }, - { url = "https://files.pythonhosted.org/packages/d6/d7/58afe5e85217e845edf26d8780c2d2d2ae77675eeb8d1b8b8121d799ce52/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b", size = 612540 }, - { url = "https://files.pythonhosted.org/packages/6d/d5/b96eeb9fe3fda137200dd2f31553670cbc731b1e13164fd69b49870b76ec/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18", size = 593625 }, - { url = "https://files.pythonhosted.org/packages/c1/e5/c326fe52ee0054107267608d8cea275e80be4455b6079491dfd9da29f46f/watchfiles-0.24.0-cp313-none-win32.whl", hash = "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07", size = 263899 }, - { url = "https://files.pythonhosted.org/packages/a6/8b/8a7755c5e7221bb35fe4af2dc44db9174f90ebf0344fd5e9b1e8b42d381e/watchfiles-0.24.0-cp313-none-win_amd64.whl", hash = "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366", size = 276622 }, - { url = "https://files.pythonhosted.org/packages/df/94/1ad200e937ec91b2a9d6b39ae1cf9c2b1a9cc88d5ceb43aa5c6962eb3c11/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f", size = 376986 }, - { url = "https://files.pythonhosted.org/packages/ee/fd/d9e020d687ccf90fe95efc513fbb39a8049cf5a3ff51f53c59fcf4c47a5d/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b", size = 369445 }, - { url = "https://files.pythonhosted.org/packages/43/cb/c0279b35053555d10ef03559c5aebfcb0c703d9c70a7b4e532df74b9b0e8/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4", size = 439383 }, - { url = "https://files.pythonhosted.org/packages/8b/c4/08b3c2cda45db5169148a981c2100c744a4a222fa7ae7644937c0c002069/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a", size = 426804 }, +sdist = { url = "https://files.pythonhosted.org/packages/c8/27/2ba23c8cc85796e2d41976439b08d52f691655fdb9401362099502d1f0cf/watchfiles-0.24.0.tar.gz", hash = "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1", size = 37870, upload_time = "2024-08-28T16:21:37.42Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/a1/631c12626378b9f1538664aa221feb5c60dfafbd7f60b451f8d0bdbcdedd/watchfiles-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0", size = 375096, upload_time = "2024-08-28T16:19:47.704Z" }, + { url = "https://files.pythonhosted.org/packages/f7/5c/f27c979c8a10aaa2822286c1bffdce3db731cd1aa4224b9f86623e94bbfe/watchfiles-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c", size = 367425, upload_time = "2024-08-28T16:19:49.66Z" }, + { url = "https://files.pythonhosted.org/packages/74/0d/1889e5649885484d29f6c792ef274454d0a26b20d6ed5fdba5409335ccb6/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361", size = 437705, upload_time = "2024-08-28T16:19:51.068Z" }, + { url = "https://files.pythonhosted.org/packages/85/8a/01d9a22e839f0d1d547af11b1fcac6ba6f889513f1b2e6f221d9d60d9585/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3", size = 433636, upload_time = "2024-08-28T16:19:52.799Z" }, + { url = "https://files.pythonhosted.org/packages/62/32/a93db78d340c7ef86cde469deb20e36c6b2a873edee81f610e94bbba4e06/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571", size = 451069, upload_time = "2024-08-28T16:19:54.111Z" }, + { url = "https://files.pythonhosted.org/packages/99/c2/e9e2754fae3c2721c9a7736f92dab73723f1968ed72535fff29e70776008/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd", size = 469306, upload_time = "2024-08-28T16:19:55.616Z" }, + { url = "https://files.pythonhosted.org/packages/4c/45/f317d9e3affb06c3c27c478de99f7110143e87f0f001f0f72e18d0e1ddce/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a", size = 476187, upload_time = "2024-08-28T16:19:56.915Z" }, + { url = "https://files.pythonhosted.org/packages/ac/d3/f1f37248abe0114916921e638f71c7d21fe77e3f2f61750e8057d0b68ef2/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e", size = 425743, upload_time = "2024-08-28T16:19:57.957Z" }, + { url = "https://files.pythonhosted.org/packages/2b/e8/c7037ea38d838fd81a59cd25761f106ee3ef2cfd3261787bee0c68908171/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c", size = 612327, upload_time = "2024-08-28T16:19:59.4Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c5/0e6e228aafe01a7995fbfd2a4edb221bb11a2744803b65a5663fb85e5063/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188", size = 595096, upload_time = "2024-08-28T16:20:01.003Z" }, + { url = "https://files.pythonhosted.org/packages/63/d5/4780e8bf3de3b4b46e7428a29654f7dc041cad6b19fd86d083e4b6f64bbe/watchfiles-0.24.0-cp310-none-win32.whl", hash = "sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735", size = 264149, upload_time = "2024-08-28T16:20:02.833Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1b/5148898ba55fc9c111a2a4a5fb67ad3fa7eb2b3d7f0618241ed88749313d/watchfiles-0.24.0-cp310-none-win_amd64.whl", hash = "sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04", size = 277542, upload_time = "2024-08-28T16:20:03.876Z" }, + { url = "https://files.pythonhosted.org/packages/85/02/366ae902cd81ca5befcd1854b5c7477b378f68861597cef854bd6dc69fbe/watchfiles-0.24.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428", size = 375579, upload_time = "2024-08-28T16:20:04.865Z" }, + { url = "https://files.pythonhosted.org/packages/bc/67/d8c9d256791fe312fea118a8a051411337c948101a24586e2df237507976/watchfiles-0.24.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c", size = 367726, upload_time = "2024-08-28T16:20:06.111Z" }, + { url = "https://files.pythonhosted.org/packages/b1/dc/a8427b21ef46386adf824a9fec4be9d16a475b850616cfd98cf09a97a2ef/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43", size = 437735, upload_time = "2024-08-28T16:20:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/3a/21/0b20bef581a9fbfef290a822c8be645432ceb05fb0741bf3c032e0d90d9a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327", size = 433644, upload_time = "2024-08-28T16:20:09.15Z" }, + { url = "https://files.pythonhosted.org/packages/1c/e8/d5e5f71cc443c85a72e70b24269a30e529227986096abe091040d6358ea9/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5", size = 450928, upload_time = "2024-08-28T16:20:11.152Z" }, + { url = "https://files.pythonhosted.org/packages/61/ee/bf17f5a370c2fcff49e1fec987a6a43fd798d8427ea754ce45b38f9e117a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61", size = 469072, upload_time = "2024-08-28T16:20:12.345Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/03b66d425986de3fc6077e74a74c78da298f8cb598887f664a4485e55543/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15", size = 475517, upload_time = "2024-08-28T16:20:13.555Z" }, + { url = "https://files.pythonhosted.org/packages/70/eb/82f089c4f44b3171ad87a1b433abb4696f18eb67292909630d886e073abe/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823", size = 425480, upload_time = "2024-08-28T16:20:15.037Z" }, + { url = "https://files.pythonhosted.org/packages/53/20/20509c8f5291e14e8a13104b1808cd7cf5c44acd5feaecb427a49d387774/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab", size = 612322, upload_time = "2024-08-28T16:20:16.095Z" }, + { url = "https://files.pythonhosted.org/packages/df/2b/5f65014a8cecc0a120f5587722068a975a692cadbe9fe4ea56b3d8e43f14/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec", size = 595094, upload_time = "2024-08-28T16:20:17.395Z" }, + { url = "https://files.pythonhosted.org/packages/18/98/006d8043a82c0a09d282d669c88e587b3a05cabdd7f4900e402250a249ac/watchfiles-0.24.0-cp311-none-win32.whl", hash = "sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d", size = 264191, upload_time = "2024-08-28T16:20:18.472Z" }, + { url = "https://files.pythonhosted.org/packages/8a/8b/badd9247d6ec25f5f634a9b3d0d92e39c045824ec7e8afcedca8ee52c1e2/watchfiles-0.24.0-cp311-none-win_amd64.whl", hash = "sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c", size = 277527, upload_time = "2024-08-28T16:20:20.096Z" }, + { url = "https://files.pythonhosted.org/packages/af/19/35c957c84ee69d904299a38bae3614f7cede45f07f174f6d5a2f4dbd6033/watchfiles-0.24.0-cp311-none-win_arm64.whl", hash = "sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633", size = 266253, upload_time = "2024-08-28T16:20:21.381Z" }, + { url = "https://files.pythonhosted.org/packages/35/82/92a7bb6dc82d183e304a5f84ae5437b59ee72d48cee805a9adda2488b237/watchfiles-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a", size = 374137, upload_time = "2024-08-28T16:20:23.055Z" }, + { url = "https://files.pythonhosted.org/packages/87/91/49e9a497ddaf4da5e3802d51ed67ff33024597c28f652b8ab1e7c0f5718b/watchfiles-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370", size = 367733, upload_time = "2024-08-28T16:20:24.543Z" }, + { url = "https://files.pythonhosted.org/packages/0d/d8/90eb950ab4998effea2df4cf3a705dc594f6bc501c5a353073aa990be965/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6", size = 437322, upload_time = "2024-08-28T16:20:25.572Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a2/300b22e7bc2a222dd91fce121cefa7b49aa0d26a627b2777e7bdfcf1110b/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b", size = 433409, upload_time = "2024-08-28T16:20:26.628Z" }, + { url = "https://files.pythonhosted.org/packages/99/44/27d7708a43538ed6c26708bcccdde757da8b7efb93f4871d4cc39cffa1cc/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e", size = 452142, upload_time = "2024-08-28T16:20:28.003Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ec/c4e04f755be003129a2c5f3520d2c47026f00da5ecb9ef1e4f9449637571/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea", size = 469414, upload_time = "2024-08-28T16:20:29.55Z" }, + { url = "https://files.pythonhosted.org/packages/c5/4e/cdd7de3e7ac6432b0abf282ec4c1a1a2ec62dfe423cf269b86861667752d/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f", size = 472962, upload_time = "2024-08-28T16:20:31.314Z" }, + { url = "https://files.pythonhosted.org/packages/27/69/e1da9d34da7fc59db358424f5d89a56aaafe09f6961b64e36457a80a7194/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234", size = 425705, upload_time = "2024-08-28T16:20:32.427Z" }, + { url = "https://files.pythonhosted.org/packages/e8/c1/24d0f7357be89be4a43e0a656259676ea3d7a074901f47022f32e2957798/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef", size = 612851, upload_time = "2024-08-28T16:20:33.527Z" }, + { url = "https://files.pythonhosted.org/packages/c7/af/175ba9b268dec56f821639c9893b506c69fd999fe6a2e2c51de420eb2f01/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968", size = 594868, upload_time = "2024-08-28T16:20:34.639Z" }, + { url = "https://files.pythonhosted.org/packages/44/81/1f701323a9f70805bc81c74c990137123344a80ea23ab9504a99492907f8/watchfiles-0.24.0-cp312-none-win32.whl", hash = "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444", size = 264109, upload_time = "2024-08-28T16:20:35.692Z" }, + { url = "https://files.pythonhosted.org/packages/b4/0b/32cde5bc2ebd9f351be326837c61bdeb05ad652b793f25c91cac0b48a60b/watchfiles-0.24.0-cp312-none-win_amd64.whl", hash = "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896", size = 277055, upload_time = "2024-08-28T16:20:36.849Z" }, + { url = "https://files.pythonhosted.org/packages/4b/81/daade76ce33d21dbec7a15afd7479de8db786e5f7b7d249263b4ea174e08/watchfiles-0.24.0-cp312-none-win_arm64.whl", hash = "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418", size = 266169, upload_time = "2024-08-28T16:20:38.149Z" }, + { url = "https://files.pythonhosted.org/packages/30/dc/6e9f5447ae14f645532468a84323a942996d74d5e817837a5c8ce9d16c69/watchfiles-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48", size = 373764, upload_time = "2024-08-28T16:20:39.263Z" }, + { url = "https://files.pythonhosted.org/packages/79/c0/c3a9929c372816c7fc87d8149bd722608ea58dc0986d3ef7564c79ad7112/watchfiles-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90", size = 367873, upload_time = "2024-08-28T16:20:40.399Z" }, + { url = "https://files.pythonhosted.org/packages/2e/11/ff9a4445a7cfc1c98caf99042df38964af12eed47d496dd5d0d90417349f/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94", size = 438381, upload_time = "2024-08-28T16:20:41.371Z" }, + { url = "https://files.pythonhosted.org/packages/48/a3/763ba18c98211d7bb6c0f417b2d7946d346cdc359d585cc28a17b48e964b/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e", size = 432809, upload_time = "2024-08-28T16:20:42.504Z" }, + { url = "https://files.pythonhosted.org/packages/30/4c/616c111b9d40eea2547489abaf4ffc84511e86888a166d3a4522c2ba44b5/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827", size = 451801, upload_time = "2024-08-28T16:20:43.696Z" }, + { url = "https://files.pythonhosted.org/packages/b6/be/d7da83307863a422abbfeb12903a76e43200c90ebe5d6afd6a59d158edea/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df", size = 468886, upload_time = "2024-08-28T16:20:44.847Z" }, + { url = "https://files.pythonhosted.org/packages/1d/d3/3dfe131ee59d5e90b932cf56aba5c996309d94dafe3d02d204364c23461c/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab", size = 472973, upload_time = "2024-08-28T16:20:45.991Z" }, + { url = "https://files.pythonhosted.org/packages/42/6c/279288cc5653a289290d183b60a6d80e05f439d5bfdfaf2d113738d0f932/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f", size = 425282, upload_time = "2024-08-28T16:20:47.579Z" }, + { url = "https://files.pythonhosted.org/packages/d6/d7/58afe5e85217e845edf26d8780c2d2d2ae77675eeb8d1b8b8121d799ce52/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b", size = 612540, upload_time = "2024-08-28T16:20:48.915Z" }, + { url = "https://files.pythonhosted.org/packages/6d/d5/b96eeb9fe3fda137200dd2f31553670cbc731b1e13164fd69b49870b76ec/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18", size = 593625, upload_time = "2024-08-28T16:20:50.543Z" }, + { url = "https://files.pythonhosted.org/packages/c1/e5/c326fe52ee0054107267608d8cea275e80be4455b6079491dfd9da29f46f/watchfiles-0.24.0-cp313-none-win32.whl", hash = "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07", size = 263899, upload_time = "2024-08-28T16:20:51.759Z" }, + { url = "https://files.pythonhosted.org/packages/a6/8b/8a7755c5e7221bb35fe4af2dc44db9174f90ebf0344fd5e9b1e8b42d381e/watchfiles-0.24.0-cp313-none-win_amd64.whl", hash = "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366", size = 276622, upload_time = "2024-08-28T16:20:52.82Z" }, + { url = "https://files.pythonhosted.org/packages/df/94/1ad200e937ec91b2a9d6b39ae1cf9c2b1a9cc88d5ceb43aa5c6962eb3c11/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f", size = 376986, upload_time = "2024-08-28T16:21:26.895Z" }, + { url = "https://files.pythonhosted.org/packages/ee/fd/d9e020d687ccf90fe95efc513fbb39a8049cf5a3ff51f53c59fcf4c47a5d/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b", size = 369445, upload_time = "2024-08-28T16:21:28.157Z" }, + { url = "https://files.pythonhosted.org/packages/43/cb/c0279b35053555d10ef03559c5aebfcb0c703d9c70a7b4e532df74b9b0e8/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4", size = 439383, upload_time = "2024-08-28T16:21:29.515Z" }, + { url = "https://files.pythonhosted.org/packages/8b/c4/08b3c2cda45db5169148a981c2100c744a4a222fa7ae7644937c0c002069/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a", size = 426804, upload_time = "2024-08-28T16:21:30.687Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload_time = "2024-01-06T02:10:57.829Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload_time = "2024-01-06T02:10:55.763Z" }, +] + +[[package]] +name = "weasel" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cloudpathlib" }, + { name = "confection" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "smart-open" }, + { name = "srsly" }, + { name = "typer" }, + { name = "wasabi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/1a/9c522dd61b52939c217925d3e55c95f9348b73a66a956f52608e1e59a2c0/weasel-0.4.1.tar.gz", hash = "sha256:aabc210f072e13f6744e5c3a28037f93702433405cd35673f7c6279147085aa9", size = 38417, upload_time = "2024-05-15T08:52:54.765Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/87/abd57374044e1f627f0a905ac33c1a7daab35a3a815abfea4e1bafd3fdb1/weasel-0.4.1-py3-none-any.whl", hash = "sha256:24140a090ea1ac512a2b2f479cc64192fd1d527a7f3627671268d08ed5ac418c", size = 50270, upload_time = "2024-05-15T08:52:52.977Z" }, +] + +[[package]] +name = "websocket-client" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648, upload_time = "2024-04-23T22:16:16.976Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload_time = "2024-04-23T22:16:14.422Z" }, ] [[package]] name = "websockets" version = "13.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e2/73/9223dbc7be3dcaf2a7bbf756c351ec8da04b1fa573edaf545b95f6b0c7fd/websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878", size = 158549 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/94/d15dbfc6a5eb636dbc754303fba18208f2e88cf97e733e1d64fb9cb5c89e/websockets-13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee", size = 157815 }, - { url = "https://files.pythonhosted.org/packages/30/02/c04af33f4663945a26f5e8cf561eb140c35452b50af47a83c3fbcfe62ae1/websockets-13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7", size = 155466 }, - { url = "https://files.pythonhosted.org/packages/35/e8/719f08d12303ea643655e52d9e9851b2dadbb1991d4926d9ce8862efa2f5/websockets-13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6", size = 155716 }, - { url = "https://files.pythonhosted.org/packages/91/e1/14963ae0252a8925f7434065d25dcd4701d5e281a0b4b460a3b5963d2594/websockets-13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b", size = 164806 }, - { url = "https://files.pythonhosted.org/packages/ec/fa/ab28441bae5e682a0f7ddf3d03440c0c352f930da419301f4a717f675ef3/websockets-13.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa", size = 163810 }, - { url = "https://files.pythonhosted.org/packages/44/77/dea187bd9d16d4b91566a2832be31f99a40d0f5bfa55eeb638eb2c3bc33d/websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700", size = 164125 }, - { url = "https://files.pythonhosted.org/packages/cf/d9/3af14544e83f1437eb684b399e6ba0fa769438e869bf5d83d74bc197fae8/websockets-13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c", size = 164532 }, - { url = "https://files.pythonhosted.org/packages/1c/8a/6d332eabe7d59dfefe4b8ba6f46c8c5fabb15b71c8a8bc3d2b65de19a7b6/websockets-13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0", size = 163948 }, - { url = "https://files.pythonhosted.org/packages/1a/91/a0aeadbaf3017467a1ee03f8fb67accdae233fe2d5ad4b038c0a84e357b0/websockets-13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f", size = 163898 }, - { url = "https://files.pythonhosted.org/packages/71/31/a90fb47c63e0ae605be914b0b969d7c6e6ffe2038cd744798e4b3fbce53b/websockets-13.1-cp310-cp310-win32.whl", hash = "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe", size = 158706 }, - { url = "https://files.pythonhosted.org/packages/93/ca/9540a9ba80da04dc7f36d790c30cae4252589dbd52ccdc92e75b0be22437/websockets-13.1-cp310-cp310-win_amd64.whl", hash = "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a", size = 159141 }, - { url = "https://files.pythonhosted.org/packages/b2/f0/cf0b8a30d86b49e267ac84addbebbc7a48a6e7bb7c19db80f62411452311/websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19", size = 157813 }, - { url = "https://files.pythonhosted.org/packages/bf/e7/22285852502e33071a8cf0ac814f8988480ec6db4754e067b8b9d0e92498/websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5", size = 155469 }, - { url = "https://files.pythonhosted.org/packages/68/d4/c8c7c1e5b40ee03c5cc235955b0fb1ec90e7e37685a5f69229ad4708dcde/websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd", size = 155717 }, - { url = "https://files.pythonhosted.org/packages/c9/e4/c50999b9b848b1332b07c7fd8886179ac395cb766fda62725d1539e7bc6c/websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02", size = 165379 }, - { url = "https://files.pythonhosted.org/packages/bc/49/4a4ad8c072f18fd79ab127650e47b160571aacfc30b110ee305ba25fffc9/websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7", size = 164376 }, - { url = "https://files.pythonhosted.org/packages/af/9b/8c06d425a1d5a74fd764dd793edd02be18cf6fc3b1ccd1f29244ba132dc0/websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096", size = 164753 }, - { url = "https://files.pythonhosted.org/packages/d5/5b/0acb5815095ff800b579ffc38b13ab1b915b317915023748812d24e0c1ac/websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084", size = 165051 }, - { url = "https://files.pythonhosted.org/packages/30/93/c3891c20114eacb1af09dedfcc620c65c397f4fd80a7009cd12d9457f7f5/websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3", size = 164489 }, - { url = "https://files.pythonhosted.org/packages/28/09/af9e19885539759efa2e2cd29b8b3f9eecef7ecefea40d46612f12138b36/websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9", size = 164438 }, - { url = "https://files.pythonhosted.org/packages/b6/08/6f38b8e625b3d93de731f1d248cc1493327f16cb45b9645b3e791782cff0/websockets-13.1-cp311-cp311-win32.whl", hash = "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f", size = 158710 }, - { url = "https://files.pythonhosted.org/packages/fb/39/ec8832ecb9bb04a8d318149005ed8cee0ba4e0205835da99e0aa497a091f/websockets-13.1-cp311-cp311-win_amd64.whl", hash = "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557", size = 159137 }, - { url = "https://files.pythonhosted.org/packages/df/46/c426282f543b3c0296cf964aa5a7bb17e984f58dde23460c3d39b3148fcf/websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc", size = 157821 }, - { url = "https://files.pythonhosted.org/packages/aa/85/22529867010baac258da7c45848f9415e6cf37fef00a43856627806ffd04/websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49", size = 155480 }, - { url = "https://files.pythonhosted.org/packages/29/2c/bdb339bfbde0119a6e84af43ebf6275278698a2241c2719afc0d8b0bdbf2/websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd", size = 155715 }, - { url = "https://files.pythonhosted.org/packages/9f/d0/8612029ea04c5c22bf7af2fd3d63876c4eaeef9b97e86c11972a43aa0e6c/websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0", size = 165647 }, - { url = "https://files.pythonhosted.org/packages/56/04/1681ed516fa19ca9083f26d3f3a302257e0911ba75009533ed60fbb7b8d1/websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6", size = 164592 }, - { url = "https://files.pythonhosted.org/packages/38/6f/a96417a49c0ed132bb6087e8e39a37db851c70974f5c724a4b2a70066996/websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9", size = 165012 }, - { url = "https://files.pythonhosted.org/packages/40/8b/fccf294919a1b37d190e86042e1a907b8f66cff2b61e9befdbce03783e25/websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68", size = 165311 }, - { url = "https://files.pythonhosted.org/packages/c1/61/f8615cf7ce5fe538476ab6b4defff52beb7262ff8a73d5ef386322d9761d/websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14", size = 164692 }, - { url = "https://files.pythonhosted.org/packages/5c/f1/a29dd6046d3a722d26f182b783a7997d25298873a14028c4760347974ea3/websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", size = 164686 }, - { url = "https://files.pythonhosted.org/packages/0f/99/ab1cdb282f7e595391226f03f9b498f52109d25a2ba03832e21614967dfa/websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", size = 158712 }, - { url = "https://files.pythonhosted.org/packages/46/93/e19160db48b5581feac8468330aa11b7292880a94a37d7030478596cc14e/websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", size = 159145 }, - { url = "https://files.pythonhosted.org/packages/51/20/2b99ca918e1cbd33c53db2cace5f0c0cd8296fc77558e1908799c712e1cd/websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", size = 157828 }, - { url = "https://files.pythonhosted.org/packages/b8/47/0932a71d3d9c0e9483174f60713c84cee58d62839a143f21a2bcdbd2d205/websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", size = 155487 }, - { url = "https://files.pythonhosted.org/packages/a9/60/f1711eb59ac7a6c5e98e5637fef5302f45b6f76a2c9d64fd83bbb341377a/websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", size = 155721 }, - { url = "https://files.pythonhosted.org/packages/6a/e6/ba9a8db7f9d9b0e5f829cf626ff32677f39824968317223605a6b419d445/websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", size = 165609 }, - { url = "https://files.pythonhosted.org/packages/c1/22/4ec80f1b9c27a0aebd84ccd857252eda8418ab9681eb571b37ca4c5e1305/websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", size = 164556 }, - { url = "https://files.pythonhosted.org/packages/27/ac/35f423cb6bb15600438db80755609d27eda36d4c0b3c9d745ea12766c45e/websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", size = 164993 }, - { url = "https://files.pythonhosted.org/packages/31/4e/98db4fd267f8be9e52e86b6ee4e9aa7c42b83452ea0ea0672f176224b977/websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", size = 165360 }, - { url = "https://files.pythonhosted.org/packages/3f/15/3f0de7cda70ffc94b7e7024544072bc5b26e2c1eb36545291abb755d8cdb/websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", size = 164745 }, - { url = "https://files.pythonhosted.org/packages/a1/6e/66b6b756aebbd680b934c8bdbb6dcb9ce45aad72cde5f8a7208dbb00dd36/websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", size = 164732 }, - { url = "https://files.pythonhosted.org/packages/35/c6/12e3aab52c11aeb289e3dbbc05929e7a9d90d7a9173958477d3ef4f8ce2d/websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", size = 158709 }, - { url = "https://files.pythonhosted.org/packages/41/d8/63d6194aae711d7263df4498200c690a9c39fb437ede10f3e157a6343e0d/websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", size = 159144 }, - { url = "https://files.pythonhosted.org/packages/2d/75/6da22cb3ad5b8c606963f9a5f9f88656256fecc29d420b4b2bf9e0c7d56f/websockets-13.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238", size = 155499 }, - { url = "https://files.pythonhosted.org/packages/c0/ba/22833d58629088fcb2ccccedfae725ac0bbcd713319629e97125b52ac681/websockets-13.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5", size = 155737 }, - { url = "https://files.pythonhosted.org/packages/95/54/61684fe22bdb831e9e1843d972adadf359cf04ab8613285282baea6a24bb/websockets-13.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9", size = 157095 }, - { url = "https://files.pythonhosted.org/packages/fc/f5/6652fb82440813822022a9301a30afde85e5ff3fb2aebb77f34aabe2b4e8/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6", size = 156701 }, - { url = "https://files.pythonhosted.org/packages/67/33/ae82a7b860fa8a08aba68818bdf7ff61f04598aa5ab96df4cd5a3e418ca4/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a", size = 156654 }, - { url = "https://files.pythonhosted.org/packages/63/0b/a1b528d36934f833e20f6da1032b995bf093d55cb416b9f2266f229fb237/websockets-13.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23", size = 159192 }, - { url = "https://files.pythonhosted.org/packages/56/27/96a5cd2626d11c8280656c6c71d8ab50fe006490ef9971ccd154e0c42cd2/websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f", size = 152134 }, +sdist = { url = "https://files.pythonhosted.org/packages/e2/73/9223dbc7be3dcaf2a7bbf756c351ec8da04b1fa573edaf545b95f6b0c7fd/websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878", size = 158549, upload_time = "2024-09-21T17:34:21.54Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/94/d15dbfc6a5eb636dbc754303fba18208f2e88cf97e733e1d64fb9cb5c89e/websockets-13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee", size = 157815, upload_time = "2024-09-21T17:32:27.107Z" }, + { url = "https://files.pythonhosted.org/packages/30/02/c04af33f4663945a26f5e8cf561eb140c35452b50af47a83c3fbcfe62ae1/websockets-13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7", size = 155466, upload_time = "2024-09-21T17:32:28.428Z" }, + { url = "https://files.pythonhosted.org/packages/35/e8/719f08d12303ea643655e52d9e9851b2dadbb1991d4926d9ce8862efa2f5/websockets-13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6", size = 155716, upload_time = "2024-09-21T17:32:29.905Z" }, + { url = "https://files.pythonhosted.org/packages/91/e1/14963ae0252a8925f7434065d25dcd4701d5e281a0b4b460a3b5963d2594/websockets-13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b", size = 164806, upload_time = "2024-09-21T17:32:31.384Z" }, + { url = "https://files.pythonhosted.org/packages/ec/fa/ab28441bae5e682a0f7ddf3d03440c0c352f930da419301f4a717f675ef3/websockets-13.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa", size = 163810, upload_time = "2024-09-21T17:32:32.384Z" }, + { url = "https://files.pythonhosted.org/packages/44/77/dea187bd9d16d4b91566a2832be31f99a40d0f5bfa55eeb638eb2c3bc33d/websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700", size = 164125, upload_time = "2024-09-21T17:32:33.398Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d9/3af14544e83f1437eb684b399e6ba0fa769438e869bf5d83d74bc197fae8/websockets-13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c", size = 164532, upload_time = "2024-09-21T17:32:35.109Z" }, + { url = "https://files.pythonhosted.org/packages/1c/8a/6d332eabe7d59dfefe4b8ba6f46c8c5fabb15b71c8a8bc3d2b65de19a7b6/websockets-13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0", size = 163948, upload_time = "2024-09-21T17:32:36.214Z" }, + { url = "https://files.pythonhosted.org/packages/1a/91/a0aeadbaf3017467a1ee03f8fb67accdae233fe2d5ad4b038c0a84e357b0/websockets-13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f", size = 163898, upload_time = "2024-09-21T17:32:37.277Z" }, + { url = "https://files.pythonhosted.org/packages/71/31/a90fb47c63e0ae605be914b0b969d7c6e6ffe2038cd744798e4b3fbce53b/websockets-13.1-cp310-cp310-win32.whl", hash = "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe", size = 158706, upload_time = "2024-09-21T17:32:38.755Z" }, + { url = "https://files.pythonhosted.org/packages/93/ca/9540a9ba80da04dc7f36d790c30cae4252589dbd52ccdc92e75b0be22437/websockets-13.1-cp310-cp310-win_amd64.whl", hash = "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a", size = 159141, upload_time = "2024-09-21T17:32:40.495Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f0/cf0b8a30d86b49e267ac84addbebbc7a48a6e7bb7c19db80f62411452311/websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19", size = 157813, upload_time = "2024-09-21T17:32:42.188Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e7/22285852502e33071a8cf0ac814f8988480ec6db4754e067b8b9d0e92498/websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5", size = 155469, upload_time = "2024-09-21T17:32:43.858Z" }, + { url = "https://files.pythonhosted.org/packages/68/d4/c8c7c1e5b40ee03c5cc235955b0fb1ec90e7e37685a5f69229ad4708dcde/websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd", size = 155717, upload_time = "2024-09-21T17:32:44.914Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e4/c50999b9b848b1332b07c7fd8886179ac395cb766fda62725d1539e7bc6c/websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02", size = 165379, upload_time = "2024-09-21T17:32:45.933Z" }, + { url = "https://files.pythonhosted.org/packages/bc/49/4a4ad8c072f18fd79ab127650e47b160571aacfc30b110ee305ba25fffc9/websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7", size = 164376, upload_time = "2024-09-21T17:32:46.987Z" }, + { url = "https://files.pythonhosted.org/packages/af/9b/8c06d425a1d5a74fd764dd793edd02be18cf6fc3b1ccd1f29244ba132dc0/websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096", size = 164753, upload_time = "2024-09-21T17:32:48.046Z" }, + { url = "https://files.pythonhosted.org/packages/d5/5b/0acb5815095ff800b579ffc38b13ab1b915b317915023748812d24e0c1ac/websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084", size = 165051, upload_time = "2024-09-21T17:32:49.271Z" }, + { url = "https://files.pythonhosted.org/packages/30/93/c3891c20114eacb1af09dedfcc620c65c397f4fd80a7009cd12d9457f7f5/websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3", size = 164489, upload_time = "2024-09-21T17:32:50.392Z" }, + { url = "https://files.pythonhosted.org/packages/28/09/af9e19885539759efa2e2cd29b8b3f9eecef7ecefea40d46612f12138b36/websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9", size = 164438, upload_time = "2024-09-21T17:32:52.223Z" }, + { url = "https://files.pythonhosted.org/packages/b6/08/6f38b8e625b3d93de731f1d248cc1493327f16cb45b9645b3e791782cff0/websockets-13.1-cp311-cp311-win32.whl", hash = "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f", size = 158710, upload_time = "2024-09-21T17:32:53.244Z" }, + { url = "https://files.pythonhosted.org/packages/fb/39/ec8832ecb9bb04a8d318149005ed8cee0ba4e0205835da99e0aa497a091f/websockets-13.1-cp311-cp311-win_amd64.whl", hash = "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557", size = 159137, upload_time = "2024-09-21T17:32:54.721Z" }, + { url = "https://files.pythonhosted.org/packages/df/46/c426282f543b3c0296cf964aa5a7bb17e984f58dde23460c3d39b3148fcf/websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc", size = 157821, upload_time = "2024-09-21T17:32:56.442Z" }, + { url = "https://files.pythonhosted.org/packages/aa/85/22529867010baac258da7c45848f9415e6cf37fef00a43856627806ffd04/websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49", size = 155480, upload_time = "2024-09-21T17:32:57.698Z" }, + { url = "https://files.pythonhosted.org/packages/29/2c/bdb339bfbde0119a6e84af43ebf6275278698a2241c2719afc0d8b0bdbf2/websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd", size = 155715, upload_time = "2024-09-21T17:32:59.429Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/8612029ea04c5c22bf7af2fd3d63876c4eaeef9b97e86c11972a43aa0e6c/websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0", size = 165647, upload_time = "2024-09-21T17:33:00.495Z" }, + { url = "https://files.pythonhosted.org/packages/56/04/1681ed516fa19ca9083f26d3f3a302257e0911ba75009533ed60fbb7b8d1/websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6", size = 164592, upload_time = "2024-09-21T17:33:02.223Z" }, + { url = "https://files.pythonhosted.org/packages/38/6f/a96417a49c0ed132bb6087e8e39a37db851c70974f5c724a4b2a70066996/websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9", size = 165012, upload_time = "2024-09-21T17:33:03.288Z" }, + { url = "https://files.pythonhosted.org/packages/40/8b/fccf294919a1b37d190e86042e1a907b8f66cff2b61e9befdbce03783e25/websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68", size = 165311, upload_time = "2024-09-21T17:33:04.728Z" }, + { url = "https://files.pythonhosted.org/packages/c1/61/f8615cf7ce5fe538476ab6b4defff52beb7262ff8a73d5ef386322d9761d/websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14", size = 164692, upload_time = "2024-09-21T17:33:05.829Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f1/a29dd6046d3a722d26f182b783a7997d25298873a14028c4760347974ea3/websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", size = 164686, upload_time = "2024-09-21T17:33:06.823Z" }, + { url = "https://files.pythonhosted.org/packages/0f/99/ab1cdb282f7e595391226f03f9b498f52109d25a2ba03832e21614967dfa/websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", size = 158712, upload_time = "2024-09-21T17:33:07.877Z" }, + { url = "https://files.pythonhosted.org/packages/46/93/e19160db48b5581feac8468330aa11b7292880a94a37d7030478596cc14e/websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", size = 159145, upload_time = "2024-09-21T17:33:09.202Z" }, + { url = "https://files.pythonhosted.org/packages/51/20/2b99ca918e1cbd33c53db2cace5f0c0cd8296fc77558e1908799c712e1cd/websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", size = 157828, upload_time = "2024-09-21T17:33:10.987Z" }, + { url = "https://files.pythonhosted.org/packages/b8/47/0932a71d3d9c0e9483174f60713c84cee58d62839a143f21a2bcdbd2d205/websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", size = 155487, upload_time = "2024-09-21T17:33:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/a9/60/f1711eb59ac7a6c5e98e5637fef5302f45b6f76a2c9d64fd83bbb341377a/websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", size = 155721, upload_time = "2024-09-21T17:33:13.909Z" }, + { url = "https://files.pythonhosted.org/packages/6a/e6/ba9a8db7f9d9b0e5f829cf626ff32677f39824968317223605a6b419d445/websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", size = 165609, upload_time = "2024-09-21T17:33:14.967Z" }, + { url = "https://files.pythonhosted.org/packages/c1/22/4ec80f1b9c27a0aebd84ccd857252eda8418ab9681eb571b37ca4c5e1305/websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", size = 164556, upload_time = "2024-09-21T17:33:17.113Z" }, + { url = "https://files.pythonhosted.org/packages/27/ac/35f423cb6bb15600438db80755609d27eda36d4c0b3c9d745ea12766c45e/websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", size = 164993, upload_time = "2024-09-21T17:33:18.168Z" }, + { url = "https://files.pythonhosted.org/packages/31/4e/98db4fd267f8be9e52e86b6ee4e9aa7c42b83452ea0ea0672f176224b977/websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", size = 165360, upload_time = "2024-09-21T17:33:19.233Z" }, + { url = "https://files.pythonhosted.org/packages/3f/15/3f0de7cda70ffc94b7e7024544072bc5b26e2c1eb36545291abb755d8cdb/websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", size = 164745, upload_time = "2024-09-21T17:33:20.361Z" }, + { url = "https://files.pythonhosted.org/packages/a1/6e/66b6b756aebbd680b934c8bdbb6dcb9ce45aad72cde5f8a7208dbb00dd36/websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", size = 164732, upload_time = "2024-09-21T17:33:23.103Z" }, + { url = "https://files.pythonhosted.org/packages/35/c6/12e3aab52c11aeb289e3dbbc05929e7a9d90d7a9173958477d3ef4f8ce2d/websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", size = 158709, upload_time = "2024-09-21T17:33:24.196Z" }, + { url = "https://files.pythonhosted.org/packages/41/d8/63d6194aae711d7263df4498200c690a9c39fb437ede10f3e157a6343e0d/websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", size = 159144, upload_time = "2024-09-21T17:33:25.96Z" }, + { url = "https://files.pythonhosted.org/packages/2d/75/6da22cb3ad5b8c606963f9a5f9f88656256fecc29d420b4b2bf9e0c7d56f/websockets-13.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238", size = 155499, upload_time = "2024-09-21T17:33:54.917Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ba/22833d58629088fcb2ccccedfae725ac0bbcd713319629e97125b52ac681/websockets-13.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5", size = 155737, upload_time = "2024-09-21T17:33:56.052Z" }, + { url = "https://files.pythonhosted.org/packages/95/54/61684fe22bdb831e9e1843d972adadf359cf04ab8613285282baea6a24bb/websockets-13.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9", size = 157095, upload_time = "2024-09-21T17:33:57.21Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f5/6652fb82440813822022a9301a30afde85e5ff3fb2aebb77f34aabe2b4e8/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6", size = 156701, upload_time = "2024-09-21T17:33:59.061Z" }, + { url = "https://files.pythonhosted.org/packages/67/33/ae82a7b860fa8a08aba68818bdf7ff61f04598aa5ab96df4cd5a3e418ca4/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a", size = 156654, upload_time = "2024-09-21T17:34:00.944Z" }, + { url = "https://files.pythonhosted.org/packages/63/0b/a1b528d36934f833e20f6da1032b995bf093d55cb416b9f2266f229fb237/websockets-13.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23", size = 159192, upload_time = "2024-09-21T17:34:02.656Z" }, + { url = "https://files.pythonhosted.org/packages/56/27/96a5cd2626d11c8280656c6c71d8ab50fe006490ef9971ccd154e0c42cd2/websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f", size = 152134, upload_time = "2024-09-21T17:34:19.904Z" }, +] + +[[package]] +name = "wrapt" +version = "1.17.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/fc/e91cc220803d7bc4db93fb02facd8461c37364151b8494762cc88b0fbcef/wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", size = 55531, upload_time = "2025-01-14T10:35:45.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/d1/1daec934997e8b160040c78d7b31789f19b122110a75eca3d4e8da0049e1/wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984", size = 53307, upload_time = "2025-01-14T10:33:13.616Z" }, + { url = "https://files.pythonhosted.org/packages/1b/7b/13369d42651b809389c1a7153baa01d9700430576c81a2f5c5e460df0ed9/wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22", size = 38486, upload_time = "2025-01-14T10:33:15.947Z" }, + { url = "https://files.pythonhosted.org/packages/62/bf/e0105016f907c30b4bd9e377867c48c34dc9c6c0c104556c9c9126bd89ed/wrapt-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7", size = 38777, upload_time = "2025-01-14T10:33:17.462Z" }, + { url = "https://files.pythonhosted.org/packages/27/70/0f6e0679845cbf8b165e027d43402a55494779295c4b08414097b258ac87/wrapt-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c", size = 83314, upload_time = "2025-01-14T10:33:21.282Z" }, + { url = "https://files.pythonhosted.org/packages/0f/77/0576d841bf84af8579124a93d216f55d6f74374e4445264cb378a6ed33eb/wrapt-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72", size = 74947, upload_time = "2025-01-14T10:33:24.414Z" }, + { url = "https://files.pythonhosted.org/packages/90/ec/00759565518f268ed707dcc40f7eeec38637d46b098a1f5143bff488fe97/wrapt-1.17.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061", size = 82778, upload_time = "2025-01-14T10:33:26.152Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5a/7cffd26b1c607b0b0c8a9ca9d75757ad7620c9c0a9b4a25d3f8a1480fafc/wrapt-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2", size = 81716, upload_time = "2025-01-14T10:33:27.372Z" }, + { url = "https://files.pythonhosted.org/packages/7e/09/dccf68fa98e862df7e6a60a61d43d644b7d095a5fc36dbb591bbd4a1c7b2/wrapt-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c", size = 74548, upload_time = "2025-01-14T10:33:28.52Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8e/067021fa3c8814952c5e228d916963c1115b983e21393289de15128e867e/wrapt-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62", size = 81334, upload_time = "2025-01-14T10:33:29.643Z" }, + { url = "https://files.pythonhosted.org/packages/4b/0d/9d4b5219ae4393f718699ca1c05f5ebc0c40d076f7e65fd48f5f693294fb/wrapt-1.17.2-cp310-cp310-win32.whl", hash = "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563", size = 36427, upload_time = "2025-01-14T10:33:30.832Z" }, + { url = "https://files.pythonhosted.org/packages/72/6a/c5a83e8f61aec1e1aeef939807602fb880e5872371e95df2137142f5c58e/wrapt-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f", size = 38774, upload_time = "2025-01-14T10:33:32.897Z" }, + { url = "https://files.pythonhosted.org/packages/cd/f7/a2aab2cbc7a665efab072344a8949a71081eed1d2f451f7f7d2b966594a2/wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58", size = 53308, upload_time = "2025-01-14T10:33:33.992Z" }, + { url = "https://files.pythonhosted.org/packages/50/ff/149aba8365fdacef52b31a258c4dc1c57c79759c335eff0b3316a2664a64/wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda", size = 38488, upload_time = "2025-01-14T10:33:35.264Z" }, + { url = "https://files.pythonhosted.org/packages/65/46/5a917ce85b5c3b490d35c02bf71aedaa9f2f63f2d15d9949cc4ba56e8ba9/wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438", size = 38776, upload_time = "2025-01-14T10:33:38.28Z" }, + { url = "https://files.pythonhosted.org/packages/ca/74/336c918d2915a4943501c77566db41d1bd6e9f4dbc317f356b9a244dfe83/wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a", size = 83776, upload_time = "2025-01-14T10:33:40.678Z" }, + { url = "https://files.pythonhosted.org/packages/09/99/c0c844a5ccde0fe5761d4305485297f91d67cf2a1a824c5f282e661ec7ff/wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000", size = 75420, upload_time = "2025-01-14T10:33:41.868Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b0/9fc566b0fe08b282c850063591a756057c3247b2362b9286429ec5bf1721/wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6", size = 83199, upload_time = "2025-01-14T10:33:43.598Z" }, + { url = "https://files.pythonhosted.org/packages/9d/4b/71996e62d543b0a0bd95dda485219856def3347e3e9380cc0d6cf10cfb2f/wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b", size = 82307, upload_time = "2025-01-14T10:33:48.499Z" }, + { url = "https://files.pythonhosted.org/packages/39/35/0282c0d8789c0dc9bcc738911776c762a701f95cfe113fb8f0b40e45c2b9/wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662", size = 75025, upload_time = "2025-01-14T10:33:51.191Z" }, + { url = "https://files.pythonhosted.org/packages/4f/6d/90c9fd2c3c6fee181feecb620d95105370198b6b98a0770cba090441a828/wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72", size = 81879, upload_time = "2025-01-14T10:33:52.328Z" }, + { url = "https://files.pythonhosted.org/packages/8f/fa/9fb6e594f2ce03ef03eddbdb5f4f90acb1452221a5351116c7c4708ac865/wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317", size = 36419, upload_time = "2025-01-14T10:33:53.551Z" }, + { url = "https://files.pythonhosted.org/packages/47/f8/fb1773491a253cbc123c5d5dc15c86041f746ed30416535f2a8df1f4a392/wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3", size = 38773, upload_time = "2025-01-14T10:33:56.323Z" }, + { url = "https://files.pythonhosted.org/packages/a1/bd/ab55f849fd1f9a58ed7ea47f5559ff09741b25f00c191231f9f059c83949/wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925", size = 53799, upload_time = "2025-01-14T10:33:57.4Z" }, + { url = "https://files.pythonhosted.org/packages/53/18/75ddc64c3f63988f5a1d7e10fb204ffe5762bc663f8023f18ecaf31a332e/wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392", size = 38821, upload_time = "2025-01-14T10:33:59.334Z" }, + { url = "https://files.pythonhosted.org/packages/48/2a/97928387d6ed1c1ebbfd4efc4133a0633546bec8481a2dd5ec961313a1c7/wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40", size = 38919, upload_time = "2025-01-14T10:34:04.093Z" }, + { url = "https://files.pythonhosted.org/packages/73/54/3bfe5a1febbbccb7a2f77de47b989c0b85ed3a6a41614b104204a788c20e/wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d", size = 88721, upload_time = "2025-01-14T10:34:07.163Z" }, + { url = "https://files.pythonhosted.org/packages/25/cb/7262bc1b0300b4b64af50c2720ef958c2c1917525238d661c3e9a2b71b7b/wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b", size = 80899, upload_time = "2025-01-14T10:34:09.82Z" }, + { url = "https://files.pythonhosted.org/packages/2a/5a/04cde32b07a7431d4ed0553a76fdb7a61270e78c5fd5a603e190ac389f14/wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98", size = 89222, upload_time = "2025-01-14T10:34:11.258Z" }, + { url = "https://files.pythonhosted.org/packages/09/28/2e45a4f4771fcfb109e244d5dbe54259e970362a311b67a965555ba65026/wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82", size = 86707, upload_time = "2025-01-14T10:34:12.49Z" }, + { url = "https://files.pythonhosted.org/packages/c6/d2/dcb56bf5f32fcd4bd9aacc77b50a539abdd5b6536872413fd3f428b21bed/wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae", size = 79685, upload_time = "2025-01-14T10:34:15.043Z" }, + { url = "https://files.pythonhosted.org/packages/80/4e/eb8b353e36711347893f502ce91c770b0b0929f8f0bed2670a6856e667a9/wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9", size = 87567, upload_time = "2025-01-14T10:34:16.563Z" }, + { url = "https://files.pythonhosted.org/packages/17/27/4fe749a54e7fae6e7146f1c7d914d28ef599dacd4416566c055564080fe2/wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", size = 36672, upload_time = "2025-01-14T10:34:17.727Z" }, + { url = "https://files.pythonhosted.org/packages/15/06/1dbf478ea45c03e78a6a8c4be4fdc3c3bddea5c8de8a93bc971415e47f0f/wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", size = 38865, upload_time = "2025-01-14T10:34:19.577Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b9/0ffd557a92f3b11d4c5d5e0c5e4ad057bd9eb8586615cdaf901409920b14/wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", size = 53800, upload_time = "2025-01-14T10:34:21.571Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ef/8be90a0b7e73c32e550c73cfb2fa09db62234227ece47b0e80a05073b375/wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", size = 38824, upload_time = "2025-01-14T10:34:22.999Z" }, + { url = "https://files.pythonhosted.org/packages/36/89/0aae34c10fe524cce30fe5fc433210376bce94cf74d05b0d68344c8ba46e/wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", size = 38920, upload_time = "2025-01-14T10:34:25.386Z" }, + { url = "https://files.pythonhosted.org/packages/3b/24/11c4510de906d77e0cfb5197f1b1445d4fec42c9a39ea853d482698ac681/wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", size = 88690, upload_time = "2025-01-14T10:34:28.058Z" }, + { url = "https://files.pythonhosted.org/packages/71/d7/cfcf842291267bf455b3e266c0c29dcb675b5540ee8b50ba1699abf3af45/wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", size = 80861, upload_time = "2025-01-14T10:34:29.167Z" }, + { url = "https://files.pythonhosted.org/packages/d5/66/5d973e9f3e7370fd686fb47a9af3319418ed925c27d72ce16b791231576d/wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", size = 89174, upload_time = "2025-01-14T10:34:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d3/8e17bb70f6ae25dabc1aaf990f86824e4fd98ee9cadf197054e068500d27/wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", size = 86721, upload_time = "2025-01-14T10:34:32.91Z" }, + { url = "https://files.pythonhosted.org/packages/6f/54/f170dfb278fe1c30d0ff864513cff526d624ab8de3254b20abb9cffedc24/wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", size = 79763, upload_time = "2025-01-14T10:34:34.903Z" }, + { url = "https://files.pythonhosted.org/packages/4a/98/de07243751f1c4a9b15c76019250210dd3486ce098c3d80d5f729cba029c/wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", size = 87585, upload_time = "2025-01-14T10:34:36.13Z" }, + { url = "https://files.pythonhosted.org/packages/f9/f0/13925f4bd6548013038cdeb11ee2cbd4e37c30f8bfd5db9e5a2a370d6e20/wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", size = 36676, upload_time = "2025-01-14T10:34:37.962Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ae/743f16ef8c2e3628df3ddfd652b7d4c555d12c84b53f3d8218498f4ade9b/wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", size = 38871, upload_time = "2025-01-14T10:34:39.13Z" }, + { url = "https://files.pythonhosted.org/packages/3d/bc/30f903f891a82d402ffb5fda27ec1d621cc97cb74c16fea0b6141f1d4e87/wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", size = 56312, upload_time = "2025-01-14T10:34:40.604Z" }, + { url = "https://files.pythonhosted.org/packages/8a/04/c97273eb491b5f1c918857cd26f314b74fc9b29224521f5b83f872253725/wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", size = 40062, upload_time = "2025-01-14T10:34:45.011Z" }, + { url = "https://files.pythonhosted.org/packages/4e/ca/3b7afa1eae3a9e7fefe499db9b96813f41828b9fdb016ee836c4c379dadb/wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", size = 40155, upload_time = "2025-01-14T10:34:47.25Z" }, + { url = "https://files.pythonhosted.org/packages/89/be/7c1baed43290775cb9030c774bc53c860db140397047cc49aedaf0a15477/wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", size = 113471, upload_time = "2025-01-14T10:34:50.934Z" }, + { url = "https://files.pythonhosted.org/packages/32/98/4ed894cf012b6d6aae5f5cc974006bdeb92f0241775addad3f8cd6ab71c8/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", size = 101208, upload_time = "2025-01-14T10:34:52.297Z" }, + { url = "https://files.pythonhosted.org/packages/ea/fd/0c30f2301ca94e655e5e057012e83284ce8c545df7661a78d8bfca2fac7a/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", size = 109339, upload_time = "2025-01-14T10:34:53.489Z" }, + { url = "https://files.pythonhosted.org/packages/75/56/05d000de894c4cfcb84bcd6b1df6214297b8089a7bd324c21a4765e49b14/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", size = 110232, upload_time = "2025-01-14T10:34:55.327Z" }, + { url = "https://files.pythonhosted.org/packages/53/f8/c3f6b2cf9b9277fb0813418e1503e68414cd036b3b099c823379c9575e6d/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", size = 100476, upload_time = "2025-01-14T10:34:58.055Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b1/0bb11e29aa5139d90b770ebbfa167267b1fc548d2302c30c8f7572851738/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", size = 106377, upload_time = "2025-01-14T10:34:59.3Z" }, + { url = "https://files.pythonhosted.org/packages/6a/e1/0122853035b40b3f333bbb25f1939fc1045e21dd518f7f0922b60c156f7c/wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", size = 37986, upload_time = "2025-01-14T10:35:00.498Z" }, + { url = "https://files.pythonhosted.org/packages/09/5e/1655cf481e079c1f22d0cabdd4e51733679932718dc23bf2db175f329b76/wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", size = 40750, upload_time = "2025-01-14T10:35:03.378Z" }, + { url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594, upload_time = "2025-01-14T10:35:44.018Z" }, +] + +[[package]] +name = "xlsxwriter" +version = "3.2.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/47/7704bac42ac6fe1710ae099b70e6a1e68ed173ef14792b647808c357da43/xlsxwriter-3.2.5.tar.gz", hash = "sha256:7e88469d607cdc920151c0ab3ce9cf1a83992d4b7bc730c5ffdd1a12115a7dbe", size = 213306, upload_time = "2025-06-17T08:59:14.619Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/34/a22e6664211f0c8879521328000bdcae9bf6dbafa94a923e531f6d5b3f73/xlsxwriter-3.2.5-py3-none-any.whl", hash = "sha256:4f4824234e1eaf9d95df9a8fe974585ff91d0f5e3d3f12ace5b71e443c1c6abd", size = 172347, upload_time = "2025-06-17T08:59:13.453Z" }, +] + +[[package]] +name = "zipp" +version = "3.23.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload_time = "2025-06-08T17:06:39.4Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload_time = "2025-06-08T17:06:38.034Z" }, +] + +[[package]] +name = "zstandard" +version = "0.23.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation == 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/f6/2ac0287b442160a89d726b17a9184a4c615bb5237db763791a7fd16d9df1/zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09", size = 681701, upload_time = "2024-07-15T00:18:06.141Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/55/bd0487e86679db1823fc9ee0d8c9c78ae2413d34c0b461193b5f4c31d22f/zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9", size = 788701, upload_time = "2024-07-15T00:13:27.351Z" }, + { url = "https://files.pythonhosted.org/packages/e1/8a/ccb516b684f3ad987dfee27570d635822e3038645b1a950c5e8022df1145/zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880", size = 633678, upload_time = "2024-07-15T00:13:30.24Z" }, + { url = "https://files.pythonhosted.org/packages/12/89/75e633d0611c028e0d9af6df199423bf43f54bea5007e6718ab7132e234c/zstandard-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc", size = 4941098, upload_time = "2024-07-15T00:13:32.526Z" }, + { url = "https://files.pythonhosted.org/packages/4a/7a/bd7f6a21802de358b63f1ee636ab823711c25ce043a3e9f043b4fcb5ba32/zstandard-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573", size = 5308798, upload_time = "2024-07-15T00:13:34.925Z" }, + { url = "https://files.pythonhosted.org/packages/79/3b/775f851a4a65013e88ca559c8ae42ac1352db6fcd96b028d0df4d7d1d7b4/zstandard-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391", size = 5341840, upload_time = "2024-07-15T00:13:37.376Z" }, + { url = "https://files.pythonhosted.org/packages/09/4f/0cc49570141dd72d4d95dd6fcf09328d1b702c47a6ec12fbed3b8aed18a5/zstandard-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e", size = 5440337, upload_time = "2024-07-15T00:13:39.772Z" }, + { url = "https://files.pythonhosted.org/packages/e7/7c/aaa7cd27148bae2dc095191529c0570d16058c54c4597a7d118de4b21676/zstandard-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd", size = 4861182, upload_time = "2024-07-15T00:13:42.495Z" }, + { url = "https://files.pythonhosted.org/packages/ac/eb/4b58b5c071d177f7dc027129d20bd2a44161faca6592a67f8fcb0b88b3ae/zstandard-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4", size = 4932936, upload_time = "2024-07-15T00:13:44.234Z" }, + { url = "https://files.pythonhosted.org/packages/44/f9/21a5fb9bb7c9a274b05ad700a82ad22ce82f7ef0f485980a1e98ed6e8c5f/zstandard-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea", size = 5464705, upload_time = "2024-07-15T00:13:46.822Z" }, + { url = "https://files.pythonhosted.org/packages/49/74/b7b3e61db3f88632776b78b1db597af3f44c91ce17d533e14a25ce6a2816/zstandard-0.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2", size = 4857882, upload_time = "2024-07-15T00:13:49.297Z" }, + { url = "https://files.pythonhosted.org/packages/4a/7f/d8eb1cb123d8e4c541d4465167080bec88481ab54cd0b31eb4013ba04b95/zstandard-0.23.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9", size = 4697672, upload_time = "2024-07-15T00:13:51.447Z" }, + { url = "https://files.pythonhosted.org/packages/5e/05/f7dccdf3d121309b60342da454d3e706453a31073e2c4dac8e1581861e44/zstandard-0.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a", size = 5206043, upload_time = "2024-07-15T00:13:53.587Z" }, + { url = "https://files.pythonhosted.org/packages/86/9d/3677a02e172dccd8dd3a941307621c0cbd7691d77cb435ac3c75ab6a3105/zstandard-0.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0", size = 5667390, upload_time = "2024-07-15T00:13:56.137Z" }, + { url = "https://files.pythonhosted.org/packages/41/7e/0012a02458e74a7ba122cd9cafe491facc602c9a17f590367da369929498/zstandard-0.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c", size = 5198901, upload_time = "2024-07-15T00:13:58.584Z" }, + { url = "https://files.pythonhosted.org/packages/65/3a/8f715b97bd7bcfc7342d8adcd99a026cb2fb550e44866a3b6c348e1b0f02/zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813", size = 430596, upload_time = "2024-07-15T00:14:00.693Z" }, + { url = "https://files.pythonhosted.org/packages/19/b7/b2b9eca5e5a01111e4fe8a8ffb56bdcdf56b12448a24effe6cfe4a252034/zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4", size = 495498, upload_time = "2024-07-15T00:14:02.741Z" }, + { url = "https://files.pythonhosted.org/packages/9e/40/f67e7d2c25a0e2dc1744dd781110b0b60306657f8696cafb7ad7579469bd/zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e", size = 788699, upload_time = "2024-07-15T00:14:04.909Z" }, + { url = "https://files.pythonhosted.org/packages/e8/46/66d5b55f4d737dd6ab75851b224abf0afe5774976fe511a54d2eb9063a41/zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23", size = 633681, upload_time = "2024-07-15T00:14:13.99Z" }, + { url = "https://files.pythonhosted.org/packages/63/b6/677e65c095d8e12b66b8f862b069bcf1f1d781b9c9c6f12eb55000d57583/zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a", size = 4944328, upload_time = "2024-07-15T00:14:16.588Z" }, + { url = "https://files.pythonhosted.org/packages/59/cc/e76acb4c42afa05a9d20827116d1f9287e9c32b7ad58cc3af0721ce2b481/zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db", size = 5311955, upload_time = "2024-07-15T00:14:19.389Z" }, + { url = "https://files.pythonhosted.org/packages/78/e4/644b8075f18fc7f632130c32e8f36f6dc1b93065bf2dd87f03223b187f26/zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2", size = 5344944, upload_time = "2024-07-15T00:14:22.173Z" }, + { url = "https://files.pythonhosted.org/packages/76/3f/dbafccf19cfeca25bbabf6f2dd81796b7218f768ec400f043edc767015a6/zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca", size = 5442927, upload_time = "2024-07-15T00:14:24.825Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c3/d24a01a19b6733b9f218e94d1a87c477d523237e07f94899e1c10f6fd06c/zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c", size = 4864910, upload_time = "2024-07-15T00:14:26.982Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a9/cf8f78ead4597264f7618d0875be01f9bc23c9d1d11afb6d225b867cb423/zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e", size = 4935544, upload_time = "2024-07-15T00:14:29.582Z" }, + { url = "https://files.pythonhosted.org/packages/2c/96/8af1e3731b67965fb995a940c04a2c20997a7b3b14826b9d1301cf160879/zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5", size = 5467094, upload_time = "2024-07-15T00:14:40.126Z" }, + { url = "https://files.pythonhosted.org/packages/ff/57/43ea9df642c636cb79f88a13ab07d92d88d3bfe3e550b55a25a07a26d878/zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48", size = 4860440, upload_time = "2024-07-15T00:14:42.786Z" }, + { url = "https://files.pythonhosted.org/packages/46/37/edb78f33c7f44f806525f27baa300341918fd4c4af9472fbc2c3094be2e8/zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c", size = 4700091, upload_time = "2024-07-15T00:14:45.184Z" }, + { url = "https://files.pythonhosted.org/packages/c1/f1/454ac3962671a754f3cb49242472df5c2cced4eb959ae203a377b45b1a3c/zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003", size = 5208682, upload_time = "2024-07-15T00:14:47.407Z" }, + { url = "https://files.pythonhosted.org/packages/85/b2/1734b0fff1634390b1b887202d557d2dd542de84a4c155c258cf75da4773/zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78", size = 5669707, upload_time = "2024-07-15T00:15:03.529Z" }, + { url = "https://files.pythonhosted.org/packages/52/5a/87d6971f0997c4b9b09c495bf92189fb63de86a83cadc4977dc19735f652/zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473", size = 5201792, upload_time = "2024-07-15T00:15:28.372Z" }, + { url = "https://files.pythonhosted.org/packages/79/02/6f6a42cc84459d399bd1a4e1adfc78d4dfe45e56d05b072008d10040e13b/zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160", size = 430586, upload_time = "2024-07-15T00:15:32.26Z" }, + { url = "https://files.pythonhosted.org/packages/be/a2/4272175d47c623ff78196f3c10e9dc7045c1b9caf3735bf041e65271eca4/zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0", size = 495420, upload_time = "2024-07-15T00:15:34.004Z" }, + { url = "https://files.pythonhosted.org/packages/7b/83/f23338c963bd9de687d47bf32efe9fd30164e722ba27fb59df33e6b1719b/zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094", size = 788713, upload_time = "2024-07-15T00:15:35.815Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b3/1a028f6750fd9227ee0b937a278a434ab7f7fdc3066c3173f64366fe2466/zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8", size = 633459, upload_time = "2024-07-15T00:15:37.995Z" }, + { url = "https://files.pythonhosted.org/packages/26/af/36d89aae0c1f95a0a98e50711bc5d92c144939efc1f81a2fcd3e78d7f4c1/zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1", size = 4945707, upload_time = "2024-07-15T00:15:39.872Z" }, + { url = "https://files.pythonhosted.org/packages/cd/2e/2051f5c772f4dfc0aae3741d5fc72c3dcfe3aaeb461cc231668a4db1ce14/zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072", size = 5306545, upload_time = "2024-07-15T00:15:41.75Z" }, + { url = "https://files.pythonhosted.org/packages/0a/9e/a11c97b087f89cab030fa71206963090d2fecd8eb83e67bb8f3ffb84c024/zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20", size = 5337533, upload_time = "2024-07-15T00:15:44.114Z" }, + { url = "https://files.pythonhosted.org/packages/fc/79/edeb217c57fe1bf16d890aa91a1c2c96b28c07b46afed54a5dcf310c3f6f/zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373", size = 5436510, upload_time = "2024-07-15T00:15:46.509Z" }, + { url = "https://files.pythonhosted.org/packages/81/4f/c21383d97cb7a422ddf1ae824b53ce4b51063d0eeb2afa757eb40804a8ef/zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db", size = 4859973, upload_time = "2024-07-15T00:15:49.939Z" }, + { url = "https://files.pythonhosted.org/packages/ab/15/08d22e87753304405ccac8be2493a495f529edd81d39a0870621462276ef/zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772", size = 4936968, upload_time = "2024-07-15T00:15:52.025Z" }, + { url = "https://files.pythonhosted.org/packages/eb/fa/f3670a597949fe7dcf38119a39f7da49a8a84a6f0b1a2e46b2f71a0ab83f/zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105", size = 5467179, upload_time = "2024-07-15T00:15:54.971Z" }, + { url = "https://files.pythonhosted.org/packages/4e/a9/dad2ab22020211e380adc477a1dbf9f109b1f8d94c614944843e20dc2a99/zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba", size = 4848577, upload_time = "2024-07-15T00:15:57.634Z" }, + { url = "https://files.pythonhosted.org/packages/08/03/dd28b4484b0770f1e23478413e01bee476ae8227bbc81561f9c329e12564/zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd", size = 4693899, upload_time = "2024-07-15T00:16:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/2b/64/3da7497eb635d025841e958bcd66a86117ae320c3b14b0ae86e9e8627518/zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a", size = 5199964, upload_time = "2024-07-15T00:16:03.669Z" }, + { url = "https://files.pythonhosted.org/packages/43/a4/d82decbab158a0e8a6ebb7fc98bc4d903266bce85b6e9aaedea1d288338c/zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90", size = 5655398, upload_time = "2024-07-15T00:16:06.694Z" }, + { url = "https://files.pythonhosted.org/packages/f2/61/ac78a1263bc83a5cf29e7458b77a568eda5a8f81980691bbc6eb6a0d45cc/zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35", size = 5191313, upload_time = "2024-07-15T00:16:09.758Z" }, + { url = "https://files.pythonhosted.org/packages/e7/54/967c478314e16af5baf849b6ee9d6ea724ae5b100eb506011f045d3d4e16/zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d", size = 430877, upload_time = "2024-07-15T00:16:11.758Z" }, + { url = "https://files.pythonhosted.org/packages/75/37/872d74bd7739639c4553bf94c84af7d54d8211b626b352bc57f0fd8d1e3f/zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b", size = 495595, upload_time = "2024-07-15T00:16:13.731Z" }, + { url = "https://files.pythonhosted.org/packages/80/f1/8386f3f7c10261fe85fbc2c012fdb3d4db793b921c9abcc995d8da1b7a80/zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9", size = 788975, upload_time = "2024-07-15T00:16:16.005Z" }, + { url = "https://files.pythonhosted.org/packages/16/e8/cbf01077550b3e5dc86089035ff8f6fbbb312bc0983757c2d1117ebba242/zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a", size = 633448, upload_time = "2024-07-15T00:16:17.897Z" }, + { url = "https://files.pythonhosted.org/packages/06/27/4a1b4c267c29a464a161aeb2589aff212b4db653a1d96bffe3598f3f0d22/zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2", size = 4945269, upload_time = "2024-07-15T00:16:20.136Z" }, + { url = "https://files.pythonhosted.org/packages/7c/64/d99261cc57afd9ae65b707e38045ed8269fbdae73544fd2e4a4d50d0ed83/zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5", size = 5306228, upload_time = "2024-07-15T00:16:23.398Z" }, + { url = "https://files.pythonhosted.org/packages/7a/cf/27b74c6f22541f0263016a0fd6369b1b7818941de639215c84e4e94b2a1c/zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f", size = 5336891, upload_time = "2024-07-15T00:16:26.391Z" }, + { url = "https://files.pythonhosted.org/packages/fa/18/89ac62eac46b69948bf35fcd90d37103f38722968e2981f752d69081ec4d/zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed", size = 5436310, upload_time = "2024-07-15T00:16:29.018Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a8/5ca5328ee568a873f5118d5b5f70d1f36c6387716efe2e369010289a5738/zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea", size = 4859912, upload_time = "2024-07-15T00:16:31.871Z" }, + { url = "https://files.pythonhosted.org/packages/ea/ca/3781059c95fd0868658b1cf0440edd832b942f84ae60685d0cfdb808bca1/zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847", size = 4936946, upload_time = "2024-07-15T00:16:34.593Z" }, + { url = "https://files.pythonhosted.org/packages/ce/11/41a58986f809532742c2b832c53b74ba0e0a5dae7e8ab4642bf5876f35de/zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171", size = 5466994, upload_time = "2024-07-15T00:16:36.887Z" }, + { url = "https://files.pythonhosted.org/packages/83/e3/97d84fe95edd38d7053af05159465d298c8b20cebe9ccb3d26783faa9094/zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840", size = 4848681, upload_time = "2024-07-15T00:16:39.709Z" }, + { url = "https://files.pythonhosted.org/packages/6e/99/cb1e63e931de15c88af26085e3f2d9af9ce53ccafac73b6e48418fd5a6e6/zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690", size = 4694239, upload_time = "2024-07-15T00:16:41.83Z" }, + { url = "https://files.pythonhosted.org/packages/ab/50/b1e703016eebbc6501fc92f34db7b1c68e54e567ef39e6e59cf5fb6f2ec0/zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b", size = 5200149, upload_time = "2024-07-15T00:16:44.287Z" }, + { url = "https://files.pythonhosted.org/packages/aa/e0/932388630aaba70197c78bdb10cce2c91fae01a7e553b76ce85471aec690/zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057", size = 5655392, upload_time = "2024-07-15T00:16:46.423Z" }, + { url = "https://files.pythonhosted.org/packages/02/90/2633473864f67a15526324b007a9f96c96f56d5f32ef2a56cc12f9548723/zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33", size = 5191299, upload_time = "2024-07-15T00:16:49.053Z" }, + { url = "https://files.pythonhosted.org/packages/b0/4c/315ca5c32da7e2dc3455f3b2caee5c8c2246074a61aac6ec3378a97b7136/zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd", size = 430862, upload_time = "2024-07-15T00:16:51.003Z" }, + { url = "https://files.pythonhosted.org/packages/a2/bf/c6aaba098e2d04781e8f4f7c0ba3c7aa73d00e4c436bcc0cf059a66691d1/zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b", size = 495578, upload_time = "2024-07-15T00:16:53.135Z" }, ] diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 0751abe901..6b0c6353df 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -10,81 +10,45 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock ports: - - "80:80" + - "8081:80" - "8090:8080" - # Duplicate the command from docker-compose.yml to add --api.insecure=true command: - # Enable Docker in Traefik, so that it reads labels from Docker services - --providers.docker - # Add a constraint to only use services with the label for this stack - --providers.docker.constraints=Label(`traefik.constraint-label`, `traefik-public`) - # Do not expose all Docker services, only the ones explicitly exposed - --providers.docker.exposedbydefault=false - # Create an entrypoint "http" listening on port 80 - - --entrypoints.http.address=:80 - # Create an entrypoint "https" listening on port 443 - - --entrypoints.https.address=:443 - # Enable the access log, with HTTP requests - - --accesslog - # Enable the Traefik log, for configurations and errors - - --log - # Enable debug logging for local development - - --log.level=DEBUG - # Enable the Dashboard and API + - --providers.file.directory=/etc/traefik/dynamic/ + - --entrypoints.web.address=:80 - --api - # Enable the Dashboard and API in insecure mode for local development + - --api.dashboard=true - --api.insecure=true labels: - # Enable Traefik for this service, to make it available in the public network - traefik.enable=true - traefik.constraint-label=traefik-public - # Dummy https-redirect middleware that doesn't really redirect, only to - # allow running it locally - - traefik.http.middlewares.https-redirect.contenttype.autodetect=false - networks: - - traefik-public - - default + - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https + - traefik.http.middlewares.admin-auth.basicauth.users=admin:$$apr1$$GQUXqJzr$$qxA5ZBDy3hKNJqXgzGxwX. + - traefik.http.routers.traefik-public-http.rule=Host(`${DOMAIN?Variable not set}`) + - traefik.http.routers.traefik-public-http.entrypoints=web + - traefik.http.routers.traefik-public-http.middlewares=https-redirect + - traefik.http.routers.traefik-public-http.service=api@internal db: - restart: "no" ports: - - "5432:5432" + - "5444:5432" adminer: - restart: "no" ports: - "8080:8080" backend: - restart: "no" ports: - - "8000:8000" - build: - context: ./backend - # command: sleep infinity # Infinite loop to keep container alive doing nothing - command: - - fastapi - - run - - --reload - - "app/main.py" - develop: - watch: - - path: ./backend - action: sync - target: /app - ignore: - - ./backend/.venv - - .venv - - path: ./backend/pyproject.toml - action: rebuild - # TODO: remove once coverage is done locally + - "8010:8000" volumes: - - ./backend/htmlcov:/app/htmlcov + - ./backend:/app environment: - SMTP_HOST: "mailcatcher" - SMTP_PORT: "1025" - SMTP_TLS: "false" - EMAILS_FROM_EMAIL: "noreply@example.com" + - ENVIRONMENT=local + - FRONTEND_HOST=http://localhost:5173 + - BACKEND_CORS_ORIGINS=["http://localhost:5173","http://localhost:3000","http://localhost:8080","http://localhost:8010","http://localhost","https://localhost","https://localhost:5173","https://localhost:3000","https://localhost:8080","https://counselor-ai.cc"] + command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] mailcatcher: image: schickling/mailcatcher @@ -93,14 +57,24 @@ services: - "1025:1025" frontend: - restart: "no" - ports: - - "5173:80" build: context: ./frontend - args: - - VITE_API_URL=http://localhost:8000 - - NODE_ENV=development + dockerfile: Dockerfile + target: dev + ports: + - "5173:5173" + volumes: + - ./frontend:/app + - /app/node_modules + environment: + - VITE_API_URL=https://counselor-ai.cc + - NODE_ENV=production + command: npm run dev -- --host 0.0.0.0 + labels: + - traefik.enable=true + - traefik.constraint-label=traefik-public + - traefik.http.routers.app-frontend-http.rule=PathPrefix(`/`) + - traefik.http.services.app-frontend.loadbalancer.server.port=5173 playwright: build: @@ -128,6 +102,7 @@ services: - 9323:9323 networks: + default: + name: ${STACK_NAME?Variable not set}-default traefik-public: - # For local dev, don't expect an external Traefik network - external: false + name: ${STACK_NAME?Variable not set}-traefik-public diff --git a/docker-compose.traefik.yml b/docker-compose.traefik.yml index 886d6dcc2f..7d57184224 100644 --- a/docker-compose.traefik.yml +++ b/docker-compose.traefik.yml @@ -2,10 +2,10 @@ services: traefik: image: traefik:3.0 ports: - # Listen on port 80, default for HTTP, necessary to redirect to HTTPS - - 80:80 - # Listen on port 443, default for HTTPS - - 443:443 + # Listen on port 8080, alternative for HTTP, necessary to redirect to HTTPS + - 8080:80 + # Listen on port 8443, alternative for HTTPS + - 8443:443 restart: always labels: # Enable Traefik for this service, to make it available in the public network diff --git a/docker-compose.yml b/docker-compose.yml index b1aa17ed43..1efea1e4b9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,8 +6,8 @@ services: healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 10s - retries: 5 - start_period: 30s + retries: 10 + start_period: 60s timeout: 10s volumes: - app-db-data:/var/lib/postgresql/data/pgdata @@ -26,9 +26,12 @@ services: - traefik-public - default depends_on: - - db + db: + condition: service_healthy + restart: true environment: - ADMINER_DESIGN=pepa-linha-dark + - ADMINER_DEFAULT_SERVER=db labels: - traefik.enable=true - traefik.docker.network=traefik-public @@ -87,6 +90,12 @@ services: restart: true prestart: condition: service_completed_successfully + redis: + condition: service_healthy + restart: true + qdrant: + condition: service_started + restart: true env_file: - .env environment: @@ -107,12 +116,15 @@ services: - POSTGRES_USER=${POSTGRES_USER?Variable not set} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set} - SENTRY_DSN=${SENTRY_DSN} + - QDRANT_URL=http://qdrant:6333 + - REDIS_URL=redis://redis:6379 healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/utils/health-check/"] - interval: 10s - timeout: 5s + test: ["CMD", "curl", "-f", "http://localhost:8000/api/utils/health-check/"] + interval: 30s + timeout: 10s retries: 5 + start_period: 60s build: context: ./backend @@ -123,10 +135,10 @@ services: - traefik.http.services.${STACK_NAME?Variable not set}-backend.loadbalancer.server.port=8000 - - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.rule=Host(`api.${DOMAIN?Variable not set}`) + - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.rule=Host(`${DOMAIN?Variable not set}`) && PathPrefix(`/api`) - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.entrypoints=http - - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.rule=Host(`api.${DOMAIN?Variable not set}`) + - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.rule=Host(`${DOMAIN?Variable not set}`) && PathPrefix(`/api`) - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.entrypoints=https - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.tls=true - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.tls.certresolver=le @@ -143,7 +155,7 @@ services: build: context: ./frontend args: - - VITE_API_URL=https://api.${DOMAIN?Variable not set} + - VITE_API_URL=http://${DOMAIN?Variable not set}:8010/api - NODE_ENV=production labels: - traefik.enable=true @@ -152,18 +164,149 @@ services: - traefik.http.services.${STACK_NAME?Variable not set}-frontend.loadbalancer.server.port=80 - - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.rule=Host(`dashboard.${DOMAIN?Variable not set}`) + - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.rule=Host(`${DOMAIN?Variable not set}`) - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.entrypoints=http - - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.rule=Host(`dashboard.${DOMAIN?Variable not set}`) + - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.rule=Host(`${DOMAIN?Variable not set}`) - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.entrypoints=https - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls=true - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls.certresolver=le # Enable redirection for HTTP and HTTPS - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.middlewares=https-redirect + + + + # Qdrant Vector Database for Enhanced RAG + qdrant: + image: qdrant/qdrant:latest + restart: always + networks: + - traefik-public + - default + volumes: + - qdrant-data:/qdrant/storage + ports: + - "6333:6333" + - "6334:6334" + environment: + - QDRANT__SERVICE__HTTP_PORT=6333 + - QDRANT__SERVICE__GRPC_PORT=6334 + - QDRANT__LOG_LEVEL=INFO + + + # Redis for caching and session management + redis: + image: redis:7-alpine + restart: always + networks: + - traefik-public + - default + volumes: + - redis-data:/data + ports: + - "6379:6379" + command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 30s + + # Celery Worker for background RAG processing + celery-worker: + image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}' + restart: always + networks: + - traefik-public + - default + depends_on: + db: + condition: service_healthy + restart: true + redis: + condition: service_healthy + restart: true + qdrant: + condition: service_started + restart: true + command: bash -c "cd /app && export PYTHONPATH=/app && celery -A app.celery_app worker --loglevel=info --concurrency=2" + env_file: + - .env + environment: + - DOMAIN=${DOMAIN} + - ENVIRONMENT=${ENVIRONMENT} + - POSTGRES_SERVER=db + - POSTGRES_PORT=${POSTGRES_PORT} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER?Variable not set} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set} + - REDIS_URL=redis://redis:6379/0 + - QDRANT_URL=http://qdrant:6333 + volumes: + - app-uploads:/app/uploads + build: + context: ./backend + + # Celery Beat for scheduled tasks + celery-beat: + image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}' + restart: always + networks: + - traefik-public + - default + depends_on: + db: + condition: service_healthy + restart: true + redis: + condition: service_healthy + restart: true + command: bash -c "cd /app && export PYTHONPATH=/app && celery -A app.celery_app beat --loglevel=info" + env_file: + - .env + environment: + - DOMAIN=${DOMAIN} + - ENVIRONMENT=${ENVIRONMENT} + - POSTGRES_SERVER=db + - POSTGRES_PORT=${POSTGRES_PORT} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER?Variable not set} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set} + - REDIS_URL=redis://redis:6379/0 + - QDRANT_URL=http://qdrant:6333 + build: + context: ./backend + + # Flower for Celery monitoring (optional) + flower: + image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}' + restart: always + networks: + - traefik-public + - default + depends_on: + redis: + condition: service_healthy + restart: true + celery-worker: + condition: service_started + command: bash -c "cd /app && export PYTHONPATH=/app && celery -A app.celery_app flower --port=5555" + ports: + - "5555:5555" + env_file: + - .env + environment: + - REDIS_URL=redis://redis:6379/0 + build: + context: ./backend + volumes: app-db-data: + qdrant-data: + redis-data: + app-uploads: networks: traefik-public: diff --git a/frontend/.env b/frontend/.env deleted file mode 100644 index 27fcbfe8c8..0000000000 --- a/frontend/.env +++ /dev/null @@ -1,2 +0,0 @@ -VITE_API_URL=http://localhost:8000 -MAILCATCHER_HOST=http://localhost:1080 diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 8728c7b029..e36dd3399a 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,3 +1,16 @@ +# Development stage +FROM node:20 AS dev + +WORKDIR /app + +COPY package*.json ./ + +RUN npm install + +COPY . . + +CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"] + # Stage 0, "build-stage", based on Node.js, to build and compile the frontend FROM node:20 AS build-stage @@ -20,4 +33,3 @@ FROM nginx:1 COPY --from=build-stage /app/dist/ /usr/share/nginx/html COPY ./nginx.conf /etc/nginx/conf.d/default.conf -COPY ./nginx-backend-not-found.conf /etc/nginx/extra-conf.d/backend-not-found.conf diff --git a/frontend/nginx-backend-not-found.conf b/frontend/nginx-backend-not-found.conf deleted file mode 100644 index f6fea66358..0000000000 --- a/frontend/nginx-backend-not-found.conf +++ /dev/null @@ -1,9 +0,0 @@ -location /api { - return 404; -} -location /docs { - return 404; -} -location /redoc { - return 404; -} diff --git a/frontend/nginx.conf b/frontend/nginx.conf index ba4d9aad6c..bb4caf8b59 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -1,11 +1,37 @@ server { listen 80; + # Proxy API requests to backend + location /api { + proxy_pass http://backend:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # Proxy docs requests to backend + location /docs { + proxy_pass http://backend:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # Proxy redoc requests to backend + location /redoc { + proxy_pass http://backend:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # Serve frontend static files location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri /index.html =404; } - - include /etc/nginx/extra-conf.d/*.conf; } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ef1ad57113..46e47984fc 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,7 +9,9 @@ "version": "0.0.0", "dependencies": { "@chakra-ui/react": "^3.8.0", + "@chakra-ui/toast": "^7.0.2", "@emotion/react": "^11.14.0", + "@radix-ui/react-dialog": "^1.1.14", "@tanstack/react-query": "^5.28.14", "@tanstack/react-query-devtools": "^5.74.9", "@tanstack/react-router": "1.19.1", @@ -56,63 +58,69 @@ } }, "node_modules/@ark-ui/react": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@ark-ui/react/-/react-4.9.1.tgz", - "integrity": "sha512-grnfoSUrGxN0VMgtf4yvpMgin2T4ERINqYm3x/XKny+q2iIO76PD7yjNP7IW+CDmNxy3QPOidcvRiCyy6x0LGA==", - "license": "MIT", - "dependencies": { - "@internationalized/date": "3.7.0", - "@zag-js/accordion": "0.82.1", - "@zag-js/anatomy": "0.82.1", - "@zag-js/auto-resize": "0.82.1", - "@zag-js/avatar": "0.82.1", - "@zag-js/carousel": "0.82.1", - "@zag-js/checkbox": "0.82.1", - "@zag-js/clipboard": "0.82.1", - "@zag-js/collapsible": "0.82.1", - "@zag-js/collection": "0.82.1", - "@zag-js/color-picker": "0.82.1", - "@zag-js/color-utils": "0.82.1", - "@zag-js/combobox": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/date-picker": "0.82.1", - "@zag-js/date-utils": "0.82.1", - "@zag-js/dialog": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/editable": "0.82.1", - "@zag-js/file-upload": "0.82.1", - "@zag-js/file-utils": "0.82.1", - "@zag-js/focus-trap": "0.82.1", - "@zag-js/highlight-word": "0.82.1", - "@zag-js/hover-card": "0.82.1", - "@zag-js/i18n-utils": "0.82.1", - "@zag-js/menu": "0.82.1", - "@zag-js/number-input": "0.82.1", - "@zag-js/pagination": "0.82.1", - "@zag-js/pin-input": "0.82.1", - "@zag-js/popover": "0.82.1", - "@zag-js/presence": "0.82.1", - "@zag-js/progress": "0.82.1", - "@zag-js/qr-code": "0.82.1", - "@zag-js/radio-group": "0.82.1", - "@zag-js/rating-group": "0.82.1", - "@zag-js/react": "0.82.1", - "@zag-js/select": "0.82.1", - "@zag-js/signature-pad": "0.82.1", - "@zag-js/slider": "0.82.1", - "@zag-js/splitter": "0.82.1", - "@zag-js/steps": "0.82.1", - "@zag-js/switch": "0.82.1", - "@zag-js/tabs": "0.82.1", - "@zag-js/tags-input": "0.82.1", - "@zag-js/time-picker": "0.82.1", - "@zag-js/timer": "0.82.1", - "@zag-js/toast": "0.82.1", - "@zag-js/toggle-group": "0.82.1", - "@zag-js/tooltip": "0.82.1", - "@zag-js/tour": "0.82.1", - "@zag-js/tree-view": "0.82.1", - "@zag-js/types": "0.82.1" + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@ark-ui/react/-/react-5.15.4.tgz", + "integrity": "sha512-+xBKqxmt0JHewOsYsHXtedcdPsPZirAwd9y80JpyYfp8bSpIhmombLTjh0Ue9ktKPr7LdoZhV7qcX1TNrX4grg==", + "license": "MIT", + "dependencies": { + "@internationalized/date": "3.8.2", + "@zag-js/accordion": "1.17.4", + "@zag-js/anatomy": "1.17.4", + "@zag-js/angle-slider": "1.17.4", + "@zag-js/auto-resize": "1.17.4", + "@zag-js/avatar": "1.17.4", + "@zag-js/carousel": "1.17.4", + "@zag-js/checkbox": "1.17.4", + "@zag-js/clipboard": "1.17.4", + "@zag-js/collapsible": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/color-picker": "1.17.4", + "@zag-js/color-utils": "1.17.4", + "@zag-js/combobox": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/date-picker": "1.17.4", + "@zag-js/date-utils": "1.17.4", + "@zag-js/dialog": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/editable": "1.17.4", + "@zag-js/file-upload": "1.17.4", + "@zag-js/file-utils": "1.17.4", + "@zag-js/floating-panel": "1.17.4", + "@zag-js/focus-trap": "1.17.4", + "@zag-js/highlight-word": "1.17.4", + "@zag-js/hover-card": "1.17.4", + "@zag-js/i18n-utils": "1.17.4", + "@zag-js/listbox": "1.17.4", + "@zag-js/menu": "1.17.4", + "@zag-js/number-input": "1.17.4", + "@zag-js/pagination": "1.17.4", + "@zag-js/password-input": "1.17.4", + "@zag-js/pin-input": "1.17.4", + "@zag-js/popover": "1.17.4", + "@zag-js/presence": "1.17.4", + "@zag-js/progress": "1.17.4", + "@zag-js/qr-code": "1.17.4", + "@zag-js/radio-group": "1.17.4", + "@zag-js/rating-group": "1.17.4", + "@zag-js/react": "1.17.4", + "@zag-js/select": "1.17.4", + "@zag-js/signature-pad": "1.17.4", + "@zag-js/slider": "1.17.4", + "@zag-js/splitter": "1.17.4", + "@zag-js/steps": "1.17.4", + "@zag-js/switch": "1.17.4", + "@zag-js/tabs": "1.17.4", + "@zag-js/tags-input": "1.17.4", + "@zag-js/time-picker": "1.17.4", + "@zag-js/timer": "1.17.4", + "@zag-js/toast": "1.17.4", + "@zag-js/toggle": "1.17.4", + "@zag-js/toggle-group": "1.17.4", + "@zag-js/tooltip": "1.17.4", + "@zag-js/tour": "1.17.4", + "@zag-js/tree-view": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" }, "peerDependencies": { "react": ">=18.0.0", @@ -488,19 +496,102 @@ "node": ">=14.21.3" } }, + "node_modules/@chakra-ui/alert": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/alert/-/alert-2.2.2.tgz", + "integrity": "sha512-jHg4LYMRNOJH830ViLuicjb3F+v6iriE/2G5T+Sd0Hna04nukNJ1MxUmBPE+vI22me2dIflfelu2v9wdB6Pojw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/icon": "3.2.0", + "@chakra-ui/react-context": "2.1.0", + "@chakra-ui/shared-utils": "2.0.5", + "@chakra-ui/spinner": "2.1.0" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/anatomy": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.2.2.tgz", + "integrity": "sha512-MV6D4VLRIHr4PkW4zMyqfrNS1mPlCTiCXwvYGtDFQYr+xHFfonhAuf9WjsSc0nyp2m0OdkSLnzmVKkZFLo25Tg==", + "license": "MIT" + }, + "node_modules/@chakra-ui/close-button": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-2.1.1.tgz", + "integrity": "sha512-gnpENKOanKexswSVpVz7ojZEALl2x5qjLYNqSQGbxz+aP9sOXPfUS56ebyBrre7T7exuWGiFeRwnM0oVeGPaiw==", + "license": "MIT", + "dependencies": { + "@chakra-ui/icon": "3.2.0" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/color-mode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-2.2.0.tgz", + "integrity": "sha512-niTEA8PALtMWRI9wJ4LL0CSBDo8NBfLNp4GD6/0hstcm3IlbBHTVKxN6HwSaoNYfphDQLxCjT4yG+0BJA5tFpg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@chakra-ui/react-use-safe-layout-effect": "2.1.0" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/icon": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.2.0.tgz", + "integrity": "sha512-xxjGLvlX2Ys4H0iHrI16t74rG9EBcpFvJ3Y3B7KMQTrnW34Kf7Da/UC8J67Gtx85mTHW020ml85SVPKORWNNKQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/object-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/object-utils/-/object-utils-2.1.0.tgz", + "integrity": "sha512-tgIZOgLHaoti5PYGPTwK3t/cqtcycW0owaiOXoZOcpwwX/vlVb+H1jFsQyWiiwQVPt9RkoSLtxzXamx+aHH+bQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@chakra-ui/portal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/portal/-/portal-2.1.0.tgz", + "integrity": "sha512-9q9KWf6SArEcIq1gGofNcFPSWEyl+MfJjEUg/un1SMlQjaROOh3zYr+6JAwvcORiX7tyHosnmWC3d3wI2aPSQg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-context": "2.1.0", + "@chakra-ui/react-use-safe-layout-effect": "2.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/@chakra-ui/react": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-3.8.0.tgz", - "integrity": "sha512-UOkDxxMYHqQ6z/ExMcLYnjIIj2Ulu6syAkrpSueYmzLlG93cljkMCze5y9GXh/M6fyQEbLBuDVesULTqMmHuiA==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-3.21.1.tgz", + "integrity": "sha512-tc8SAeOZbOeOSY+BROE6o1FyzoS8sAuC6TAwlfUCZWhv9CMsxBisC88D4WI/puwnZVfUbzzhdVEQmWkCbJK6ag==", "license": "MIT", "dependencies": { - "@ark-ui/react": "4.9.1", + "@ark-ui/react": "5.15.4", "@emotion/is-prop-valid": "1.3.1", "@emotion/serialize": "1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "1.2.0", "@emotion/utils": "1.4.2", - "@pandacss/is-valid-prop": "0.41.0", - "csstype": "3.1.3" + "@pandacss/is-valid-prop": "0.54.0", + "csstype": "3.1.3", + "fast-safe-stringify": "2.1.1" }, "peerDependencies": { "@emotion/react": ">=11", @@ -508,6 +599,195 @@ "react-dom": ">=18" } }, + "node_modules/@chakra-ui/react-context": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-context/-/react-context-2.1.0.tgz", + "integrity": "sha512-iahyStvzQ4AOwKwdPReLGfDesGG+vWJfEsn0X/NoGph/SkN+HXtv2sCfYFFR9k7bb+Kvc6YfpLlSuLvKMHi2+w==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-callback-ref": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.1.0.tgz", + "integrity": "sha512-efnJrBtGDa4YaxDzDE90EnKD3Vkh5a1t3w7PhnRQmsphLy3g2UieasoKTlT2Hn118TwDjIv5ZjHJW6HbzXA9wQ==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-safe-layout-effect": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.1.0.tgz", + "integrity": "sha512-Knbrrx/bcPwVS1TorFdzrK/zWA8yuU/eaXDkNj24IrKoRlQrSBFarcgAEzlCHtzuhufP3OULPkELTzz91b0tCw==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-timeout": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-timeout/-/react-use-timeout-2.1.0.tgz", + "integrity": "sha512-cFN0sobKMM9hXUhyCofx3/Mjlzah6ADaEl/AXl5Y+GawB5rgedgAcu2ErAgarEkwvsKdP6c68CKjQ9dmTQlJxQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.1.0" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-update-effect": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.1.0.tgz", + "integrity": "sha512-ND4Q23tETaR2Qd3zwCKYOOS1dfssojPLJMLvUtUbW5M9uW1ejYWgGUobeAiOVfSplownG8QYMmHTP86p/v0lbA==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-utils": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-2.0.12.tgz", + "integrity": "sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@chakra-ui/utils": "2.0.15" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/shared-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/shared-utils/-/shared-utils-2.0.5.tgz", + "integrity": "sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q==", + "license": "MIT" + }, + "node_modules/@chakra-ui/spinner": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/spinner/-/spinner-2.1.0.tgz", + "integrity": "sha512-hczbnoXt+MMv/d3gE+hjQhmkzLiKuoTo42YhUG7Bs9OSv2lg1fZHW1fGNRFP3wTi6OIbD044U1P9HK+AOgFH3g==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/styled-system": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.9.2.tgz", + "integrity": "sha512-To/Z92oHpIE+4nk11uVMWqo2GGRS86coeMmjxtpnErmWRdLcp1WVCVRAvn+ZwpLiNR+reWFr2FFqJRsREuZdAg==", + "license": "MIT", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.5", + "csstype": "^3.1.2", + "lodash.mergewith": "4.6.2" + } + }, + "node_modules/@chakra-ui/system": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-2.6.2.tgz", + "integrity": "sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@chakra-ui/color-mode": "2.2.0", + "@chakra-ui/object-utils": "2.1.0", + "@chakra-ui/react-utils": "2.0.12", + "@chakra-ui/styled-system": "2.9.2", + "@chakra-ui/theme-utils": "2.0.21", + "@chakra-ui/utils": "2.0.15", + "react-fast-compare": "3.2.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0", + "@emotion/styled": "^11.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/theme": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-3.3.1.tgz", + "integrity": "sha512-Hft/VaT8GYnItGCBbgWd75ICrIrIFrR7lVOhV/dQnqtfGqsVDlrztbSErvMkoPKt0UgAkd9/o44jmZ6X4U2nZQ==", + "license": "MIT", + "dependencies": { + "@chakra-ui/anatomy": "2.2.2", + "@chakra-ui/shared-utils": "2.0.5", + "@chakra-ui/theme-tools": "2.1.2" + }, + "peerDependencies": { + "@chakra-ui/styled-system": ">=2.8.0" + } + }, + "node_modules/@chakra-ui/theme-tools": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.1.2.tgz", + "integrity": "sha512-Qdj8ajF9kxY4gLrq7gA+Azp8CtFHGO9tWMN2wfF9aQNgG9AuMhPrUzMq9AMQ0MXiYcgNq/FD3eegB43nHVmXVA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/anatomy": "2.2.2", + "@chakra-ui/shared-utils": "2.0.5", + "color2k": "^2.0.2" + }, + "peerDependencies": { + "@chakra-ui/styled-system": ">=2.0.0" + } + }, + "node_modules/@chakra-ui/theme-utils": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-utils/-/theme-utils-2.0.21.tgz", + "integrity": "sha512-FjH5LJbT794r0+VSCXB3lT4aubI24bLLRWB+CuRKHijRvsOg717bRdUN/N1fEmEpFnRVrbewttWh/OQs0EWpWw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@chakra-ui/shared-utils": "2.0.5", + "@chakra-ui/styled-system": "2.9.2", + "@chakra-ui/theme": "3.3.1", + "lodash.mergewith": "4.6.2" + } + }, + "node_modules/@chakra-ui/toast": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/toast/-/toast-7.0.2.tgz", + "integrity": "sha512-yvRP8jFKRs/YnkuE41BVTq9nB2v/KDRmje9u6dgDmE5+1bFt3bwjdf9gVbif4u5Ve7F7BGk5E093ARRVtvLvXA==", + "license": "MIT", + "dependencies": { + "@chakra-ui/alert": "2.2.2", + "@chakra-ui/close-button": "2.1.1", + "@chakra-ui/portal": "2.1.0", + "@chakra-ui/react-context": "2.1.0", + "@chakra-ui/react-use-timeout": "2.1.0", + "@chakra-ui/react-use-update-effect": "2.1.0", + "@chakra-ui/shared-utils": "2.0.5", + "@chakra-ui/styled-system": "2.9.2", + "@chakra-ui/theme": "3.3.1" + }, + "peerDependencies": { + "@chakra-ui/system": "2.6.2", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/utils": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.0.15.tgz", + "integrity": "sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/lodash.mergewith": "4.6.7", + "css-box-model": "1.2.1", + "framesync": "6.1.2", + "lodash.mergewith": "4.6.2" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", @@ -612,6 +892,30 @@ "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", "license": "MIT" }, + "node_modules/@emotion/styled": { + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@emotion/unitless": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", @@ -1065,28 +1369,28 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.9", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", - "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", + "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.9" + "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", - "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.1.tgz", + "integrity": "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.8" + "@floating-ui/core": "^1.7.1", + "@floating-ui/utils": "^0.2.9" } }, "node_modules/@floating-ui/utils": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", - "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", "license": "MIT" }, "node_modules/@hey-api/openapi-ts": { @@ -1115,18 +1419,18 @@ } }, "node_modules/@internationalized/date": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.7.0.tgz", - "integrity": "sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.8.2.tgz", + "integrity": "sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@internationalized/number": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.0.tgz", - "integrity": "sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.3.tgz", + "integrity": "sha512-p+Zh1sb6EfrfVaS86jlHGQ9HA66fJhV9x5LiE5vCbZtXEHAuhcmUZUdZ4WrFpUBfNalr2OkAJI5AcKEQF+Lebw==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" @@ -1140,9 +1444,9 @@ "license": "MIT" }, "node_modules/@pandacss/is-valid-prop": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@pandacss/is-valid-prop/-/is-valid-prop-0.41.0.tgz", - "integrity": "sha512-BE6h6CsJk14ugIRrsazJtN3fcg+KDFRat1Bs93YFKH6jd4DOb1yUyVvC70jKqPVvg70zEcV8acZ7VdcU5TLu+w==" + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@pandacss/is-valid-prop/-/is-valid-prop-0.54.0.tgz", + "integrity": "sha512-UhRgg1k9VKRCBAHl+XUK3lvN0k9bYifzYGZOqajDid4L1DyU813A1L0ZwN4iV9WX5TX3PfUugqtgG9LnIeFGBQ==" }, "node_modules/@playwright/test": { "version": "1.52.0", @@ -1160,6 +1464,337 @@ "node": ">=18" } }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", + "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", + "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", + "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.40.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz", @@ -1858,6 +2493,23 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/lodash.mergewith": { + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz", + "integrity": "sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/node": { "version": "22.15.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz", @@ -1877,13 +2529,13 @@ "version": "15.7.11", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", - "dev": true + "devOptional": true }, "node_modules/@types/react": { "version": "18.2.39", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", - "dev": true, + "devOptional": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1894,7 +2546,7 @@ "version": "18.2.17", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", - "dev": true, + "devOptional": true, "dependencies": { "@types/react": "*" } @@ -1903,7 +2555,7 @@ "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "dev": true + "devOptional": true }, "node_modules/@vitejs/plugin-react-swc": { "version": "3.9.0", @@ -1919,508 +2571,555 @@ } }, "node_modules/@zag-js/accordion": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-0.82.1.tgz", - "integrity": "sha512-DWaElpm6RhntW8zVPMfd+s461FuXi6rv4pDPpXb4xCAJ0KTkBzS6PFxoBLL+11Mjv9XioaBoJatIGOCF8GAtTA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-1.17.4.tgz", + "integrity": "sha512-WkzoksfxJjuSdq+hIHCINc6hQtoYo5Nf0SfuInBiehRnoJtVjmpqk8VLxhLWhwFD/KMqz0wtWcM0itUGNpOyiw==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/anatomy": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-0.82.1.tgz", - "integrity": "sha512-wpgU7LyU9St3o/ft8Nkundi7MkW37vN1hYc2E7VA/R6mun0qiANsEf83ymIlAYnovLC6WUlBso9xwqejr6wRCg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-1.17.4.tgz", + "integrity": "sha512-EDc7dD5nnr5T3kujMc+EvWIAACZ45cyeKKiPDUCAsmrOAYxIpD+Efh5lvKum6XLIUyUNnkpEVTazVNOeaoZBtQ==", "license": "MIT" }, + "node_modules/@zag-js/angle-slider": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/angle-slider/-/angle-slider-1.17.4.tgz", + "integrity": "sha512-atke7qq2dd2f4Om4T6k9GYi5bvUdBWDuwDIaBC39Kygyrj8IjShlcyv+QETbX0MaghIhbLBJQuvc+7G3eIMF1A==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/rect-utils": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" + } + }, "node_modules/@zag-js/aria-hidden": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/aria-hidden/-/aria-hidden-0.82.1.tgz", - "integrity": "sha512-KSz9oMY9rn1N3k3tFTKHlU66eQf8XZ/gy/ex27J0ykZoaYJplWQerSZvVakbILeh+rtpvdiTNaSgrCAwYwvAPA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/aria-hidden/-/aria-hidden-1.17.4.tgz", + "integrity": "sha512-P7aSTINxBwGbDUxhemto10JsajbE+kIzKrPMOWAbIipfFSwPtaN4XJRg2aQHZFBuHNm1n2x87n2TJBwjAlPiNQ==", "license": "MIT" }, "node_modules/@zag-js/auto-resize": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/auto-resize/-/auto-resize-0.82.1.tgz", - "integrity": "sha512-adOB7Y4p4i6b8GJv4V6qhlK1YRj4Ejs5I+eWFd8Rx535uQIcxEEVtpEAD5SRYg5PNk1ikaT+GCoHnTadGj6PuA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/auto-resize/-/auto-resize-1.17.4.tgz", + "integrity": "sha512-kCC0cvuxG/yf28P52waRlz7FaliPrOyPXH+XM+GrznLkC8/TpMeR092G9+oHiYauNESTb+yyQzGgKqW6xFd/Rw==", "license": "MIT", "dependencies": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "node_modules/@zag-js/avatar": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/avatar/-/avatar-0.82.1.tgz", - "integrity": "sha512-XjRvDRmBxwy5OtIzlQOpf7zNk4g0b/uA7qZve5Hz0R7yWOu+NFlbFv0GsvRfgyYMCT5J0xBu271EG9FJq3QKyw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/avatar/-/avatar-1.17.4.tgz", + "integrity": "sha512-+B4esXErOoiYNmHarg9aZWAhUhx6bzoIp31zCMkb6lNUKCDb8hBpFIWYpkgOrPmMaMka2zSYSvpfx6+4zA1Lcg==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/carousel": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/carousel/-/carousel-0.82.1.tgz", - "integrity": "sha512-MO9+9oedxdKynxgvLLzXs+VQSOhu+GvsCLV4fBt7nMBMGIRHtRSzXHRNRkO0aqbsO/nKQ8TFH7GYzI1NqT/y4A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/carousel/-/carousel-1.17.4.tgz", + "integrity": "sha512-/n6nK5N9d+j3C+Q5GFnkeX4pMzZY/spKKhAbEMk2MPIHcbX50Ozdn+2MIGz0opAWtVwMXPhbl+WFeoNr8jbiSw==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/scroll-snap": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/scroll-snap": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/checkbox": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/checkbox/-/checkbox-0.82.1.tgz", - "integrity": "sha512-yD/h8ao/JTljEo+zthpKzTy/f9fqOlJ7Nd6psPoSKZy2MRGD0TDUbOjravb3icVgjTLCiaPVWMWdonny08Me6A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/checkbox/-/checkbox-1.17.4.tgz", + "integrity": "sha512-nHrbGhHHUdtvkaJ4jAeCzAG5ioEm719a815oxji2rM1Ei+tCD0mrHCntIeuFejVCGnvR2wFnNJaWaZlES85Vqw==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-visible": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/clipboard": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/clipboard/-/clipboard-0.82.1.tgz", - "integrity": "sha512-r1r3vwozs+lyNgccR3OfmYAydP0cJbIHGsgDKGuempinqv6xIoptHOkFgWNd6Kxz/3MnxP+BMEy6fZzECXkhdQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/clipboard/-/clipboard-1.17.4.tgz", + "integrity": "sha512-WieXgxRCbBayngNSSMMj2zVcR0QO0cT5cZZuYLSn1eTbglo9J4sAX1QyEvHwbZWVt/rEokj3Gdp/Pme6rAQpwQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/collapsible": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/collapsible/-/collapsible-0.82.1.tgz", - "integrity": "sha512-TuggUoXRVBOwACksi63TsN2rOukzUpe6oVMUvp9MaQaDbg9gpw0JzLTrdAaHfE+bhgXAb3EjN6wcZjq8zBctZQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/collapsible/-/collapsible-1.17.4.tgz", + "integrity": "sha512-2bDQYGYoiHWECQPQNeC8ekCshXoXb1i3yY9U3siSyKxMZdBL4VdW5+0UOQoleperbN9NONeEcHW0H10cPofEIA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/collection": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/collection/-/collection-0.82.1.tgz", - "integrity": "sha512-uteM+xWZlWhRQe5biA5QWyva9PdzXONs+bpycUtZt8MakQgPmhW2whY9r1aW5NFVb/ScTwGAIGB3Eyc6Npz7Wg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/collection/-/collection-1.17.4.tgz", + "integrity": "sha512-N4FUhh6avw146IAUKxMj57clXOoN1XjY45ETWJMfahlmmmnttaCKuiiUj57/XIgmt3Vpg2bYIthcyTxeI+K4QQ==", "license": "MIT", "dependencies": { - "@zag-js/utils": "0.82.1" + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/color-picker": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/color-picker/-/color-picker-0.82.1.tgz", - "integrity": "sha512-/MShDVBFNnXResLzeyWyKApeHuB9rmUeJo3WD/Bl6rTwjmvVCKRYguIe1SQviOokMLjuAyh0YWXdKMQw0HvMqQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/color-picker/-/color-picker-1.17.4.tgz", + "integrity": "sha512-Zue+eoBeTyKNiHW8lSN+GMWHWsPdl0yZozuRmtuxpKYnI30SSr6GIs88GCY9Inosxz9RqKx7t7TMxsyJlLiJVA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/color-utils": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/color-utils": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/color-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/color-utils/-/color-utils-0.82.1.tgz", - "integrity": "sha512-BMSYcBeypGX0wCLszU2jxWBRUmd5/wPDJ59Y3Zwl9yNld0gtMnuBLSUeokMcG0UVQ/BxkyrWu3VDkKTUYKprqQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/color-utils/-/color-utils-1.17.4.tgz", + "integrity": "sha512-gasEa7yNMRW3dyJPtSVgZkXB5yrDF21XEaT+x8QLzj7WDutXeCOVPpc1GzBD+DupCcb6mTMUbhYdaf52WQxmWA==", "license": "MIT", "dependencies": { - "@zag-js/utils": "0.82.1" + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/combobox": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/combobox/-/combobox-0.82.1.tgz", - "integrity": "sha512-Me3a0Sw4dTtmBRmbLGO/C1LJ4btZwbd5RLYnf8RPhEnqGJ5Z05i+ffWEe+SNBvpQO14njqBcF6P8VypVD/Ro1A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/combobox/-/combobox-1.17.4.tgz", + "integrity": "sha512-E7mDsVEcIVbRUUIzsI8+OfXyTdPCih60/g7SRd5Mu8cLnzOxdC4tmeoIY+42otPr0e1bieVMjUXTEKR7wvQuAA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/aria-hidden": "0.82.1", - "@zag-js/collection": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/aria-hidden": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/core": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-0.82.1.tgz", - "integrity": "sha512-Ux0fkt1PumcqLwExcEozCMEfKBxtd2JlnitXo4hR3lJW5q9G52FkgWDyPSrhblyTkX+7RgxViZTMnHxaXs99jg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-1.17.4.tgz", + "integrity": "sha512-DIL2MXMLBYKR3pnjGGodiEUkY+ST/J81gtIJ32bLYxWWiMeX0SoPIvDZ9tqDHub9Kkd5CF07onXHkdAmB9Djrg==", "license": "MIT", "dependencies": { - "@zag-js/store": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/dom-query": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/date-picker": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/date-picker/-/date-picker-0.82.1.tgz", - "integrity": "sha512-f+4CV29+hcQ3Yw9hh0yyVRANONIUEWIrPS1fpnrrUNtIC0Y7f1Ajx+x089X9VxgQhwreK1sEwpnrL2vIqy+9+A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/date-picker/-/date-picker-1.17.4.tgz", + "integrity": "sha512-yNYLFlNnmBI+9gzHmrGrDsGSeHa8cj6+pWhNutIVAT9pyEmg/6AciFndL5+P9bolKo59qtXLpX8libxZ4wLr2g==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/date-utils": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/live-region": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/date-utils": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/live-region": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" }, "peerDependencies": { "@internationalized/date": ">=3.0.0" } }, "node_modules/@zag-js/date-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/date-utils/-/date-utils-0.82.1.tgz", - "integrity": "sha512-z9sHtgV4fvtXsqLaTD4/o+D+H5wumLYhIw/Bj3yC41gR5oa4Wo9QifRT9DBfvuokmXsrnRZ8k32hUtWoYb6M/A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/date-utils/-/date-utils-1.17.4.tgz", + "integrity": "sha512-kPw7GLnj560NdUpXJ1SeoJkNSIddZBa+Sd2fPlyDwqxB5lptqNeRK9FcascRL12PgI7EeM7/R9MVTkTPGdQNjg==", "license": "MIT", "peerDependencies": { "@internationalized/date": ">=3.0.0" } }, "node_modules/@zag-js/dialog": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/dialog/-/dialog-0.82.1.tgz", - "integrity": "sha512-oqi+6Y/rx6ZKxg3s9r6bIuo33x+5+UDhvrlk31kE3LWgU1KJjVV0VEkFMK9B1SJTY7IizhlWMyDx+JXJ+jOy5Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/dialog/-/dialog-1.17.4.tgz", + "integrity": "sha512-UCTcGlAlbTSS2Po5XvOOl7FiLba5+kh0Vltz8NAZUNn4e87LeitQVTW68k/pxa2nnnaKfPN6CsAWYQ21aZOcwA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/aria-hidden": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-trap": "0.82.1", - "@zag-js/remove-scroll": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/aria-hidden": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-trap": "1.17.4", + "@zag-js/remove-scroll": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/dismissable": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/dismissable/-/dismissable-0.82.1.tgz", - "integrity": "sha512-vs+zkORzaeNzX4Wsy4OkW1AVce7l4Tc6DHZq8gqNB5SvhK+5wEPl6EmacQRvZyoCxi2m6xpaI98UkLCmVJKU+Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/dismissable/-/dismissable-1.17.4.tgz", + "integrity": "sha512-LkFdUz2Ay3D/CsSjQSVjxQwzH6U5rU6cvEcUTOM90RUSozuV2pAK5NnI3JH3jAy1USlpTbjxHL+2bdep2jkAEg==", "license": "MIT", "dependencies": { - "@zag-js/dom-query": "0.82.1", - "@zag-js/interact-outside": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/dom-query": "1.17.4", + "@zag-js/interact-outside": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/dom-query": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-0.82.1.tgz", - "integrity": "sha512-KFtbqDUykQur587hyrGi8LL8GfTS2mqBpIT0kL3E+S63Mq7U84i+hGf3VyNuInMB5ONpkNEk5JN4G9/HWQ6pAQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-1.17.4.tgz", + "integrity": "sha512-1fNDCWkHRZXB4dD2hoiyMy0cSkrB/u4fur3To5sOKteka5e9om1/YdbYxXNLmVfeTiC/SJtWNelXP7c/8uDwOw==", "license": "MIT", "dependencies": { - "@zag-js/types": "0.82.1" + "@zag-js/types": "1.17.4" } }, "node_modules/@zag-js/editable": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/editable/-/editable-0.82.1.tgz", - "integrity": "sha512-V5i3kYSHFJYj8914nBf4VKKtm6m59gG482vm20As4EnLcwGFrOBbm4HXUgsKq0wYSLy/lTtvMrUT8Iqudye2gw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/editable/-/editable-1.17.4.tgz", + "integrity": "sha512-qTfvrhbHtfvFZv3l+qAlweOpWyzDwYRQ1xrI+Sc8pCHhml6QiZ1UFUpYbiQWPn7dqdzBEVUIhjzDX4lzjsWGSA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/interact-outside": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/interact-outside": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, - "node_modules/@zag-js/element-rect": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/element-rect/-/element-rect-0.82.1.tgz", - "integrity": "sha512-xXUjmeIUdxkxic5bepp6fVqN9Qs+54PXCAUl6g/DtJecQVmVooIfa3SLSULhany4aR4mlGojp5TJxvSpUBA58Q==", - "license": "MIT" - }, - "node_modules/@zag-js/element-size": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.82.1.tgz", - "integrity": "sha512-k1rOE6NhoULI9d5pt2qVUxWCQVEf3OTPH8UDnbsdf11xn+hMCzRYd9lekUdVGrcHHGvEK+W6iAfWZnlwsJsmow==", - "license": "MIT" - }, "node_modules/@zag-js/file-upload": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/file-upload/-/file-upload-0.82.1.tgz", - "integrity": "sha512-6cgJsy9bf2DB0v+CVq1L4g4aCePTpfWsV4C0HC+82K+OSPomiIPsQS87wo4+eAcy3z+80Qh+uglZCFAwkW8W+g==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/file-upload/-/file-upload-1.17.4.tgz", + "integrity": "sha512-onV7jN2l9oXcKAuO/KY0TNcqyaFroQ8JjY+QxOOrZEmhvo48h/Lbi0FwBfk3syNWCRK3ihpRQbKOa1lthupGjg==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/file-utils": "0.82.1", - "@zag-js/i18n-utils": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/file-utils": "1.17.4", + "@zag-js/i18n-utils": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/file-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/file-utils/-/file-utils-0.82.1.tgz", - "integrity": "sha512-/u86hMd+E5UCrrY9akDAExkO7sgPA1lXzWC9gSX4LSxHATk7Vo4o5+4LiE1MX4WZRytOhtxAycJzNDVpqzmppQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/file-utils/-/file-utils-1.17.4.tgz", + "integrity": "sha512-eg+ywy2qJn+rXz7wBsJc0N0H6qmKEMvxaWtsynBZ+XDbyrEec/aHNRDaM+l5xdFjDKb5/R151nEDXgnBAT8miA==", "license": "MIT", "dependencies": { - "@zag-js/i18n-utils": "0.82.1" + "@zag-js/i18n-utils": "1.17.4" + } + }, + "node_modules/@zag-js/floating-panel": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/floating-panel/-/floating-panel-1.17.4.tgz", + "integrity": "sha512-YgGP0PybQ0adlW6aOkFaho1tOzSk0rIVhCzsCQmln9mhSYgSCgwMoJIqfsFTLVpKB7TO155okOh5kwelH75Jfw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/rect-utils": "1.17.4", + "@zag-js/store": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/focus-trap": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/focus-trap/-/focus-trap-0.82.1.tgz", - "integrity": "sha512-z5OzmR8O3n2043Lwhp1qcizNHXvzc/Xteb3hWmxbX9hR3k0wHJeMXMj3GTDO0FBixRt+d8iHEmt3/8CkI72mqw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/focus-trap/-/focus-trap-1.17.4.tgz", + "integrity": "sha512-6exU3DOkyqE2LSRydhgQIho/XhNOvQ35AEbYN81I6yniJPARbkGmDcQaKHZXSL7+tAe0ynX09yfVo4Cskio8Ow==", "license": "MIT", "dependencies": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "node_modules/@zag-js/focus-visible": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.82.1.tgz", - "integrity": "sha512-b87FqZO6e9RmTY4msEzwZ3hZ8pRuPd2vbR2b6SlXr6ohtmGKlGgBGO4kmarZN/ClE+7VOnOEqIicatRBEgX9bw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-1.17.4.tgz", + "integrity": "sha512-9P1GtsFqbuLcplwK/Y7MdnQz9NipYUjef8PS2/duQzRf3UM99/zu1ZbRqwNIW/Tf5ztvet3+dMBAN5HEyYW0Rw==", "license": "MIT", "dependencies": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "node_modules/@zag-js/highlight-word": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/highlight-word/-/highlight-word-0.82.1.tgz", - "integrity": "sha512-lS5r3V0l7Z53QyNwkxulYp5QYA9mFkU+3XsZqfM6cBjh+wmGE1xeIwknAmFtYvuYNK37AwT7pp5z0Rm1Ep6WVQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/highlight-word/-/highlight-word-1.17.4.tgz", + "integrity": "sha512-uBK/5OsopYE5qBjkIoQuqvgd6CTnKpttt4+ODFjPV0NPImgcDuqBT1KlFZZZEPZ58fu1TtNU6hNVKHmZ4EzUnw==", "license": "MIT" }, "node_modules/@zag-js/hover-card": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/hover-card/-/hover-card-0.82.1.tgz", - "integrity": "sha512-fp9t/PNXODwxXR1X+VzgYeSpgoJ+M3W/qvuA2stgPI4kEinwKEssSlP2sH6gTmQVZKL8SV1jiNQinVh00NE85g==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/hover-card/-/hover-card-1.17.4.tgz", + "integrity": "sha512-yOVqj2KUxcMZx6B0LpkMRa1q736eVUXTzQD6Keh4cKxtnCFE+ydYVv70xHL4CLWFqz6+PFRYApgzd05IIbff7w==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/i18n-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/i18n-utils/-/i18n-utils-0.82.1.tgz", - "integrity": "sha512-YcTIqka6+/YoH2VRBMnv3CvTjHdUo/NG2nMenAB9Wq0MLTn+TAtcsujenz7ckJcgayVhFAchWNhwK9+/cs1dAw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/i18n-utils/-/i18n-utils-1.17.4.tgz", + "integrity": "sha512-HiRKMQGaZUpjqekq1h1UlMqquIBnQYSiGpW9vWCUbKs5hr7z3VIgJtKoxdCsBkno7vBEejl316DIIDh3N2qbeA==", "license": "MIT", "dependencies": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "node_modules/@zag-js/interact-outside": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/interact-outside/-/interact-outside-0.82.1.tgz", - "integrity": "sha512-WcWJB5kM41fDM6YMGC3ZEPVn1q3Nrm+cAFkllRJrRY4+bUKXmtN8bqDaRKghP+dG5CXz66SiM6xBvDE4nqtK5Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/interact-outside/-/interact-outside-1.17.4.tgz", + "integrity": "sha512-jd7/4V7ESS6FJILPWIm5CmXVR+maZ4fQmQUPV56WOURKdl2LZ2bPgfjvEaVI9BTm7qPTML6O55xgB87rS/sXlw==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.17.4", + "@zag-js/utils": "1.17.4" + } + }, + "node_modules/@zag-js/listbox": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/listbox/-/listbox-1.17.4.tgz", + "integrity": "sha512-14OReAbUZNEYjy2eBPqI7FUxts0kTjQS268aukfzLvHcJHAHTcP9ru7XMftZlPbQBofPGr/lSLhIa4NZJF3vrw==", "license": "MIT", "dependencies": { - "@zag-js/dom-query": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/live-region": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/live-region/-/live-region-0.82.1.tgz", - "integrity": "sha512-BmSXc41y1uOra/UV1lt8BurWkuwne/+c371IJCK6l+MWsO0ufq1lrjfx4cyFf5yhVcPRkhv/b/0i+7RxfDSK1A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/live-region/-/live-region-1.17.4.tgz", + "integrity": "sha512-fP2f6C6vEcWydvhYKMYWaVu8tqyiCnKJx8auJ2zL/yZGLz/W3xDdRRqHJCfneilN7m8C6tJhWBBZm5Th22bGmQ==", "license": "MIT" }, "node_modules/@zag-js/menu": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/menu/-/menu-0.82.1.tgz", - "integrity": "sha512-faAlQZYeWHcGH8nIxBYh7HHfVjSKsHV8yUsbhMD0XkePWM6eB+dPRd/Fc3DeT8ieM8+sUODnTHEuxar0i48v4w==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/menu/-/menu-1.17.4.tgz", + "integrity": "sha512-KzpvU/rPiPFDexcD+RmcLhPOII5SPgGSSdidpz3pTBy8yEwnwOSoN0PGHm8WnOD4US2wZOHvOqR+Rov8IbmKWw==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/rect-utils": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/rect-utils": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/number-input": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/number-input/-/number-input-0.82.1.tgz", - "integrity": "sha512-QIQlxlxM78+TkEhPEGlTbkBR3G2ngm5vhc3BFw4sG6ABMyre8TiIH37EqQB7EGKyAcuz6QwPk3AervHMFKe4YQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/number-input/-/number-input-1.17.4.tgz", + "integrity": "sha512-lyrZwr3X1wicL8MThZvu4JH5pwldYO2gKQ+CVgMTx6H2epQNVJJ9i8v/+buUNB9/2ufjUV0MaxQ2fuGTXyjAKw==", "license": "MIT", "dependencies": { - "@internationalized/number": "3.6.0", - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@internationalized/number": "3.6.3", + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/pagination": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/pagination/-/pagination-0.82.1.tgz", - "integrity": "sha512-1Rsd3cSnlewefNB1RBI0ymK5wlgiBcK42H1IrJIhly6+SXDAhp0Oc45ofsCzpfhkQ4be+A9Cb30ayc6J4ZU2kA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/pagination/-/pagination-1.17.4.tgz", + "integrity": "sha512-yTOcwRdJ0CozEzw0Q+lAUkpWUERFVCCSx9qqIAGqF5jEZSWefUWMQVcPRqupLQ51mhCXdt+wDDh2mTY6Mr+L3A==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" + } + }, + "node_modules/@zag-js/password-input": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/password-input/-/password-input-1.17.4.tgz", + "integrity": "sha512-h77V18+KBvZHUcARnr+Qw+P5vGvvSC9UMzjnE2SpMIpyvOIr1Fp+4TCGKVEIIsWR0LzWnK79UNExVj1Th3t1TQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/pin-input": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/pin-input/-/pin-input-0.82.1.tgz", - "integrity": "sha512-P7UN7rIt03YHt05SuK+kZ9mhl4AfvCvaSGB/9KzEq5r6p1D3lc4+0LVkkOvL2EEB8vbGY/y5BNcvaF2jPQPH5Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/pin-input/-/pin-input-1.17.4.tgz", + "integrity": "sha512-k2rhmS0oAPUE93DgdHtV7HkpBvTj3iGvUusVwmifE42ct1VnuuedXHKlicGbJ2ZXWelXmKd5675LHfwmF68h2A==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/popover": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/popover/-/popover-0.82.1.tgz", - "integrity": "sha512-zZ8H/jcjaXcLRX4dBcmandexeKV/5cBOt4AUVEnd3/X5NFFkA2Njz8rpQFcNRZl814NxG4RCchIu8kmonmUKCA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/popover/-/popover-1.17.4.tgz", + "integrity": "sha512-uDRfw5/F3FPeanOJbXnVmk5c+RFFkQozZ6dn3qdnynWn1sLh56Kf5Ys4X+MQInxqUKdtDCb7cO2tfkAZXE5ZOA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/aria-hidden": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-trap": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/remove-scroll": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/aria-hidden": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-trap": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/remove-scroll": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/popper": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/popper/-/popper-0.82.1.tgz", - "integrity": "sha512-vQTmVUs6aLGqKmWb+FnLDntsulvd/sCvgndeTmwOHRW8PBwPb86aDnvNrNosBSS+Kk9p6CMJwWZ6CuPWR5Kf7Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/popper/-/popper-1.17.4.tgz", + "integrity": "sha512-ZdlDcaBzDx4XUzicTviaCP0Q6W1AXwRzdPVO2TzosqQyyn/tYqEfcJePYu9XVsr1Y6bkume4Pt0ucuRN+kUeYQ==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "1.6.12", - "@zag-js/dom-query": "0.82.1", - "@zag-js/utils": "0.82.1" + "@floating-ui/dom": "1.7.1", + "@zag-js/dom-query": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/presence": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/presence/-/presence-0.82.1.tgz", - "integrity": "sha512-eZeAkq2s7NYCiNVMvkWL2Or458hZj71u7ygCt6skA18sO1ZksY+qIFqj99leCov+fesz06Hf8bxZz5029t/Wjg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/presence/-/presence-1.17.4.tgz", + "integrity": "sha512-xFEITSvZjoNYh3Ea+48tFqwwsOtSeEa27c3GOa1ToCTs0J+7SrP19bj5w7Hnbk5cGY/4P5OD8OiMKvkPughjEw==", "license": "MIT", "dependencies": { - "@zag-js/core": "0.82.1", - "@zag-js/types": "0.82.1" + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4" } }, "node_modules/@zag-js/progress": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/progress/-/progress-0.82.1.tgz", - "integrity": "sha512-Fy1EjUda7o7e/yTKbZgKKayGOsHxkjLG+x0AakHmbR/k2VKbM4QuFHB9RJLlqNd9a+m/BzS1kEKWzCJ7/mXL9Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/progress/-/progress-1.17.4.tgz", + "integrity": "sha512-1FWUIizd8OMcK+0uUA/6ly3VJd5eHeOZkXC4lIWDGGwLhfEv2Lm+pgF5Ix5u1mtcmawBbhpkSlYjc1CbsjUTQQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/qr-code": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/qr-code/-/qr-code-0.82.1.tgz", - "integrity": "sha512-E1N1o1dPVuhWkcrg6urut2aaCqrc16OeE9VJh1mAGIUknF3p0QScH+ql7J/n9r8WOa21xyF6HLKhnWVPRQmHGg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/qr-code/-/qr-code-1.17.4.tgz", + "integrity": "sha512-z2FLUlGCLmKcNyXCdeWJkovLo4NvFdRAe43psn0M8rhd470rYCzol1/86s2G72DjqUT0ZwadkfgRjLfaLHkYdQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1", + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4", "proxy-memoize": "3.0.1", "uqr": "0.1.2" } }, "node_modules/@zag-js/radio-group": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/radio-group/-/radio-group-0.82.1.tgz", - "integrity": "sha512-YTqP4Ok2YEmEXCEiNW2tufZ6svt4sh7KHqrHZq81vPAJMKKhVosP6LnZvmt4dVn6tKJ0OU8idwFVtPM5jSAWoA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/radio-group/-/radio-group-1.17.4.tgz", + "integrity": "sha512-/u9ugWth+FPu3W1VUTuBIVq3TbJZMLYF8cFPhvTgIjBvbQw9Oe+TW+WywyH1z7Oaz03e4IYhW445sWGoC9TNvw==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/element-rect": "0.82.1", - "@zag-js/focus-visible": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/rating-group": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/rating-group/-/rating-group-0.82.1.tgz", - "integrity": "sha512-ULl0OA207b6Ilsr2QWt4dbx58hA/NnyCmHpvv1pAYSlH3K0Es5b25B80Cc5jM/3NK3yqoY81OkS9U8lxmpWo+A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/rating-group/-/rating-group-1.17.4.tgz", + "integrity": "sha512-5KQdf+CLX3RzCu7Bj8Xn7AKeDU+sxCjxCcbjs8VviLl6Rj/OaFUoUomZFf/wLsJLY1tqk6PD7dX4NczY7YC2YQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/react": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/react/-/react-0.82.1.tgz", - "integrity": "sha512-CZivUTFQ4TdRKTN+9wpWAo0lEZlMnbjJPVn2VJVpcz+eRNUeoVzevkNY/OzAqdV3mp+VtdNabQn1fAz8ngViPQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/react/-/react-1.17.4.tgz", + "integrity": "sha512-43TEe1Afjh1RR3Byxib/jZ2Wn4UVdZY5Irx5v3tnp8NY8BFeswPhP28e6W2NT4c/UZoWeRxYlXDdrRS2p8L8Wg==", "license": "MIT", "dependencies": { - "@zag-js/core": "0.82.1", - "@zag-js/store": "0.82.1", - "@zag-js/types": "0.82.1", - "proxy-compare": "3.0.1" + "@zag-js/core": "1.17.4", + "@zag-js/store": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" }, "peerDependencies": { "react": ">=18.0.0", @@ -2428,269 +3127,281 @@ } }, "node_modules/@zag-js/rect-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/rect-utils/-/rect-utils-0.82.1.tgz", - "integrity": "sha512-gXmvj1wK9FeToOCzvoZ5gycqUNRzfeqd84uwJeG9zA8SVdoyEnoAji8IAynneq8t3LbiNUcu37wjTw0dcWM6ig==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/rect-utils/-/rect-utils-1.17.4.tgz", + "integrity": "sha512-DiYNOwtVek9qwtbV906zjNpM8dmJL4sp131rPRgRStTg8MHpfW2PUOaxFklKh9/ykFwPDu6rx7kQ9Y2P4ez/xg==", "license": "MIT" }, "node_modules/@zag-js/remove-scroll": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/remove-scroll/-/remove-scroll-0.82.1.tgz", - "integrity": "sha512-68cvXvqgNOlucbnGKRyephk8Qg8wb4xpjgUdmF9xQwICdY/uhW2p4ZGJ4471TDCDIlpoBrJPYsWqV2oWH3QNfA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/remove-scroll/-/remove-scroll-1.17.4.tgz", + "integrity": "sha512-EY+N1UodKfu2omYknbWfv+33pljfVW5ZX01iuSlTng3Vx5Zn6xlQCTxpVWvDidACEN6jjBn00QFbGWEhDDBpdw==", "license": "MIT", "dependencies": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "node_modules/@zag-js/scroll-snap": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/scroll-snap/-/scroll-snap-0.82.1.tgz", - "integrity": "sha512-HL3MkBpWx4Cw0+h1UP/PnvLP3Z1T+F5mkeS8HWmiP+KPzhtFiEBRrve+xk7h7BMXifteg2UZy53ZiZfJeGsd3w==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/scroll-snap/-/scroll-snap-1.17.4.tgz", + "integrity": "sha512-bdYtDdJjXcupjoTs5n3Z310wEDrsykgWIKVOy5r4daNp+aH99YHBvINt0BUzjfyCpoEH0KvM9KwKlwOhq7XUNA==", "license": "MIT", "dependencies": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "node_modules/@zag-js/select": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/select/-/select-0.82.1.tgz", - "integrity": "sha512-cc6D8Iz+Ewnx9L0J63QGqC2bbiwzCEcJVE/j4OZDcy4Qk3lqr3qA09uuJbQxAi7yvIeB44DIEt9ryTZPkZbgiw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/select/-/select-1.17.4.tgz", + "integrity": "sha512-Yy/83xydKl/Qz3BoeNCwu964lLRDqoF4fsOWPeOFEN6HHftLD7NNNO7eIqe2Qe84ZBwAeQeZ8cNNI2oYHFc/ag==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/collection": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/signature-pad": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/signature-pad/-/signature-pad-0.82.1.tgz", - "integrity": "sha512-s8ae88OpAafkpuqimO9beUiVTn3FG+bnWeWnYQOLtNYMCNHzQbVZp9QBNbOoUpNcDT14mx9rfZe98BqfiMohFw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/signature-pad/-/signature-pad-1.17.4.tgz", + "integrity": "sha512-nGv9uBNkq+jrLfdN+wuINA+ch0jZs/m1UUDcyUvpRfQa/AlkNdv9oC8p6KUJwNhunTQN6E2RCZqO43q49ioEtg==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1", + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4", "perfect-freehand": "^1.2.2" } }, "node_modules/@zag-js/slider": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/slider/-/slider-0.82.1.tgz", - "integrity": "sha512-qXVvXbDRq6Cla036M9OH6plO7ubefM7k65NJQKjtITDua+VliKQLXj9BrdPLT9K96wWntW+D/TiZXE+JNbR4ow==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/slider/-/slider-1.17.4.tgz", + "integrity": "sha512-Iq3pgLmJIvmQXaUm/+Xt1/s1IV1p73E7ySbThdZ8EADDn60m5ESVTwEymK9jnH10hpXuxDvI1GcbWPOTrIxwYQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/element-size": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/splitter": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/splitter/-/splitter-0.82.1.tgz", - "integrity": "sha512-eMNncj+pcepYTf+51s4ysDS/tjtKXswpwsSQR0AeNqCE3SW3TGzHOM0+uheyjgv9EmDGDrr3Imdo0PCkq3bqug==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/splitter/-/splitter-1.17.4.tgz", + "integrity": "sha512-6uThEf+gD0z6Nf6CYvp28I2zjfGW0JOdFAJDpwyqyngvGbO4oPkWPozn8uUmbovQrzhiyUx1C6o5UPDsLgFWhw==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/steps": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/steps/-/steps-0.82.1.tgz", - "integrity": "sha512-N/LVOPbpQGtqpnNsdgZsQytpvXVoJ9Uldo8G38Q7892wwhVx63L0qLaiOK+SkU7kUTueOh109HezZ67nq3sadw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/steps/-/steps-1.17.4.tgz", + "integrity": "sha512-MSPtDEkPpQTQ/LTsTRhSeG/P4TCl9b0/nKf/cMT/KlmrK7pTonjkDvux/AQHLxkqZ+tMZYl7qYd/ocdARe1mtA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/store": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-0.82.1.tgz", - "integrity": "sha512-uWlVivLZBCuAEXrXOITM1srwfBtAnT8kBYVPElrT5aSO9gkV1YC/g+YdFRol7KKOg12qO561CPKReVfilmtAKg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-1.17.4.tgz", + "integrity": "sha512-80i4/ggb2OrZ9+l1EJgYcp8uBy5oJwwae/kzy2/r93P+gotct5/qiyZYrybE8+YhU0u5zPiyjTxH0SILfP9Ofg==", "license": "MIT", "dependencies": { "proxy-compare": "3.0.1" } }, "node_modules/@zag-js/switch": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/switch/-/switch-0.82.1.tgz", - "integrity": "sha512-lIZsOs5nG9TkPs75+OK5THprEO0u3NAiLnEJ489KEFautVX/GMwAWvGHNFS7CcCpLZv+EpVKAPAdmGfEphrzhA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/switch/-/switch-1.17.4.tgz", + "integrity": "sha512-d5kBKe+q7V87V6K3BcsfJ1jU2qiJvPLjBumUDFkrzU0E5jweVOOwYrqDzLX8X4cBXk9A2R6U8rYdgGwWDctmWQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-visible": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/tabs": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tabs/-/tabs-0.82.1.tgz", - "integrity": "sha512-1uwNRvy8LyUTCAWjL1kD7BexOZ0sHrZ4OnUwDNuaWbqxUjtzoe+ftvcLXvmwFMmrns7o1SVnjqkgSVKuE4mcDA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tabs/-/tabs-1.17.4.tgz", + "integrity": "sha512-jvchw7erb8ryQTR92QQyP64nmJPJHCeOr6s09ghYqyNIVI5xgVy5hcfgrE4iMXODJ9CSAMsZHqY7QN5Xq10l3Q==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/element-rect": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/tags-input": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tags-input/-/tags-input-0.82.1.tgz", - "integrity": "sha512-1mY8nCNMQgMwWBV5zX0bUcIgstqKjvFOAuYhGLIxbQPbgX7lP8Kr3nuhABh0oC0KnWaKfOMlItir2k795G4KMQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tags-input/-/tags-input-1.17.4.tgz", + "integrity": "sha512-BYzvgIdqjv2LZSf5tfRECklCEt9u/uyc4gaGOiEseNIzcyQ9xrg9fq2Yk6Wt8mhWujdCbC/zJS2RB3LdcVePng==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/auto-resize": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/interact-outside": "0.82.1", - "@zag-js/live-region": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/auto-resize": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/interact-outside": "1.17.4", + "@zag-js/live-region": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/time-picker": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/time-picker/-/time-picker-0.82.1.tgz", - "integrity": "sha512-nWKx3yyHFBUBPOTDFhi3du4wWlQe8wY0EoeWLQN6bpJSF4qo/BosTZJkUHm//FgUdwdhQBFOAsrlrJ0vL4qvNA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/time-picker/-/time-picker-1.17.4.tgz", + "integrity": "sha512-HGMIWqmpo2/cybCLNaPuMfRZx/wjkNAJKm33oZJXqwpc6rxWvh8bpEtpEOp7WDwWifthc/6VBUI5Smc+aO6oVA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" }, "peerDependencies": { "@internationalized/date": ">=3.0.0" } }, "node_modules/@zag-js/timer": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/timer/-/timer-0.82.1.tgz", - "integrity": "sha512-uG4xCrYHgDZJgvW+71ROQX0xIkqMup37ZpNSLS2f5eD5DO1n/9NYLztA1YyeCJyv1aEDsZreeJLJvNDElgXA2A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/timer/-/timer-1.17.4.tgz", + "integrity": "sha512-jDUIz4jgZAFqAOra/9Ng3mraMMnh1fTHtUAzFgolzwY6V8l2eAMGX0DrXtoEVqxlh4IGE00xN6Kus9j3NfcUOA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/toast": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/toast/-/toast-0.82.1.tgz", - "integrity": "sha512-4dL99zHXQg8j7ReJAR9zLAp5lNKMS4Nm+THnJaKsA0TF5QkELGnsZz47oKhFY0aQn46paxMLVagLqQ0+2i6D1w==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/toast/-/toast-1.17.4.tgz", + "integrity": "sha512-lhu0mhHLpT2DaI9d6BjlE2vJEL9/jFmyPGJ9QG9kkQAxDNtEJLiCJEe12mKs5S9LoxDHJGWGYkF2O/7XwLkDnA==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" + } + }, + "node_modules/@zag-js/toggle": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/toggle/-/toggle-1.17.4.tgz", + "integrity": "sha512-cKggg0TaGErAZmYXWGMHH81Gti+AXLMqT29V7EM2qI2tWQzzsmbDbUVoEQ7iZf8Ng6d/JfsZsLq6biZZHg6KsA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/toggle-group": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/toggle-group/-/toggle-group-0.82.1.tgz", - "integrity": "sha512-8YaYKFz3ciiQhlTFScrvqH3Ke6UMDQLSgMEsCcERBYatd6TxkJwlFiBzpksIDsZpmloBrylyItJvqmzj9jt6Ig==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/toggle-group/-/toggle-group-1.17.4.tgz", + "integrity": "sha512-cegFuo8X66MX7b06n6rIJlf4hFDPejmZeq1eSu7co4hVKAfqazBFh6SGsnKdIXhOUo162tFchNuKMkhZU3sWBQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/tooltip": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tooltip/-/tooltip-0.82.1.tgz", - "integrity": "sha512-ewF/1h2INDJlzYnoIigcWFWim56ezhfl7YGKgqLBdxBoRvZHyhRIfR8bbddVZk4k144gXsMVMeXwS6VEt6D0eQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tooltip/-/tooltip-1.17.4.tgz", + "integrity": "sha512-lDRXZjd7anVb4h2ZvDCYYZ+puJZZwry5xi72jY6xhz3vVWX5qfkYjZ/MHuuDk/S+fEY+luWJXJ+cPh+v1zie0g==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-visible": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/store": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/tour": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tour/-/tour-0.82.1.tgz", - "integrity": "sha512-Oo4ZA3vG2sYEotfrWVXfIV1KW0Z+s91U+2YPtM2sOLnhetEVXxj/AwAruZfvS6WOcTI7D9UBrrQolY94fdZeOA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tour/-/tour-1.17.4.tgz", + "integrity": "sha512-RSnzJLTygsMPUXcMuYY0GWTskfwDsSeyM5Jbn5iMUUphnj/3nCtZttbsA22jnXCYE8bK+/+6PnfdcD0Elysf7Q==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-trap": "0.82.1", - "@zag-js/interact-outside": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-trap": "1.17.4", + "@zag-js/interact-outside": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/tree-view": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tree-view/-/tree-view-0.82.1.tgz", - "integrity": "sha512-xvYwaL49ffC8nnb+ENgNtkSZE1jMh8tm1E777AqBqnrhJZ28+FA9Sk8YDuWIWhNOV/r4n97jTXqj4SAGCrlAMQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tree-view/-/tree-view-1.17.4.tgz", + "integrity": "sha512-XRc2DxB/gVrkmS7+ZTJBC8p0G1J+mqtFb5zzRxyNitp+VW7yMsRtAUJ7m5gT5bD71zOkk4fPhwuB+ZZtpPAaMQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/collection": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "node_modules/@zag-js/types": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-0.82.1.tgz", - "integrity": "sha512-Nr/CU/z/SZWDL92P2u9VDZL9JUxY8L1P7dGI0CmDKHlEHk1+vzqg3UnVkUKkZ5eVMNLtloHbrux5X9Gmkl39WQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-1.17.4.tgz", + "integrity": "sha512-GHE1ykkMeHuIPHkkU1JNcIWMoFH322Yq65S4dhhsEgqMRX3BUHW8ids5e+7WOu9ZSH3PGJdpUXe8+jg3USpwaw==", "license": "MIT", "dependencies": { "csstype": "3.1.3" } }, "node_modules/@zag-js/utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-0.82.1.tgz", - "integrity": "sha512-JUGdEjstrzB0G2AJqzQiURIl6UZ1ONYgby/pqBKX57LO5LxasQXk9oNZh8+ZAvePNC/lKqqTtyyI02YQB4XwkA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-1.17.4.tgz", + "integrity": "sha512-FXici9HJG1ZBLCmbHO/ed4iurDriDjdx8XOfSD052bu22ViWl5jnO2K77OwagexbXGGAJNhswvDeQg5CSqYbvA==", "license": "MIT" }, "node_modules/acorn": { @@ -2713,6 +3424,18 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2838,6 +3561,12 @@ "node": ">=6" } }, + "node_modules/color2k": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz", + "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==", + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2920,6 +3649,16 @@ "node": ">= 8" } }, + "node_modules/css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "license": "MIT", + "peer": true, + "dependencies": { + "tiny-invariant": "^1.0.6" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -2964,6 +3703,12 @@ "dev": true, "license": "MIT" }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -3119,6 +3864,12 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, "node_modules/fdir": { "version": "6.4.4", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", @@ -3173,6 +3924,51 @@ "node": ">= 6" } }, + "node_modules/framer-motion": { + "version": "12.23.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.0.tgz", + "integrity": "sha512-xf6NxTGAyf7zR4r2KlnhFmsRfKIbjqeBupEDBAaEtVIBJX96sAon00kMlsKButSIRwPSHjbRrAPnYdJJ9kyhbA==", + "license": "MIT", + "peer": true, + "dependencies": { + "motion-dom": "^12.22.0", + "motion-utils": "^12.19.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/framesync": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz", + "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==", + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "2.4.0" + } + }, + "node_modules/framesync/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "license": "0BSD", + "peer": true + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -3246,6 +4042,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -3480,6 +4285,12 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "license": "MIT" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -3611,6 +4422,23 @@ "ufo": "^1.5.4" } }, + "node_modules/motion-dom": { + "version": "12.22.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.22.0.tgz", + "integrity": "sha512-ooH7+/BPw9gOsL9VtPhEJHE2m4ltnhMlcGMhEqA0YGNhKof7jdaszvsyThXI6LVIKshJUZ9/CP6HNqQhJfV7kw==", + "license": "MIT", + "peer": true, + "dependencies": { + "motion-utils": "^12.19.0" + } + }, + "node_modules/motion-utils": { + "version": "12.19.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.19.0.tgz", + "integrity": "sha512-BuFTHINYmV07pdWs6lj6aI63vr2N4dg0vR+td0rtrdpWOhBzIkEklZyLcvKBoEtwSqx8Jg06vUB5RS0xDiUybw==", + "license": "MIT", + "peer": true + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -3986,6 +4814,13 @@ "react": ">=16.13.1" } }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT", + "peer": true + }, "node_modules/react-hook-form": { "version": "7.49.3", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.49.3.tgz", @@ -4008,14 +4843,83 @@ "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", "license": "MIT", "peerDependencies": { - "react": "*" + "react": "*" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-remove-scroll": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, "node_modules/readdirp": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", @@ -4296,6 +5200,49 @@ "integrity": "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==", "license": "MIT" }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", @@ -4446,62 +5393,68 @@ } }, "@ark-ui/react": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@ark-ui/react/-/react-4.9.1.tgz", - "integrity": "sha512-grnfoSUrGxN0VMgtf4yvpMgin2T4ERINqYm3x/XKny+q2iIO76PD7yjNP7IW+CDmNxy3QPOidcvRiCyy6x0LGA==", - "requires": { - "@internationalized/date": "3.7.0", - "@zag-js/accordion": "0.82.1", - "@zag-js/anatomy": "0.82.1", - "@zag-js/auto-resize": "0.82.1", - "@zag-js/avatar": "0.82.1", - "@zag-js/carousel": "0.82.1", - "@zag-js/checkbox": "0.82.1", - "@zag-js/clipboard": "0.82.1", - "@zag-js/collapsible": "0.82.1", - "@zag-js/collection": "0.82.1", - "@zag-js/color-picker": "0.82.1", - "@zag-js/color-utils": "0.82.1", - "@zag-js/combobox": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/date-picker": "0.82.1", - "@zag-js/date-utils": "0.82.1", - "@zag-js/dialog": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/editable": "0.82.1", - "@zag-js/file-upload": "0.82.1", - "@zag-js/file-utils": "0.82.1", - "@zag-js/focus-trap": "0.82.1", - "@zag-js/highlight-word": "0.82.1", - "@zag-js/hover-card": "0.82.1", - "@zag-js/i18n-utils": "0.82.1", - "@zag-js/menu": "0.82.1", - "@zag-js/number-input": "0.82.1", - "@zag-js/pagination": "0.82.1", - "@zag-js/pin-input": "0.82.1", - "@zag-js/popover": "0.82.1", - "@zag-js/presence": "0.82.1", - "@zag-js/progress": "0.82.1", - "@zag-js/qr-code": "0.82.1", - "@zag-js/radio-group": "0.82.1", - "@zag-js/rating-group": "0.82.1", - "@zag-js/react": "0.82.1", - "@zag-js/select": "0.82.1", - "@zag-js/signature-pad": "0.82.1", - "@zag-js/slider": "0.82.1", - "@zag-js/splitter": "0.82.1", - "@zag-js/steps": "0.82.1", - "@zag-js/switch": "0.82.1", - "@zag-js/tabs": "0.82.1", - "@zag-js/tags-input": "0.82.1", - "@zag-js/time-picker": "0.82.1", - "@zag-js/timer": "0.82.1", - "@zag-js/toast": "0.82.1", - "@zag-js/toggle-group": "0.82.1", - "@zag-js/tooltip": "0.82.1", - "@zag-js/tour": "0.82.1", - "@zag-js/tree-view": "0.82.1", - "@zag-js/types": "0.82.1" + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@ark-ui/react/-/react-5.15.4.tgz", + "integrity": "sha512-+xBKqxmt0JHewOsYsHXtedcdPsPZirAwd9y80JpyYfp8bSpIhmombLTjh0Ue9ktKPr7LdoZhV7qcX1TNrX4grg==", + "requires": { + "@internationalized/date": "3.8.2", + "@zag-js/accordion": "1.17.4", + "@zag-js/anatomy": "1.17.4", + "@zag-js/angle-slider": "1.17.4", + "@zag-js/auto-resize": "1.17.4", + "@zag-js/avatar": "1.17.4", + "@zag-js/carousel": "1.17.4", + "@zag-js/checkbox": "1.17.4", + "@zag-js/clipboard": "1.17.4", + "@zag-js/collapsible": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/color-picker": "1.17.4", + "@zag-js/color-utils": "1.17.4", + "@zag-js/combobox": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/date-picker": "1.17.4", + "@zag-js/date-utils": "1.17.4", + "@zag-js/dialog": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/editable": "1.17.4", + "@zag-js/file-upload": "1.17.4", + "@zag-js/file-utils": "1.17.4", + "@zag-js/floating-panel": "1.17.4", + "@zag-js/focus-trap": "1.17.4", + "@zag-js/highlight-word": "1.17.4", + "@zag-js/hover-card": "1.17.4", + "@zag-js/i18n-utils": "1.17.4", + "@zag-js/listbox": "1.17.4", + "@zag-js/menu": "1.17.4", + "@zag-js/number-input": "1.17.4", + "@zag-js/pagination": "1.17.4", + "@zag-js/password-input": "1.17.4", + "@zag-js/pin-input": "1.17.4", + "@zag-js/popover": "1.17.4", + "@zag-js/presence": "1.17.4", + "@zag-js/progress": "1.17.4", + "@zag-js/qr-code": "1.17.4", + "@zag-js/radio-group": "1.17.4", + "@zag-js/rating-group": "1.17.4", + "@zag-js/react": "1.17.4", + "@zag-js/select": "1.17.4", + "@zag-js/signature-pad": "1.17.4", + "@zag-js/slider": "1.17.4", + "@zag-js/splitter": "1.17.4", + "@zag-js/steps": "1.17.4", + "@zag-js/switch": "1.17.4", + "@zag-js/tabs": "1.17.4", + "@zag-js/tags-input": "1.17.4", + "@zag-js/time-picker": "1.17.4", + "@zag-js/timer": "1.17.4", + "@zag-js/toast": "1.17.4", + "@zag-js/toggle": "1.17.4", + "@zag-js/toggle-group": "1.17.4", + "@zag-js/tooltip": "1.17.4", + "@zag-js/tour": "1.17.4", + "@zag-js/tree-view": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@babel/code-frame": { @@ -4733,18 +5686,214 @@ "dev": true, "optional": true }, + "@chakra-ui/alert": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/alert/-/alert-2.2.2.tgz", + "integrity": "sha512-jHg4LYMRNOJH830ViLuicjb3F+v6iriE/2G5T+Sd0Hna04nukNJ1MxUmBPE+vI22me2dIflfelu2v9wdB6Pojw==", + "requires": { + "@chakra-ui/icon": "3.2.0", + "@chakra-ui/react-context": "2.1.0", + "@chakra-ui/shared-utils": "2.0.5", + "@chakra-ui/spinner": "2.1.0" + } + }, + "@chakra-ui/anatomy": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.2.2.tgz", + "integrity": "sha512-MV6D4VLRIHr4PkW4zMyqfrNS1mPlCTiCXwvYGtDFQYr+xHFfonhAuf9WjsSc0nyp2m0OdkSLnzmVKkZFLo25Tg==" + }, + "@chakra-ui/close-button": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-2.1.1.tgz", + "integrity": "sha512-gnpENKOanKexswSVpVz7ojZEALl2x5qjLYNqSQGbxz+aP9sOXPfUS56ebyBrre7T7exuWGiFeRwnM0oVeGPaiw==", + "requires": { + "@chakra-ui/icon": "3.2.0" + } + }, + "@chakra-ui/color-mode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-2.2.0.tgz", + "integrity": "sha512-niTEA8PALtMWRI9wJ4LL0CSBDo8NBfLNp4GD6/0hstcm3IlbBHTVKxN6HwSaoNYfphDQLxCjT4yG+0BJA5tFpg==", + "peer": true, + "requires": { + "@chakra-ui/react-use-safe-layout-effect": "2.1.0" + } + }, + "@chakra-ui/icon": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.2.0.tgz", + "integrity": "sha512-xxjGLvlX2Ys4H0iHrI16t74rG9EBcpFvJ3Y3B7KMQTrnW34Kf7Da/UC8J67Gtx85mTHW020ml85SVPKORWNNKQ==", + "requires": { + "@chakra-ui/shared-utils": "2.0.5" + } + }, + "@chakra-ui/object-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/object-utils/-/object-utils-2.1.0.tgz", + "integrity": "sha512-tgIZOgLHaoti5PYGPTwK3t/cqtcycW0owaiOXoZOcpwwX/vlVb+H1jFsQyWiiwQVPt9RkoSLtxzXamx+aHH+bQ==", + "peer": true + }, + "@chakra-ui/portal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/portal/-/portal-2.1.0.tgz", + "integrity": "sha512-9q9KWf6SArEcIq1gGofNcFPSWEyl+MfJjEUg/un1SMlQjaROOh3zYr+6JAwvcORiX7tyHosnmWC3d3wI2aPSQg==", + "requires": { + "@chakra-ui/react-context": "2.1.0", + "@chakra-ui/react-use-safe-layout-effect": "2.1.0" + } + }, "@chakra-ui/react": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-3.8.0.tgz", - "integrity": "sha512-UOkDxxMYHqQ6z/ExMcLYnjIIj2Ulu6syAkrpSueYmzLlG93cljkMCze5y9GXh/M6fyQEbLBuDVesULTqMmHuiA==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-3.21.1.tgz", + "integrity": "sha512-tc8SAeOZbOeOSY+BROE6o1FyzoS8sAuC6TAwlfUCZWhv9CMsxBisC88D4WI/puwnZVfUbzzhdVEQmWkCbJK6ag==", "requires": { - "@ark-ui/react": "4.9.1", + "@ark-ui/react": "5.15.4", "@emotion/is-prop-valid": "1.3.1", "@emotion/serialize": "1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "1.2.0", "@emotion/utils": "1.4.2", - "@pandacss/is-valid-prop": "0.41.0", - "csstype": "3.1.3" + "@pandacss/is-valid-prop": "0.54.0", + "csstype": "3.1.3", + "fast-safe-stringify": "2.1.1" + } + }, + "@chakra-ui/react-context": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-context/-/react-context-2.1.0.tgz", + "integrity": "sha512-iahyStvzQ4AOwKwdPReLGfDesGG+vWJfEsn0X/NoGph/SkN+HXtv2sCfYFFR9k7bb+Kvc6YfpLlSuLvKMHi2+w==", + "requires": {} + }, + "@chakra-ui/react-use-callback-ref": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.1.0.tgz", + "integrity": "sha512-efnJrBtGDa4YaxDzDE90EnKD3Vkh5a1t3w7PhnRQmsphLy3g2UieasoKTlT2Hn118TwDjIv5ZjHJW6HbzXA9wQ==", + "requires": {} + }, + "@chakra-ui/react-use-safe-layout-effect": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.1.0.tgz", + "integrity": "sha512-Knbrrx/bcPwVS1TorFdzrK/zWA8yuU/eaXDkNj24IrKoRlQrSBFarcgAEzlCHtzuhufP3OULPkELTzz91b0tCw==", + "requires": {} + }, + "@chakra-ui/react-use-timeout": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-timeout/-/react-use-timeout-2.1.0.tgz", + "integrity": "sha512-cFN0sobKMM9hXUhyCofx3/Mjlzah6ADaEl/AXl5Y+GawB5rgedgAcu2ErAgarEkwvsKdP6c68CKjQ9dmTQlJxQ==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.1.0" + } + }, + "@chakra-ui/react-use-update-effect": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.1.0.tgz", + "integrity": "sha512-ND4Q23tETaR2Qd3zwCKYOOS1dfssojPLJMLvUtUbW5M9uW1ejYWgGUobeAiOVfSplownG8QYMmHTP86p/v0lbA==", + "requires": {} + }, + "@chakra-ui/react-utils": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-2.0.12.tgz", + "integrity": "sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw==", + "peer": true, + "requires": { + "@chakra-ui/utils": "2.0.15" + } + }, + "@chakra-ui/shared-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/shared-utils/-/shared-utils-2.0.5.tgz", + "integrity": "sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q==" + }, + "@chakra-ui/spinner": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/spinner/-/spinner-2.1.0.tgz", + "integrity": "sha512-hczbnoXt+MMv/d3gE+hjQhmkzLiKuoTo42YhUG7Bs9OSv2lg1fZHW1fGNRFP3wTi6OIbD044U1P9HK+AOgFH3g==", + "requires": { + "@chakra-ui/shared-utils": "2.0.5" + } + }, + "@chakra-ui/styled-system": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.9.2.tgz", + "integrity": "sha512-To/Z92oHpIE+4nk11uVMWqo2GGRS86coeMmjxtpnErmWRdLcp1WVCVRAvn+ZwpLiNR+reWFr2FFqJRsREuZdAg==", + "requires": { + "@chakra-ui/shared-utils": "2.0.5", + "csstype": "^3.1.2", + "lodash.mergewith": "4.6.2" + } + }, + "@chakra-ui/system": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-2.6.2.tgz", + "integrity": "sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ==", + "peer": true, + "requires": { + "@chakra-ui/color-mode": "2.2.0", + "@chakra-ui/object-utils": "2.1.0", + "@chakra-ui/react-utils": "2.0.12", + "@chakra-ui/styled-system": "2.9.2", + "@chakra-ui/theme-utils": "2.0.21", + "@chakra-ui/utils": "2.0.15", + "react-fast-compare": "3.2.2" + } + }, + "@chakra-ui/theme": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-3.3.1.tgz", + "integrity": "sha512-Hft/VaT8GYnItGCBbgWd75ICrIrIFrR7lVOhV/dQnqtfGqsVDlrztbSErvMkoPKt0UgAkd9/o44jmZ6X4U2nZQ==", + "requires": { + "@chakra-ui/anatomy": "2.2.2", + "@chakra-ui/shared-utils": "2.0.5", + "@chakra-ui/theme-tools": "2.1.2" + } + }, + "@chakra-ui/theme-tools": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.1.2.tgz", + "integrity": "sha512-Qdj8ajF9kxY4gLrq7gA+Azp8CtFHGO9tWMN2wfF9aQNgG9AuMhPrUzMq9AMQ0MXiYcgNq/FD3eegB43nHVmXVA==", + "requires": { + "@chakra-ui/anatomy": "2.2.2", + "@chakra-ui/shared-utils": "2.0.5", + "color2k": "^2.0.2" + } + }, + "@chakra-ui/theme-utils": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-utils/-/theme-utils-2.0.21.tgz", + "integrity": "sha512-FjH5LJbT794r0+VSCXB3lT4aubI24bLLRWB+CuRKHijRvsOg717bRdUN/N1fEmEpFnRVrbewttWh/OQs0EWpWw==", + "peer": true, + "requires": { + "@chakra-ui/shared-utils": "2.0.5", + "@chakra-ui/styled-system": "2.9.2", + "@chakra-ui/theme": "3.3.1", + "lodash.mergewith": "4.6.2" + } + }, + "@chakra-ui/toast": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/toast/-/toast-7.0.2.tgz", + "integrity": "sha512-yvRP8jFKRs/YnkuE41BVTq9nB2v/KDRmje9u6dgDmE5+1bFt3bwjdf9gVbif4u5Ve7F7BGk5E093ARRVtvLvXA==", + "requires": { + "@chakra-ui/alert": "2.2.2", + "@chakra-ui/close-button": "2.1.1", + "@chakra-ui/portal": "2.1.0", + "@chakra-ui/react-context": "2.1.0", + "@chakra-ui/react-use-timeout": "2.1.0", + "@chakra-ui/react-use-update-effect": "2.1.0", + "@chakra-ui/shared-utils": "2.0.5", + "@chakra-ui/styled-system": "2.9.2", + "@chakra-ui/theme": "3.3.1" + } + }, + "@chakra-ui/utils": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.0.15.tgz", + "integrity": "sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA==", + "peer": true, + "requires": { + "@types/lodash.mergewith": "4.6.7", + "css-box-model": "1.2.1", + "framesync": "6.1.2", + "lodash.mergewith": "4.6.2" } }, "@emotion/babel-plugin": { @@ -4834,6 +5983,20 @@ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" }, + "@emotion/styled": { + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "peer": true, + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + } + }, "@emotion/unitless": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", @@ -5031,26 +6194,26 @@ "optional": true }, "@floating-ui/core": { - "version": "1.6.9", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", - "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", + "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", "requires": { - "@floating-ui/utils": "^0.2.9" + "@floating-ui/utils": "^0.2.10" } }, "@floating-ui/dom": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", - "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.1.tgz", + "integrity": "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==", "requires": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.8" + "@floating-ui/core": "^1.7.1", + "@floating-ui/utils": "^0.2.9" } }, "@floating-ui/utils": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", - "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==" }, "@hey-api/openapi-ts": { "version": "0.57.0", @@ -5065,17 +6228,17 @@ } }, "@internationalized/date": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.7.0.tgz", - "integrity": "sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.8.2.tgz", + "integrity": "sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA==", "requires": { "@swc/helpers": "^0.5.0" } }, "@internationalized/number": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.0.tgz", - "integrity": "sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.3.tgz", + "integrity": "sha512-p+Zh1sb6EfrfVaS86jlHGQ9HA66fJhV9x5LiE5vCbZtXEHAuhcmUZUdZ4WrFpUBfNalr2OkAJI5AcKEQF+Lebw==", "requires": { "@swc/helpers": "^0.5.0" } @@ -5087,9 +6250,9 @@ "dev": true }, "@pandacss/is-valid-prop": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@pandacss/is-valid-prop/-/is-valid-prop-0.41.0.tgz", - "integrity": "sha512-BE6h6CsJk14ugIRrsazJtN3fcg+KDFRat1Bs93YFKH6jd4DOb1yUyVvC70jKqPVvg70zEcV8acZ7VdcU5TLu+w==" + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@pandacss/is-valid-prop/-/is-valid-prop-0.54.0.tgz", + "integrity": "sha512-UhRgg1k9VKRCBAHl+XUK3lvN0k9bYifzYGZOqajDid4L1DyU813A1L0ZwN4iV9WX5TX3PfUugqtgG9LnIeFGBQ==" }, "@playwright/test": { "version": "1.52.0", @@ -5100,6 +6263,151 @@ "playwright": "1.52.0" } }, + "@radix-ui/primitive": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", + "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==" + }, + "@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "requires": {} + }, + "@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "requires": {} + }, + "@radix-ui/react-dialog": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", + "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", + "requires": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + } + }, + "@radix-ui/react-dismissable-layer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "requires": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + } + }, + "@radix-ui/react-focus-guards": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", + "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "requires": {} + }, + "@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "requires": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + } + }, + "@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "requires": { + "@radix-ui/react-use-layout-effect": "1.1.1" + } + }, + "@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "requires": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + } + }, + "@radix-ui/react-presence": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "requires": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + } + }, + "@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "requires": { + "@radix-ui/react-slot": "1.2.3" + } + }, + "@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "requires": { + "@radix-ui/react-compose-refs": "1.1.2" + } + }, + "@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "requires": {} + }, + "@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "requires": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + } + }, + "@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "requires": { + "@radix-ui/react-use-layout-effect": "1.1.1" + } + }, + "@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "requires": { + "@radix-ui/react-use-callback-ref": "1.1.1" + } + }, + "@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "requires": {} + }, "@rollup/rollup-android-arm-eabi": { "version": "4.40.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz", @@ -5452,6 +6760,21 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "@types/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", + "peer": true + }, + "@types/lodash.mergewith": { + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz", + "integrity": "sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A==", + "peer": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/node": { "version": "22.15.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz", @@ -5470,13 +6793,13 @@ "version": "15.7.11", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", - "dev": true + "devOptional": true }, "@types/react": { "version": "18.2.39", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", - "dev": true, + "devOptional": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -5487,7 +6810,7 @@ "version": "18.2.17", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", - "dev": true, + "devOptional": true, "requires": { "@types/react": "*" } @@ -5496,7 +6819,7 @@ "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "dev": true + "devOptional": true }, "@vitejs/plugin-react-swc": { "version": "3.9.0", @@ -5508,703 +6831,759 @@ } }, "@zag-js/accordion": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-0.82.1.tgz", - "integrity": "sha512-DWaElpm6RhntW8zVPMfd+s461FuXi6rv4pDPpXb4xCAJ0KTkBzS6PFxoBLL+11Mjv9XioaBoJatIGOCF8GAtTA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-1.17.4.tgz", + "integrity": "sha512-WkzoksfxJjuSdq+hIHCINc6hQtoYo5Nf0SfuInBiehRnoJtVjmpqk8VLxhLWhwFD/KMqz0wtWcM0itUGNpOyiw==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/anatomy": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-0.82.1.tgz", - "integrity": "sha512-wpgU7LyU9St3o/ft8Nkundi7MkW37vN1hYc2E7VA/R6mun0qiANsEf83ymIlAYnovLC6WUlBso9xwqejr6wRCg==" + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-1.17.4.tgz", + "integrity": "sha512-EDc7dD5nnr5T3kujMc+EvWIAACZ45cyeKKiPDUCAsmrOAYxIpD+Efh5lvKum6XLIUyUNnkpEVTazVNOeaoZBtQ==" + }, + "@zag-js/angle-slider": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/angle-slider/-/angle-slider-1.17.4.tgz", + "integrity": "sha512-atke7qq2dd2f4Om4T6k9GYi5bvUdBWDuwDIaBC39Kygyrj8IjShlcyv+QETbX0MaghIhbLBJQuvc+7G3eIMF1A==", + "requires": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/rect-utils": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" + } }, "@zag-js/aria-hidden": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/aria-hidden/-/aria-hidden-0.82.1.tgz", - "integrity": "sha512-KSz9oMY9rn1N3k3tFTKHlU66eQf8XZ/gy/ex27J0ykZoaYJplWQerSZvVakbILeh+rtpvdiTNaSgrCAwYwvAPA==" + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/aria-hidden/-/aria-hidden-1.17.4.tgz", + "integrity": "sha512-P7aSTINxBwGbDUxhemto10JsajbE+kIzKrPMOWAbIipfFSwPtaN4XJRg2aQHZFBuHNm1n2x87n2TJBwjAlPiNQ==" }, "@zag-js/auto-resize": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/auto-resize/-/auto-resize-0.82.1.tgz", - "integrity": "sha512-adOB7Y4p4i6b8GJv4V6qhlK1YRj4Ejs5I+eWFd8Rx535uQIcxEEVtpEAD5SRYg5PNk1ikaT+GCoHnTadGj6PuA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/auto-resize/-/auto-resize-1.17.4.tgz", + "integrity": "sha512-kCC0cvuxG/yf28P52waRlz7FaliPrOyPXH+XM+GrznLkC8/TpMeR092G9+oHiYauNESTb+yyQzGgKqW6xFd/Rw==", "requires": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "@zag-js/avatar": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/avatar/-/avatar-0.82.1.tgz", - "integrity": "sha512-XjRvDRmBxwy5OtIzlQOpf7zNk4g0b/uA7qZve5Hz0R7yWOu+NFlbFv0GsvRfgyYMCT5J0xBu271EG9FJq3QKyw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/avatar/-/avatar-1.17.4.tgz", + "integrity": "sha512-+B4esXErOoiYNmHarg9aZWAhUhx6bzoIp31zCMkb6lNUKCDb8hBpFIWYpkgOrPmMaMka2zSYSvpfx6+4zA1Lcg==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/carousel": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/carousel/-/carousel-0.82.1.tgz", - "integrity": "sha512-MO9+9oedxdKynxgvLLzXs+VQSOhu+GvsCLV4fBt7nMBMGIRHtRSzXHRNRkO0aqbsO/nKQ8TFH7GYzI1NqT/y4A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/carousel/-/carousel-1.17.4.tgz", + "integrity": "sha512-/n6nK5N9d+j3C+Q5GFnkeX4pMzZY/spKKhAbEMk2MPIHcbX50Ozdn+2MIGz0opAWtVwMXPhbl+WFeoNr8jbiSw==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/scroll-snap": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/scroll-snap": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/checkbox": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/checkbox/-/checkbox-0.82.1.tgz", - "integrity": "sha512-yD/h8ao/JTljEo+zthpKzTy/f9fqOlJ7Nd6psPoSKZy2MRGD0TDUbOjravb3icVgjTLCiaPVWMWdonny08Me6A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/checkbox/-/checkbox-1.17.4.tgz", + "integrity": "sha512-nHrbGhHHUdtvkaJ4jAeCzAG5ioEm719a815oxji2rM1Ei+tCD0mrHCntIeuFejVCGnvR2wFnNJaWaZlES85Vqw==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-visible": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/clipboard": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/clipboard/-/clipboard-0.82.1.tgz", - "integrity": "sha512-r1r3vwozs+lyNgccR3OfmYAydP0cJbIHGsgDKGuempinqv6xIoptHOkFgWNd6Kxz/3MnxP+BMEy6fZzECXkhdQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/clipboard/-/clipboard-1.17.4.tgz", + "integrity": "sha512-WieXgxRCbBayngNSSMMj2zVcR0QO0cT5cZZuYLSn1eTbglo9J4sAX1QyEvHwbZWVt/rEokj3Gdp/Pme6rAQpwQ==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/collapsible": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/collapsible/-/collapsible-0.82.1.tgz", - "integrity": "sha512-TuggUoXRVBOwACksi63TsN2rOukzUpe6oVMUvp9MaQaDbg9gpw0JzLTrdAaHfE+bhgXAb3EjN6wcZjq8zBctZQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/collapsible/-/collapsible-1.17.4.tgz", + "integrity": "sha512-2bDQYGYoiHWECQPQNeC8ekCshXoXb1i3yY9U3siSyKxMZdBL4VdW5+0UOQoleperbN9NONeEcHW0H10cPofEIA==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/collection": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/collection/-/collection-0.82.1.tgz", - "integrity": "sha512-uteM+xWZlWhRQe5biA5QWyva9PdzXONs+bpycUtZt8MakQgPmhW2whY9r1aW5NFVb/ScTwGAIGB3Eyc6Npz7Wg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/collection/-/collection-1.17.4.tgz", + "integrity": "sha512-N4FUhh6avw146IAUKxMj57clXOoN1XjY45ETWJMfahlmmmnttaCKuiiUj57/XIgmt3Vpg2bYIthcyTxeI+K4QQ==", "requires": { - "@zag-js/utils": "0.82.1" + "@zag-js/utils": "1.17.4" } }, "@zag-js/color-picker": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/color-picker/-/color-picker-0.82.1.tgz", - "integrity": "sha512-/MShDVBFNnXResLzeyWyKApeHuB9rmUeJo3WD/Bl6rTwjmvVCKRYguIe1SQviOokMLjuAyh0YWXdKMQw0HvMqQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/color-picker/-/color-picker-1.17.4.tgz", + "integrity": "sha512-Zue+eoBeTyKNiHW8lSN+GMWHWsPdl0yZozuRmtuxpKYnI30SSr6GIs88GCY9Inosxz9RqKx7t7TMxsyJlLiJVA==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/color-utils": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/color-utils": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/color-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/color-utils/-/color-utils-0.82.1.tgz", - "integrity": "sha512-BMSYcBeypGX0wCLszU2jxWBRUmd5/wPDJ59Y3Zwl9yNld0gtMnuBLSUeokMcG0UVQ/BxkyrWu3VDkKTUYKprqQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/color-utils/-/color-utils-1.17.4.tgz", + "integrity": "sha512-gasEa7yNMRW3dyJPtSVgZkXB5yrDF21XEaT+x8QLzj7WDutXeCOVPpc1GzBD+DupCcb6mTMUbhYdaf52WQxmWA==", "requires": { - "@zag-js/utils": "0.82.1" + "@zag-js/utils": "1.17.4" } }, "@zag-js/combobox": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/combobox/-/combobox-0.82.1.tgz", - "integrity": "sha512-Me3a0Sw4dTtmBRmbLGO/C1LJ4btZwbd5RLYnf8RPhEnqGJ5Z05i+ffWEe+SNBvpQO14njqBcF6P8VypVD/Ro1A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/combobox/-/combobox-1.17.4.tgz", + "integrity": "sha512-E7mDsVEcIVbRUUIzsI8+OfXyTdPCih60/g7SRd5Mu8cLnzOxdC4tmeoIY+42otPr0e1bieVMjUXTEKR7wvQuAA==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/aria-hidden": "0.82.1", - "@zag-js/collection": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/aria-hidden": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/core": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-0.82.1.tgz", - "integrity": "sha512-Ux0fkt1PumcqLwExcEozCMEfKBxtd2JlnitXo4hR3lJW5q9G52FkgWDyPSrhblyTkX+7RgxViZTMnHxaXs99jg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-1.17.4.tgz", + "integrity": "sha512-DIL2MXMLBYKR3pnjGGodiEUkY+ST/J81gtIJ32bLYxWWiMeX0SoPIvDZ9tqDHub9Kkd5CF07onXHkdAmB9Djrg==", "requires": { - "@zag-js/store": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/dom-query": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/date-picker": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/date-picker/-/date-picker-0.82.1.tgz", - "integrity": "sha512-f+4CV29+hcQ3Yw9hh0yyVRANONIUEWIrPS1fpnrrUNtIC0Y7f1Ajx+x089X9VxgQhwreK1sEwpnrL2vIqy+9+A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/date-picker/-/date-picker-1.17.4.tgz", + "integrity": "sha512-yNYLFlNnmBI+9gzHmrGrDsGSeHa8cj6+pWhNutIVAT9pyEmg/6AciFndL5+P9bolKo59qtXLpX8libxZ4wLr2g==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/date-utils": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/live-region": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/date-utils": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/live-region": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/date-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/date-utils/-/date-utils-0.82.1.tgz", - "integrity": "sha512-z9sHtgV4fvtXsqLaTD4/o+D+H5wumLYhIw/Bj3yC41gR5oa4Wo9QifRT9DBfvuokmXsrnRZ8k32hUtWoYb6M/A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/date-utils/-/date-utils-1.17.4.tgz", + "integrity": "sha512-kPw7GLnj560NdUpXJ1SeoJkNSIddZBa+Sd2fPlyDwqxB5lptqNeRK9FcascRL12PgI7EeM7/R9MVTkTPGdQNjg==", "requires": {} }, "@zag-js/dialog": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/dialog/-/dialog-0.82.1.tgz", - "integrity": "sha512-oqi+6Y/rx6ZKxg3s9r6bIuo33x+5+UDhvrlk31kE3LWgU1KJjVV0VEkFMK9B1SJTY7IizhlWMyDx+JXJ+jOy5Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/dialog/-/dialog-1.17.4.tgz", + "integrity": "sha512-UCTcGlAlbTSS2Po5XvOOl7FiLba5+kh0Vltz8NAZUNn4e87LeitQVTW68k/pxa2nnnaKfPN6CsAWYQ21aZOcwA==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/aria-hidden": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-trap": "0.82.1", - "@zag-js/remove-scroll": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/aria-hidden": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-trap": "1.17.4", + "@zag-js/remove-scroll": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/dismissable": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/dismissable/-/dismissable-0.82.1.tgz", - "integrity": "sha512-vs+zkORzaeNzX4Wsy4OkW1AVce7l4Tc6DHZq8gqNB5SvhK+5wEPl6EmacQRvZyoCxi2m6xpaI98UkLCmVJKU+Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/dismissable/-/dismissable-1.17.4.tgz", + "integrity": "sha512-LkFdUz2Ay3D/CsSjQSVjxQwzH6U5rU6cvEcUTOM90RUSozuV2pAK5NnI3JH3jAy1USlpTbjxHL+2bdep2jkAEg==", "requires": { - "@zag-js/dom-query": "0.82.1", - "@zag-js/interact-outside": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/dom-query": "1.17.4", + "@zag-js/interact-outside": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/dom-query": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-0.82.1.tgz", - "integrity": "sha512-KFtbqDUykQur587hyrGi8LL8GfTS2mqBpIT0kL3E+S63Mq7U84i+hGf3VyNuInMB5ONpkNEk5JN4G9/HWQ6pAQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-1.17.4.tgz", + "integrity": "sha512-1fNDCWkHRZXB4dD2hoiyMy0cSkrB/u4fur3To5sOKteka5e9om1/YdbYxXNLmVfeTiC/SJtWNelXP7c/8uDwOw==", "requires": { - "@zag-js/types": "0.82.1" + "@zag-js/types": "1.17.4" } }, "@zag-js/editable": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/editable/-/editable-0.82.1.tgz", - "integrity": "sha512-V5i3kYSHFJYj8914nBf4VKKtm6m59gG482vm20As4EnLcwGFrOBbm4HXUgsKq0wYSLy/lTtvMrUT8Iqudye2gw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/editable/-/editable-1.17.4.tgz", + "integrity": "sha512-qTfvrhbHtfvFZv3l+qAlweOpWyzDwYRQ1xrI+Sc8pCHhml6QiZ1UFUpYbiQWPn7dqdzBEVUIhjzDX4lzjsWGSA==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/interact-outside": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/interact-outside": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, - "@zag-js/element-rect": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/element-rect/-/element-rect-0.82.1.tgz", - "integrity": "sha512-xXUjmeIUdxkxic5bepp6fVqN9Qs+54PXCAUl6g/DtJecQVmVooIfa3SLSULhany4aR4mlGojp5TJxvSpUBA58Q==" - }, - "@zag-js/element-size": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.82.1.tgz", - "integrity": "sha512-k1rOE6NhoULI9d5pt2qVUxWCQVEf3OTPH8UDnbsdf11xn+hMCzRYd9lekUdVGrcHHGvEK+W6iAfWZnlwsJsmow==" - }, "@zag-js/file-upload": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/file-upload/-/file-upload-0.82.1.tgz", - "integrity": "sha512-6cgJsy9bf2DB0v+CVq1L4g4aCePTpfWsV4C0HC+82K+OSPomiIPsQS87wo4+eAcy3z+80Qh+uglZCFAwkW8W+g==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/file-upload/-/file-upload-1.17.4.tgz", + "integrity": "sha512-onV7jN2l9oXcKAuO/KY0TNcqyaFroQ8JjY+QxOOrZEmhvo48h/Lbi0FwBfk3syNWCRK3ihpRQbKOa1lthupGjg==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/file-utils": "0.82.1", - "@zag-js/i18n-utils": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/file-utils": "1.17.4", + "@zag-js/i18n-utils": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/file-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/file-utils/-/file-utils-0.82.1.tgz", - "integrity": "sha512-/u86hMd+E5UCrrY9akDAExkO7sgPA1lXzWC9gSX4LSxHATk7Vo4o5+4LiE1MX4WZRytOhtxAycJzNDVpqzmppQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/file-utils/-/file-utils-1.17.4.tgz", + "integrity": "sha512-eg+ywy2qJn+rXz7wBsJc0N0H6qmKEMvxaWtsynBZ+XDbyrEec/aHNRDaM+l5xdFjDKb5/R151nEDXgnBAT8miA==", + "requires": { + "@zag-js/i18n-utils": "1.17.4" + } + }, + "@zag-js/floating-panel": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/floating-panel/-/floating-panel-1.17.4.tgz", + "integrity": "sha512-YgGP0PybQ0adlW6aOkFaho1tOzSk0rIVhCzsCQmln9mhSYgSCgwMoJIqfsFTLVpKB7TO155okOh5kwelH75Jfw==", "requires": { - "@zag-js/i18n-utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/rect-utils": "1.17.4", + "@zag-js/store": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/focus-trap": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/focus-trap/-/focus-trap-0.82.1.tgz", - "integrity": "sha512-z5OzmR8O3n2043Lwhp1qcizNHXvzc/Xteb3hWmxbX9hR3k0wHJeMXMj3GTDO0FBixRt+d8iHEmt3/8CkI72mqw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/focus-trap/-/focus-trap-1.17.4.tgz", + "integrity": "sha512-6exU3DOkyqE2LSRydhgQIho/XhNOvQ35AEbYN81I6yniJPARbkGmDcQaKHZXSL7+tAe0ynX09yfVo4Cskio8Ow==", "requires": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "@zag-js/focus-visible": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.82.1.tgz", - "integrity": "sha512-b87FqZO6e9RmTY4msEzwZ3hZ8pRuPd2vbR2b6SlXr6ohtmGKlGgBGO4kmarZN/ClE+7VOnOEqIicatRBEgX9bw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-1.17.4.tgz", + "integrity": "sha512-9P1GtsFqbuLcplwK/Y7MdnQz9NipYUjef8PS2/duQzRf3UM99/zu1ZbRqwNIW/Tf5ztvet3+dMBAN5HEyYW0Rw==", "requires": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "@zag-js/highlight-word": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/highlight-word/-/highlight-word-0.82.1.tgz", - "integrity": "sha512-lS5r3V0l7Z53QyNwkxulYp5QYA9mFkU+3XsZqfM6cBjh+wmGE1xeIwknAmFtYvuYNK37AwT7pp5z0Rm1Ep6WVQ==" + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/highlight-word/-/highlight-word-1.17.4.tgz", + "integrity": "sha512-uBK/5OsopYE5qBjkIoQuqvgd6CTnKpttt4+ODFjPV0NPImgcDuqBT1KlFZZZEPZ58fu1TtNU6hNVKHmZ4EzUnw==" }, "@zag-js/hover-card": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/hover-card/-/hover-card-0.82.1.tgz", - "integrity": "sha512-fp9t/PNXODwxXR1X+VzgYeSpgoJ+M3W/qvuA2stgPI4kEinwKEssSlP2sH6gTmQVZKL8SV1jiNQinVh00NE85g==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/hover-card/-/hover-card-1.17.4.tgz", + "integrity": "sha512-yOVqj2KUxcMZx6B0LpkMRa1q736eVUXTzQD6Keh4cKxtnCFE+ydYVv70xHL4CLWFqz6+PFRYApgzd05IIbff7w==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/i18n-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/i18n-utils/-/i18n-utils-0.82.1.tgz", - "integrity": "sha512-YcTIqka6+/YoH2VRBMnv3CvTjHdUo/NG2nMenAB9Wq0MLTn+TAtcsujenz7ckJcgayVhFAchWNhwK9+/cs1dAw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/i18n-utils/-/i18n-utils-1.17.4.tgz", + "integrity": "sha512-HiRKMQGaZUpjqekq1h1UlMqquIBnQYSiGpW9vWCUbKs5hr7z3VIgJtKoxdCsBkno7vBEejl316DIIDh3N2qbeA==", "requires": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "@zag-js/interact-outside": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/interact-outside/-/interact-outside-0.82.1.tgz", - "integrity": "sha512-WcWJB5kM41fDM6YMGC3ZEPVn1q3Nrm+cAFkllRJrRY4+bUKXmtN8bqDaRKghP+dG5CXz66SiM6xBvDE4nqtK5Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/interact-outside/-/interact-outside-1.17.4.tgz", + "integrity": "sha512-jd7/4V7ESS6FJILPWIm5CmXVR+maZ4fQmQUPV56WOURKdl2LZ2bPgfjvEaVI9BTm7qPTML6O55xgB87rS/sXlw==", + "requires": { + "@zag-js/dom-query": "1.17.4", + "@zag-js/utils": "1.17.4" + } + }, + "@zag-js/listbox": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/listbox/-/listbox-1.17.4.tgz", + "integrity": "sha512-14OReAbUZNEYjy2eBPqI7FUxts0kTjQS268aukfzLvHcJHAHTcP9ru7XMftZlPbQBofPGr/lSLhIa4NZJF3vrw==", "requires": { - "@zag-js/dom-query": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/live-region": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/live-region/-/live-region-0.82.1.tgz", - "integrity": "sha512-BmSXc41y1uOra/UV1lt8BurWkuwne/+c371IJCK6l+MWsO0ufq1lrjfx4cyFf5yhVcPRkhv/b/0i+7RxfDSK1A==" + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/live-region/-/live-region-1.17.4.tgz", + "integrity": "sha512-fP2f6C6vEcWydvhYKMYWaVu8tqyiCnKJx8auJ2zL/yZGLz/W3xDdRRqHJCfneilN7m8C6tJhWBBZm5Th22bGmQ==" }, "@zag-js/menu": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/menu/-/menu-0.82.1.tgz", - "integrity": "sha512-faAlQZYeWHcGH8nIxBYh7HHfVjSKsHV8yUsbhMD0XkePWM6eB+dPRd/Fc3DeT8ieM8+sUODnTHEuxar0i48v4w==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/menu/-/menu-1.17.4.tgz", + "integrity": "sha512-KzpvU/rPiPFDexcD+RmcLhPOII5SPgGSSdidpz3pTBy8yEwnwOSoN0PGHm8WnOD4US2wZOHvOqR+Rov8IbmKWw==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/rect-utils": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/rect-utils": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/number-input": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/number-input/-/number-input-0.82.1.tgz", - "integrity": "sha512-QIQlxlxM78+TkEhPEGlTbkBR3G2ngm5vhc3BFw4sG6ABMyre8TiIH37EqQB7EGKyAcuz6QwPk3AervHMFKe4YQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/number-input/-/number-input-1.17.4.tgz", + "integrity": "sha512-lyrZwr3X1wicL8MThZvu4JH5pwldYO2gKQ+CVgMTx6H2epQNVJJ9i8v/+buUNB9/2ufjUV0MaxQ2fuGTXyjAKw==", "requires": { - "@internationalized/number": "3.6.0", - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@internationalized/number": "3.6.3", + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/pagination": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/pagination/-/pagination-0.82.1.tgz", - "integrity": "sha512-1Rsd3cSnlewefNB1RBI0ymK5wlgiBcK42H1IrJIhly6+SXDAhp0Oc45ofsCzpfhkQ4be+A9Cb30ayc6J4ZU2kA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/pagination/-/pagination-1.17.4.tgz", + "integrity": "sha512-yTOcwRdJ0CozEzw0Q+lAUkpWUERFVCCSx9qqIAGqF5jEZSWefUWMQVcPRqupLQ51mhCXdt+wDDh2mTY6Mr+L3A==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" + } + }, + "@zag-js/password-input": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/password-input/-/password-input-1.17.4.tgz", + "integrity": "sha512-h77V18+KBvZHUcARnr+Qw+P5vGvvSC9UMzjnE2SpMIpyvOIr1Fp+4TCGKVEIIsWR0LzWnK79UNExVj1Th3t1TQ==", + "requires": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/pin-input": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/pin-input/-/pin-input-0.82.1.tgz", - "integrity": "sha512-P7UN7rIt03YHt05SuK+kZ9mhl4AfvCvaSGB/9KzEq5r6p1D3lc4+0LVkkOvL2EEB8vbGY/y5BNcvaF2jPQPH5Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/pin-input/-/pin-input-1.17.4.tgz", + "integrity": "sha512-k2rhmS0oAPUE93DgdHtV7HkpBvTj3iGvUusVwmifE42ct1VnuuedXHKlicGbJ2ZXWelXmKd5675LHfwmF68h2A==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/popover": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/popover/-/popover-0.82.1.tgz", - "integrity": "sha512-zZ8H/jcjaXcLRX4dBcmandexeKV/5cBOt4AUVEnd3/X5NFFkA2Njz8rpQFcNRZl814NxG4RCchIu8kmonmUKCA==", - "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/aria-hidden": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-trap": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/remove-scroll": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/popover/-/popover-1.17.4.tgz", + "integrity": "sha512-uDRfw5/F3FPeanOJbXnVmk5c+RFFkQozZ6dn3qdnynWn1sLh56Kf5Ys4X+MQInxqUKdtDCb7cO2tfkAZXE5ZOA==", + "requires": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/aria-hidden": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-trap": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/remove-scroll": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/popper": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/popper/-/popper-0.82.1.tgz", - "integrity": "sha512-vQTmVUs6aLGqKmWb+FnLDntsulvd/sCvgndeTmwOHRW8PBwPb86aDnvNrNosBSS+Kk9p6CMJwWZ6CuPWR5Kf7Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/popper/-/popper-1.17.4.tgz", + "integrity": "sha512-ZdlDcaBzDx4XUzicTviaCP0Q6W1AXwRzdPVO2TzosqQyyn/tYqEfcJePYu9XVsr1Y6bkume4Pt0ucuRN+kUeYQ==", "requires": { - "@floating-ui/dom": "1.6.12", - "@zag-js/dom-query": "0.82.1", - "@zag-js/utils": "0.82.1" + "@floating-ui/dom": "1.7.1", + "@zag-js/dom-query": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/presence": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/presence/-/presence-0.82.1.tgz", - "integrity": "sha512-eZeAkq2s7NYCiNVMvkWL2Or458hZj71u7ygCt6skA18sO1ZksY+qIFqj99leCov+fesz06Hf8bxZz5029t/Wjg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/presence/-/presence-1.17.4.tgz", + "integrity": "sha512-xFEITSvZjoNYh3Ea+48tFqwwsOtSeEa27c3GOa1ToCTs0J+7SrP19bj5w7Hnbk5cGY/4P5OD8OiMKvkPughjEw==", "requires": { - "@zag-js/core": "0.82.1", - "@zag-js/types": "0.82.1" + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4" } }, "@zag-js/progress": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/progress/-/progress-0.82.1.tgz", - "integrity": "sha512-Fy1EjUda7o7e/yTKbZgKKayGOsHxkjLG+x0AakHmbR/k2VKbM4QuFHB9RJLlqNd9a+m/BzS1kEKWzCJ7/mXL9Q==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/progress/-/progress-1.17.4.tgz", + "integrity": "sha512-1FWUIizd8OMcK+0uUA/6ly3VJd5eHeOZkXC4lIWDGGwLhfEv2Lm+pgF5Ix5u1mtcmawBbhpkSlYjc1CbsjUTQQ==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/qr-code": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/qr-code/-/qr-code-0.82.1.tgz", - "integrity": "sha512-E1N1o1dPVuhWkcrg6urut2aaCqrc16OeE9VJh1mAGIUknF3p0QScH+ql7J/n9r8WOa21xyF6HLKhnWVPRQmHGg==", - "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/qr-code/-/qr-code-1.17.4.tgz", + "integrity": "sha512-z2FLUlGCLmKcNyXCdeWJkovLo4NvFdRAe43psn0M8rhd470rYCzol1/86s2G72DjqUT0ZwadkfgRjLfaLHkYdQ==", + "requires": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4", "proxy-memoize": "3.0.1", "uqr": "0.1.2" } }, "@zag-js/radio-group": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/radio-group/-/radio-group-0.82.1.tgz", - "integrity": "sha512-YTqP4Ok2YEmEXCEiNW2tufZ6svt4sh7KHqrHZq81vPAJMKKhVosP6LnZvmt4dVn6tKJ0OU8idwFVtPM5jSAWoA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/radio-group/-/radio-group-1.17.4.tgz", + "integrity": "sha512-/u9ugWth+FPu3W1VUTuBIVq3TbJZMLYF8cFPhvTgIjBvbQw9Oe+TW+WywyH1z7Oaz03e4IYhW445sWGoC9TNvw==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/element-rect": "0.82.1", - "@zag-js/focus-visible": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/rating-group": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/rating-group/-/rating-group-0.82.1.tgz", - "integrity": "sha512-ULl0OA207b6Ilsr2QWt4dbx58hA/NnyCmHpvv1pAYSlH3K0Es5b25B80Cc5jM/3NK3yqoY81OkS9U8lxmpWo+A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/rating-group/-/rating-group-1.17.4.tgz", + "integrity": "sha512-5KQdf+CLX3RzCu7Bj8Xn7AKeDU+sxCjxCcbjs8VviLl6Rj/OaFUoUomZFf/wLsJLY1tqk6PD7dX4NczY7YC2YQ==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/react": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/react/-/react-0.82.1.tgz", - "integrity": "sha512-CZivUTFQ4TdRKTN+9wpWAo0lEZlMnbjJPVn2VJVpcz+eRNUeoVzevkNY/OzAqdV3mp+VtdNabQn1fAz8ngViPQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/react/-/react-1.17.4.tgz", + "integrity": "sha512-43TEe1Afjh1RR3Byxib/jZ2Wn4UVdZY5Irx5v3tnp8NY8BFeswPhP28e6W2NT4c/UZoWeRxYlXDdrRS2p8L8Wg==", "requires": { - "@zag-js/core": "0.82.1", - "@zag-js/store": "0.82.1", - "@zag-js/types": "0.82.1", - "proxy-compare": "3.0.1" + "@zag-js/core": "1.17.4", + "@zag-js/store": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/rect-utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/rect-utils/-/rect-utils-0.82.1.tgz", - "integrity": "sha512-gXmvj1wK9FeToOCzvoZ5gycqUNRzfeqd84uwJeG9zA8SVdoyEnoAji8IAynneq8t3LbiNUcu37wjTw0dcWM6ig==" + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/rect-utils/-/rect-utils-1.17.4.tgz", + "integrity": "sha512-DiYNOwtVek9qwtbV906zjNpM8dmJL4sp131rPRgRStTg8MHpfW2PUOaxFklKh9/ykFwPDu6rx7kQ9Y2P4ez/xg==" }, "@zag-js/remove-scroll": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/remove-scroll/-/remove-scroll-0.82.1.tgz", - "integrity": "sha512-68cvXvqgNOlucbnGKRyephk8Qg8wb4xpjgUdmF9xQwICdY/uhW2p4ZGJ4471TDCDIlpoBrJPYsWqV2oWH3QNfA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/remove-scroll/-/remove-scroll-1.17.4.tgz", + "integrity": "sha512-EY+N1UodKfu2omYknbWfv+33pljfVW5ZX01iuSlTng3Vx5Zn6xlQCTxpVWvDidACEN6jjBn00QFbGWEhDDBpdw==", "requires": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "@zag-js/scroll-snap": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/scroll-snap/-/scroll-snap-0.82.1.tgz", - "integrity": "sha512-HL3MkBpWx4Cw0+h1UP/PnvLP3Z1T+F5mkeS8HWmiP+KPzhtFiEBRrve+xk7h7BMXifteg2UZy53ZiZfJeGsd3w==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/scroll-snap/-/scroll-snap-1.17.4.tgz", + "integrity": "sha512-bdYtDdJjXcupjoTs5n3Z310wEDrsykgWIKVOy5r4daNp+aH99YHBvINt0BUzjfyCpoEH0KvM9KwKlwOhq7XUNA==", "requires": { - "@zag-js/dom-query": "0.82.1" + "@zag-js/dom-query": "1.17.4" } }, "@zag-js/select": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/select/-/select-0.82.1.tgz", - "integrity": "sha512-cc6D8Iz+Ewnx9L0J63QGqC2bbiwzCEcJVE/j4OZDcy4Qk3lqr3qA09uuJbQxAi7yvIeB44DIEt9ryTZPkZbgiw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/select/-/select-1.17.4.tgz", + "integrity": "sha512-Yy/83xydKl/Qz3BoeNCwu964lLRDqoF4fsOWPeOFEN6HHftLD7NNNO7eIqe2Qe84ZBwAeQeZ8cNNI2oYHFc/ag==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/collection": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/signature-pad": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/signature-pad/-/signature-pad-0.82.1.tgz", - "integrity": "sha512-s8ae88OpAafkpuqimO9beUiVTn3FG+bnWeWnYQOLtNYMCNHzQbVZp9QBNbOoUpNcDT14mx9rfZe98BqfiMohFw==", - "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/signature-pad/-/signature-pad-1.17.4.tgz", + "integrity": "sha512-nGv9uBNkq+jrLfdN+wuINA+ch0jZs/m1UUDcyUvpRfQa/AlkNdv9oC8p6KUJwNhunTQN6E2RCZqO43q49ioEtg==", + "requires": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4", "perfect-freehand": "^1.2.2" } }, "@zag-js/slider": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/slider/-/slider-0.82.1.tgz", - "integrity": "sha512-qXVvXbDRq6Cla036M9OH6plO7ubefM7k65NJQKjtITDua+VliKQLXj9BrdPLT9K96wWntW+D/TiZXE+JNbR4ow==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/slider/-/slider-1.17.4.tgz", + "integrity": "sha512-Iq3pgLmJIvmQXaUm/+Xt1/s1IV1p73E7ySbThdZ8EADDn60m5ESVTwEymK9jnH10hpXuxDvI1GcbWPOTrIxwYQ==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/element-size": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/splitter": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/splitter/-/splitter-0.82.1.tgz", - "integrity": "sha512-eMNncj+pcepYTf+51s4ysDS/tjtKXswpwsSQR0AeNqCE3SW3TGzHOM0+uheyjgv9EmDGDrr3Imdo0PCkq3bqug==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/splitter/-/splitter-1.17.4.tgz", + "integrity": "sha512-6uThEf+gD0z6Nf6CYvp28I2zjfGW0JOdFAJDpwyqyngvGbO4oPkWPozn8uUmbovQrzhiyUx1C6o5UPDsLgFWhw==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/steps": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/steps/-/steps-0.82.1.tgz", - "integrity": "sha512-N/LVOPbpQGtqpnNsdgZsQytpvXVoJ9Uldo8G38Q7892wwhVx63L0qLaiOK+SkU7kUTueOh109HezZ67nq3sadw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/steps/-/steps-1.17.4.tgz", + "integrity": "sha512-MSPtDEkPpQTQ/LTsTRhSeG/P4TCl9b0/nKf/cMT/KlmrK7pTonjkDvux/AQHLxkqZ+tMZYl7qYd/ocdARe1mtA==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/store": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-0.82.1.tgz", - "integrity": "sha512-uWlVivLZBCuAEXrXOITM1srwfBtAnT8kBYVPElrT5aSO9gkV1YC/g+YdFRol7KKOg12qO561CPKReVfilmtAKg==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-1.17.4.tgz", + "integrity": "sha512-80i4/ggb2OrZ9+l1EJgYcp8uBy5oJwwae/kzy2/r93P+gotct5/qiyZYrybE8+YhU0u5zPiyjTxH0SILfP9Ofg==", "requires": { "proxy-compare": "3.0.1" } }, "@zag-js/switch": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/switch/-/switch-0.82.1.tgz", - "integrity": "sha512-lIZsOs5nG9TkPs75+OK5THprEO0u3NAiLnEJ489KEFautVX/GMwAWvGHNFS7CcCpLZv+EpVKAPAdmGfEphrzhA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/switch/-/switch-1.17.4.tgz", + "integrity": "sha512-d5kBKe+q7V87V6K3BcsfJ1jU2qiJvPLjBumUDFkrzU0E5jweVOOwYrqDzLX8X4cBXk9A2R6U8rYdgGwWDctmWQ==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-visible": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/tabs": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tabs/-/tabs-0.82.1.tgz", - "integrity": "sha512-1uwNRvy8LyUTCAWjL1kD7BexOZ0sHrZ4OnUwDNuaWbqxUjtzoe+ftvcLXvmwFMmrns7o1SVnjqkgSVKuE4mcDA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tabs/-/tabs-1.17.4.tgz", + "integrity": "sha512-jvchw7erb8ryQTR92QQyP64nmJPJHCeOr6s09ghYqyNIVI5xgVy5hcfgrE4iMXODJ9CSAMsZHqY7QN5Xq10l3Q==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/element-rect": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/tags-input": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tags-input/-/tags-input-0.82.1.tgz", - "integrity": "sha512-1mY8nCNMQgMwWBV5zX0bUcIgstqKjvFOAuYhGLIxbQPbgX7lP8Kr3nuhABh0oC0KnWaKfOMlItir2k795G4KMQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tags-input/-/tags-input-1.17.4.tgz", + "integrity": "sha512-BYzvgIdqjv2LZSf5tfRECklCEt9u/uyc4gaGOiEseNIzcyQ9xrg9fq2Yk6Wt8mhWujdCbC/zJS2RB3LdcVePng==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/auto-resize": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/interact-outside": "0.82.1", - "@zag-js/live-region": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/auto-resize": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/interact-outside": "1.17.4", + "@zag-js/live-region": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/time-picker": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/time-picker/-/time-picker-0.82.1.tgz", - "integrity": "sha512-nWKx3yyHFBUBPOTDFhi3du4wWlQe8wY0EoeWLQN6bpJSF4qo/BosTZJkUHm//FgUdwdhQBFOAsrlrJ0vL4qvNA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/time-picker/-/time-picker-1.17.4.tgz", + "integrity": "sha512-HGMIWqmpo2/cybCLNaPuMfRZx/wjkNAJKm33oZJXqwpc6rxWvh8bpEtpEOp7WDwWifthc/6VBUI5Smc+aO6oVA==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/timer": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/timer/-/timer-0.82.1.tgz", - "integrity": "sha512-uG4xCrYHgDZJgvW+71ROQX0xIkqMup37ZpNSLS2f5eD5DO1n/9NYLztA1YyeCJyv1aEDsZreeJLJvNDElgXA2A==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/timer/-/timer-1.17.4.tgz", + "integrity": "sha512-jDUIz4jgZAFqAOra/9Ng3mraMMnh1fTHtUAzFgolzwY6V8l2eAMGX0DrXtoEVqxlh4IGE00xN6Kus9j3NfcUOA==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/toast": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/toast/-/toast-0.82.1.tgz", - "integrity": "sha512-4dL99zHXQg8j7ReJAR9zLAp5lNKMS4Nm+THnJaKsA0TF5QkELGnsZz47oKhFY0aQn46paxMLVagLqQ0+2i6D1w==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/toast/-/toast-1.17.4.tgz", + "integrity": "sha512-lhu0mhHLpT2DaI9d6BjlE2vJEL9/jFmyPGJ9QG9kkQAxDNtEJLiCJEe12mKs5S9LoxDHJGWGYkF2O/7XwLkDnA==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" + } + }, + "@zag-js/toggle": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/toggle/-/toggle-1.17.4.tgz", + "integrity": "sha512-cKggg0TaGErAZmYXWGMHH81Gti+AXLMqT29V7EM2qI2tWQzzsmbDbUVoEQ7iZf8Ng6d/JfsZsLq6biZZHg6KsA==", + "requires": { + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/toggle-group": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/toggle-group/-/toggle-group-0.82.1.tgz", - "integrity": "sha512-8YaYKFz3ciiQhlTFScrvqH3Ke6UMDQLSgMEsCcERBYatd6TxkJwlFiBzpksIDsZpmloBrylyItJvqmzj9jt6Ig==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/toggle-group/-/toggle-group-1.17.4.tgz", + "integrity": "sha512-cegFuo8X66MX7b06n6rIJlf4hFDPejmZeq1eSu7co4hVKAfqazBFh6SGsnKdIXhOUo162tFchNuKMkhZU3sWBQ==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/tooltip": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tooltip/-/tooltip-0.82.1.tgz", - "integrity": "sha512-ewF/1h2INDJlzYnoIigcWFWim56ezhfl7YGKgqLBdxBoRvZHyhRIfR8bbddVZk4k144gXsMVMeXwS6VEt6D0eQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tooltip/-/tooltip-1.17.4.tgz", + "integrity": "sha512-lDRXZjd7anVb4h2ZvDCYYZ+puJZZwry5xi72jY6xhz3vVWX5qfkYjZ/MHuuDk/S+fEY+luWJXJ+cPh+v1zie0g==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-visible": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-visible": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/store": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/tour": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tour/-/tour-0.82.1.tgz", - "integrity": "sha512-Oo4ZA3vG2sYEotfrWVXfIV1KW0Z+s91U+2YPtM2sOLnhetEVXxj/AwAruZfvS6WOcTI7D9UBrrQolY94fdZeOA==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tour/-/tour-1.17.4.tgz", + "integrity": "sha512-RSnzJLTygsMPUXcMuYY0GWTskfwDsSeyM5Jbn5iMUUphnj/3nCtZttbsA22jnXCYE8bK+/+6PnfdcD0Elysf7Q==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dismissable": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/focus-trap": "0.82.1", - "@zag-js/interact-outside": "0.82.1", - "@zag-js/popper": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dismissable": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/focus-trap": "1.17.4", + "@zag-js/interact-outside": "1.17.4", + "@zag-js/popper": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/tree-view": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/tree-view/-/tree-view-0.82.1.tgz", - "integrity": "sha512-xvYwaL49ffC8nnb+ENgNtkSZE1jMh8tm1E777AqBqnrhJZ28+FA9Sk8YDuWIWhNOV/r4n97jTXqj4SAGCrlAMQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/tree-view/-/tree-view-1.17.4.tgz", + "integrity": "sha512-XRc2DxB/gVrkmS7+ZTJBC8p0G1J+mqtFb5zzRxyNitp+VW7yMsRtAUJ7m5gT5bD71zOkk4fPhwuB+ZZtpPAaMQ==", "requires": { - "@zag-js/anatomy": "0.82.1", - "@zag-js/collection": "0.82.1", - "@zag-js/core": "0.82.1", - "@zag-js/dom-query": "0.82.1", - "@zag-js/types": "0.82.1", - "@zag-js/utils": "0.82.1" + "@zag-js/anatomy": "1.17.4", + "@zag-js/collection": "1.17.4", + "@zag-js/core": "1.17.4", + "@zag-js/dom-query": "1.17.4", + "@zag-js/types": "1.17.4", + "@zag-js/utils": "1.17.4" } }, "@zag-js/types": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-0.82.1.tgz", - "integrity": "sha512-Nr/CU/z/SZWDL92P2u9VDZL9JUxY8L1P7dGI0CmDKHlEHk1+vzqg3UnVkUKkZ5eVMNLtloHbrux5X9Gmkl39WQ==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-1.17.4.tgz", + "integrity": "sha512-GHE1ykkMeHuIPHkkU1JNcIWMoFH322Yq65S4dhhsEgqMRX3BUHW8ids5e+7WOu9ZSH3PGJdpUXe8+jg3USpwaw==", "requires": { "csstype": "3.1.3" } }, "@zag-js/utils": { - "version": "0.82.1", - "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-0.82.1.tgz", - "integrity": "sha512-JUGdEjstrzB0G2AJqzQiURIl6UZ1ONYgby/pqBKX57LO5LxasQXk9oNZh8+ZAvePNC/lKqqTtyyI02YQB4XwkA==" + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-1.17.4.tgz", + "integrity": "sha512-FXici9HJG1ZBLCmbHO/ed4iurDriDjdx8XOfSD052bu22ViWl5jnO2K77OwagexbXGGAJNhswvDeQg5CSqYbvA==" }, "acorn": { "version": "8.14.0", @@ -6218,6 +7597,14 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "requires": { + "tslib": "^2.0.0" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -6307,6 +7694,11 @@ "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", "dev": true }, + "color2k": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz", + "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -6368,6 +7760,15 @@ "which": "^2.0.1" } }, + "css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "peer": true, + "requires": { + "tiny-invariant": "^1.0.6" + } + }, "csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -6399,6 +7800,11 @@ "integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==", "dev": true }, + "detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -6507,6 +7913,11 @@ "strip-final-newline": "^3.0.0" } }, + "fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, "fdir": { "version": "6.4.4", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", @@ -6535,6 +7946,34 @@ "mime-types": "^2.1.12" } }, + "framer-motion": { + "version": "12.23.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.0.tgz", + "integrity": "sha512-xf6NxTGAyf7zR4r2KlnhFmsRfKIbjqeBupEDBAaEtVIBJX96sAon00kMlsKButSIRwPSHjbRrAPnYdJJ9kyhbA==", + "peer": true, + "requires": { + "motion-dom": "^12.22.0", + "motion-utils": "^12.19.0", + "tslib": "^2.4.0" + } + }, + "framesync": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz", + "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==", + "peer": true, + "requires": { + "tslib": "2.4.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "peer": true + } + } + }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -6584,6 +8023,11 @@ "math-intrinsics": "^1.1.0" } }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, "get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -6739,6 +8183,11 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6828,6 +8277,21 @@ "ufo": "^1.5.4" } }, + "motion-dom": { + "version": "12.22.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.22.0.tgz", + "integrity": "sha512-ooH7+/BPw9gOsL9VtPhEJHE2m4ltnhMlcGMhEqA0YGNhKof7jdaszvsyThXI6LVIKshJUZ9/CP6HNqQhJfV7kw==", + "peer": true, + "requires": { + "motion-utils": "^12.19.0" + } + }, + "motion-utils": { + "version": "12.19.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.19.0.tgz", + "integrity": "sha512-BuFTHINYmV07pdWs6lj6aI63vr2N4dg0vR+td0rtrdpWOhBzIkEklZyLcvKBoEtwSqx8Jg06vUB5RS0xDiUybw==", + "peer": true + }, "nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -7068,6 +8532,12 @@ "@babel/runtime": "^7.12.5" } }, + "react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "peer": true + }, "react-hook-form": { "version": "7.49.3", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.49.3.tgz", @@ -7085,6 +8555,36 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-remove-scroll": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "requires": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + } + }, + "react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "requires": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + } + }, + "react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "requires": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + } + }, "readdirp": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", @@ -7272,6 +8772,23 @@ "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.2.tgz", "integrity": "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==" }, + "use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "requires": { + "tslib": "^2.0.0" + } + }, + "use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "requires": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + } + }, "use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 1760a34723..9803a97633 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,7 +12,9 @@ }, "dependencies": { "@chakra-ui/react": "^3.8.0", + "@chakra-ui/toast": "^7.0.2", "@emotion/react": "^11.14.0", + "@radix-ui/react-dialog": "^1.1.14", "@tanstack/react-query": "^5.28.14", "@tanstack/react-query-devtools": "^5.74.9", "@tanstack/react-router": "1.19.1", diff --git a/frontend/public/assets/images/favicon.png b/frontend/public/assets/images/favicon.png index e5b7c3ada7..009e6d5e69 100644 Binary files a/frontend/public/assets/images/favicon.png and b/frontend/public/assets/images/favicon.png differ diff --git a/frontend/public/assets/images/logo.png b/frontend/public/assets/images/logo.png new file mode 100644 index 0000000000..c27369bf92 Binary files /dev/null and b/frontend/public/assets/images/logo.png differ diff --git a/frontend/src/client/core/ApiError.ts b/frontend/src/client/core/ApiError.ts index 5499aa8f05..36675d288a 100644 --- a/frontend/src/client/core/ApiError.ts +++ b/frontend/src/client/core/ApiError.ts @@ -1,25 +1,21 @@ -import type { ApiRequestOptions } from "./ApiRequestOptions" -import type { ApiResult } from "./ApiResult" +import type { ApiRequestOptions } from './ApiRequestOptions'; +import type { ApiResult } from './ApiResult'; export class ApiError extends Error { - public readonly url: string - public readonly status: number - public readonly statusText: string - public readonly body: unknown - public readonly request: ApiRequestOptions + public readonly url: string; + public readonly status: number; + public readonly statusText: string; + public readonly body: unknown; + public readonly request: ApiRequestOptions; - constructor( - request: ApiRequestOptions, - response: ApiResult, - message: string, - ) { - super(message) + constructor(request: ApiRequestOptions, response: ApiResult, message: string) { + super(message); - this.name = "ApiError" - this.url = response.url - this.status = response.status - this.statusText = response.statusText - this.body = response.body - this.request = request - } -} + this.name = 'ApiError'; + this.url = response.url; + this.status = response.status; + this.statusText = response.statusText; + this.body = response.body; + this.request = request; + } +} \ No newline at end of file diff --git a/frontend/src/client/core/ApiRequestOptions.ts b/frontend/src/client/core/ApiRequestOptions.ts index d1136f428b..939a0aa4c8 100644 --- a/frontend/src/client/core/ApiRequestOptions.ts +++ b/frontend/src/client/core/ApiRequestOptions.ts @@ -1,21 +1,21 @@ export type ApiRequestOptions = { - readonly body?: any - readonly cookies?: Record - readonly errors?: Record - readonly formData?: Record | any[] | Blob | File - readonly headers?: Record - readonly mediaType?: string - readonly method: - | "DELETE" - | "GET" - | "HEAD" - | "OPTIONS" - | "PATCH" - | "POST" - | "PUT" - readonly path?: Record - readonly query?: Record - readonly responseHeader?: string - readonly responseTransformer?: (data: unknown) => Promise - readonly url: string -} + readonly body?: any; + readonly cookies?: Record; + readonly errors?: Record; + readonly formData?: Record | any[] | Blob | File; + readonly headers?: Record; + readonly mediaType?: string; + readonly method: + | 'DELETE' + | 'GET' + | 'HEAD' + | 'OPTIONS' + | 'PATCH' + | 'POST' + | 'PUT'; + readonly path?: Record; + readonly query?: Record; + readonly responseHeader?: string; + readonly responseTransformer?: (data: unknown) => Promise; + readonly url: string; +}; \ No newline at end of file diff --git a/frontend/src/client/core/ApiResult.ts b/frontend/src/client/core/ApiResult.ts index f88b8c64f1..4c58e39138 100644 --- a/frontend/src/client/core/ApiResult.ts +++ b/frontend/src/client/core/ApiResult.ts @@ -1,7 +1,7 @@ export type ApiResult = { - readonly body: TData - readonly ok: boolean - readonly status: number - readonly statusText: string - readonly url: string -} + readonly body: TData; + readonly ok: boolean; + readonly status: number; + readonly statusText: string; + readonly url: string; +}; \ No newline at end of file diff --git a/frontend/src/client/core/CancelablePromise.ts b/frontend/src/client/core/CancelablePromise.ts index f47db79eae..ccc082e8f2 100644 --- a/frontend/src/client/core/CancelablePromise.ts +++ b/frontend/src/client/core/CancelablePromise.ts @@ -1,126 +1,126 @@ export class CancelError extends Error { - constructor(message: string) { - super(message) - this.name = "CancelError" - } - - public get isCancelled(): boolean { - return true - } + constructor(message: string) { + super(message); + this.name = 'CancelError'; + } + + public get isCancelled(): boolean { + return true; + } } export interface OnCancel { - readonly isResolved: boolean - readonly isRejected: boolean - readonly isCancelled: boolean + readonly isResolved: boolean; + readonly isRejected: boolean; + readonly isCancelled: boolean; - (cancelHandler: () => void): void + (cancelHandler: () => void): void; } export class CancelablePromise implements Promise { - private _isResolved: boolean - private _isRejected: boolean - private _isCancelled: boolean - readonly cancelHandlers: (() => void)[] - readonly promise: Promise - private _resolve?: (value: T | PromiseLike) => void - private _reject?: (reason?: unknown) => void - - constructor( - executor: ( - resolve: (value: T | PromiseLike) => void, - reject: (reason?: unknown) => void, - onCancel: OnCancel, - ) => void, - ) { - this._isResolved = false - this._isRejected = false - this._isCancelled = false - this.cancelHandlers = [] - this.promise = new Promise((resolve, reject) => { - this._resolve = resolve - this._reject = reject - - const onResolve = (value: T | PromiseLike): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return - } - this._isResolved = true - if (this._resolve) this._resolve(value) - } - - const onReject = (reason?: unknown): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return - } - this._isRejected = true - if (this._reject) this._reject(reason) - } - - const onCancel = (cancelHandler: () => void): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return - } - this.cancelHandlers.push(cancelHandler) - } - - Object.defineProperty(onCancel, "isResolved", { - get: (): boolean => this._isResolved, - }) - - Object.defineProperty(onCancel, "isRejected", { - get: (): boolean => this._isRejected, - }) - - Object.defineProperty(onCancel, "isCancelled", { - get: (): boolean => this._isCancelled, - }) - - return executor(onResolve, onReject, onCancel as OnCancel) - }) - } - - get [Symbol.toStringTag]() { - return "Cancellable Promise" - } - - public then( - onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onRejected?: ((reason: unknown) => TResult2 | PromiseLike) | null, - ): Promise { - return this.promise.then(onFulfilled, onRejected) - } - - public catch( - onRejected?: ((reason: unknown) => TResult | PromiseLike) | null, - ): Promise { - return this.promise.catch(onRejected) - } - - public finally(onFinally?: (() => void) | null): Promise { - return this.promise.finally(onFinally) - } - - public cancel(): void { - if (this._isResolved || this._isRejected || this._isCancelled) { - return - } - this._isCancelled = true - if (this.cancelHandlers.length) { - try { - for (const cancelHandler of this.cancelHandlers) { - cancelHandler() - } - } catch (error) { - console.warn("Cancellation threw an error", error) - return - } - } - this.cancelHandlers.length = 0 - if (this._reject) this._reject(new CancelError("Request aborted")) - } - - public get isCancelled(): boolean { - return this._isCancelled - } -} + private _isResolved: boolean; + private _isRejected: boolean; + private _isCancelled: boolean; + readonly cancelHandlers: (() => void)[]; + readonly promise: Promise; + private _resolve?: (value: T | PromiseLike) => void; + private _reject?: (reason?: unknown) => void; + + constructor( + executor: ( + resolve: (value: T | PromiseLike) => void, + reject: (reason?: unknown) => void, + onCancel: OnCancel + ) => void + ) { + this._isResolved = false; + this._isRejected = false; + this._isCancelled = false; + this.cancelHandlers = []; + this.promise = new Promise((resolve, reject) => { + this._resolve = resolve; + this._reject = reject; + + const onResolve = (value: T | PromiseLike): void => { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._isResolved = true; + if (this._resolve) this._resolve(value); + }; + + const onReject = (reason?: unknown): void => { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._isRejected = true; + if (this._reject) this._reject(reason); + }; + + const onCancel = (cancelHandler: () => void): void => { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this.cancelHandlers.push(cancelHandler); + }; + + Object.defineProperty(onCancel, 'isResolved', { + get: (): boolean => this._isResolved, + }); + + Object.defineProperty(onCancel, 'isRejected', { + get: (): boolean => this._isRejected, + }); + + Object.defineProperty(onCancel, 'isCancelled', { + get: (): boolean => this._isCancelled, + }); + + return executor(onResolve, onReject, onCancel as OnCancel); + }); + } + + get [Symbol.toStringTag]() { + return "Cancellable Promise"; + } + + public then( + onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, + onRejected?: ((reason: unknown) => TResult2 | PromiseLike) | null + ): Promise { + return this.promise.then(onFulfilled, onRejected); + } + + public catch( + onRejected?: ((reason: unknown) => TResult | PromiseLike) | null + ): Promise { + return this.promise.catch(onRejected); + } + + public finally(onFinally?: (() => void) | null): Promise { + return this.promise.finally(onFinally); + } + + public cancel(): void { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._isCancelled = true; + if (this.cancelHandlers.length) { + try { + for (const cancelHandler of this.cancelHandlers) { + cancelHandler(); + } + } catch (error) { + console.warn('Cancellation threw an error', error); + return; + } + } + this.cancelHandlers.length = 0; + if (this._reject) this._reject(new CancelError('Request aborted')); + } + + public get isCancelled(): boolean { + return this._isCancelled; + } +} \ No newline at end of file diff --git a/frontend/src/client/core/OpenAPI.ts b/frontend/src/client/core/OpenAPI.ts index e99068ea2e..74f92b4085 100644 --- a/frontend/src/client/core/OpenAPI.ts +++ b/frontend/src/client/core/OpenAPI.ts @@ -1,57 +1,57 @@ -import type { AxiosRequestConfig, AxiosResponse } from "axios" -import type { ApiRequestOptions } from "./ApiRequestOptions" +import type { AxiosRequestConfig, AxiosResponse } from 'axios'; +import type { ApiRequestOptions } from './ApiRequestOptions'; -type Headers = Record -type Middleware = (value: T) => T | Promise -type Resolver = (options: ApiRequestOptions) => Promise +type Headers = Record; +type Middleware = (value: T) => T | Promise; +type Resolver = (options: ApiRequestOptions) => Promise; export class Interceptors { - _fns: Middleware[] + _fns: Middleware[]; constructor() { - this._fns = [] + this._fns = []; } eject(fn: Middleware): void { - const index = this._fns.indexOf(fn) + const index = this._fns.indexOf(fn); if (index !== -1) { - this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)] + this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)]; } } use(fn: Middleware): void { - this._fns = [...this._fns, fn] + this._fns = [...this._fns, fn]; } } export type OpenAPIConfig = { - BASE: string - CREDENTIALS: "include" | "omit" | "same-origin" - ENCODE_PATH?: ((path: string) => string) | undefined - HEADERS?: Headers | Resolver | undefined - PASSWORD?: string | Resolver | undefined - TOKEN?: string | Resolver | undefined - USERNAME?: string | Resolver | undefined - VERSION: string - WITH_CREDENTIALS: boolean - interceptors: { - request: Interceptors - response: Interceptors - } -} + BASE: string; + CREDENTIALS: 'include' | 'omit' | 'same-origin'; + ENCODE_PATH?: ((path: string) => string) | undefined; + HEADERS?: Headers | Resolver | undefined; + PASSWORD?: string | Resolver | undefined; + TOKEN?: string | Resolver | undefined; + USERNAME?: string | Resolver | undefined; + VERSION: string; + WITH_CREDENTIALS: boolean; + interceptors: { + request: Interceptors; + response: Interceptors; + }; +}; export const OpenAPI: OpenAPIConfig = { - BASE: "", - CREDENTIALS: "include", - ENCODE_PATH: undefined, - HEADERS: undefined, - PASSWORD: undefined, - TOKEN: undefined, - USERNAME: undefined, - VERSION: "0.1.0", - WITH_CREDENTIALS: false, - interceptors: { - request: new Interceptors(), - response: new Interceptors(), - }, -} + BASE: '', + CREDENTIALS: 'include', + ENCODE_PATH: undefined, + HEADERS: undefined, + PASSWORD: undefined, + TOKEN: undefined, + USERNAME: undefined, + VERSION: '0.1.0', + WITH_CREDENTIALS: false, + interceptors: { + request: new Interceptors(), + response: new Interceptors(), + }, +}; \ No newline at end of file diff --git a/frontend/src/client/core/request.ts b/frontend/src/client/core/request.ts index 8b42272b93..ecc2e393cd 100644 --- a/frontend/src/client/core/request.ts +++ b/frontend/src/client/core/request.ts @@ -1,325 +1,301 @@ -import axios from "axios" -import type { - AxiosError, - AxiosRequestConfig, - AxiosResponse, - AxiosInstance, -} from "axios" - -import { ApiError } from "./ApiError" -import type { ApiRequestOptions } from "./ApiRequestOptions" -import type { ApiResult } from "./ApiResult" -import { CancelablePromise } from "./CancelablePromise" -import type { OnCancel } from "./CancelablePromise" -import type { OpenAPIConfig } from "./OpenAPI" +import axios from 'axios'; +import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios'; + +import { ApiError } from './ApiError'; +import type { ApiRequestOptions } from './ApiRequestOptions'; +import type { ApiResult } from './ApiResult'; +import { CancelablePromise } from './CancelablePromise'; +import type { OnCancel } from './CancelablePromise'; +import type { OpenAPIConfig } from './OpenAPI'; export const isString = (value: unknown): value is string => { - return typeof value === "string" -} + return typeof value === 'string'; +}; export const isStringWithValue = (value: unknown): value is string => { - return isString(value) && value !== "" -} + return isString(value) && value !== ''; +}; export const isBlob = (value: any): value is Blob => { - return value instanceof Blob -} + return value instanceof Blob; +}; export const isFormData = (value: unknown): value is FormData => { - return value instanceof FormData -} + return value instanceof FormData; +}; export const isSuccess = (status: number): boolean => { - return status >= 200 && status < 300 -} + return status >= 200 && status < 300; +}; export const base64 = (str: string): string => { - try { - return btoa(str) - } catch (err) { - // @ts-ignore - return Buffer.from(str).toString("base64") - } -} + try { + return btoa(str); + } catch (err) { + // @ts-ignore + return Buffer.from(str).toString('base64'); + } +}; export const getQueryString = (params: Record): string => { - const qs: string[] = [] + const qs: string[] = []; - const append = (key: string, value: unknown) => { - qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`) - } + const append = (key: string, value: unknown) => { + qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); + }; - const encodePair = (key: string, value: unknown) => { - if (value === undefined || value === null) { - return - } + const encodePair = (key: string, value: unknown) => { + if (value === undefined || value === null) { + return; + } - if (value instanceof Date) { - append(key, value.toISOString()) - } else if (Array.isArray(value)) { - value.forEach((v) => encodePair(key, v)) - } else if (typeof value === "object") { - Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v)) - } else { - append(key, value) - } - } + if (value instanceof Date) { + append(key, value.toISOString()); + } else if (Array.isArray(value)) { + value.forEach(v => encodePair(key, v)); + } else if (typeof value === 'object') { + Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v)); + } else { + append(key, value); + } + }; - Object.entries(params).forEach(([key, value]) => encodePair(key, value)) + Object.entries(params).forEach(([key, value]) => encodePair(key, value)); - return qs.length ? `?${qs.join("&")}` : "" -} + return qs.length ? `?${qs.join('&')}` : ''; +}; const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => { - const encoder = config.ENCODE_PATH || encodeURI - - const path = options.url - .replace("{api-version}", config.VERSION) - .replace(/{(.*?)}/g, (substring: string, group: string) => { - if (options.path?.hasOwnProperty(group)) { - return encoder(String(options.path[group])) - } - return substring - }) - - const url = config.BASE + path - return options.query ? url + getQueryString(options.query) : url -} - -export const getFormData = ( - options: ApiRequestOptions, -): FormData | undefined => { - if (options.formData) { - const formData = new FormData() - - const process = (key: string, value: unknown) => { - if (isString(value) || isBlob(value)) { - formData.append(key, value) - } else { - formData.append(key, JSON.stringify(value)) - } - } - - Object.entries(options.formData) - .filter(([, value]) => value !== undefined && value !== null) - .forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach((v) => process(key, v)) - } else { - process(key, value) - } - }) - - return formData - } - return undefined -} - -type Resolver = (options: ApiRequestOptions) => Promise - -export const resolve = async ( - options: ApiRequestOptions, - resolver?: T | Resolver, -): Promise => { - if (typeof resolver === "function") { - return (resolver as Resolver)(options) - } - return resolver -} - -export const getHeaders = async ( - config: OpenAPIConfig, - options: ApiRequestOptions, -): Promise> => { - const [token, username, password, additionalHeaders] = await Promise.all([ - // @ts-ignore - resolve(options, config.TOKEN), - // @ts-ignore - resolve(options, config.USERNAME), - // @ts-ignore - resolve(options, config.PASSWORD), - // @ts-ignore - resolve(options, config.HEADERS), - ]) - - const headers = Object.entries({ - Accept: "application/json", - ...additionalHeaders, - ...options.headers, - }) - .filter(([, value]) => value !== undefined && value !== null) - .reduce( - (headers, [key, value]) => ({ - ...headers, - [key]: String(value), - }), - {} as Record, - ) - - if (isStringWithValue(token)) { - headers["Authorization"] = `Bearer ${token}` - } - - if (isStringWithValue(username) && isStringWithValue(password)) { - const credentials = base64(`${username}:${password}`) - headers["Authorization"] = `Basic ${credentials}` - } - - if (options.body !== undefined) { - if (options.mediaType) { - headers["Content-Type"] = options.mediaType - } else if (isBlob(options.body)) { - headers["Content-Type"] = options.body.type || "application/octet-stream" - } else if (isString(options.body)) { - headers["Content-Type"] = "text/plain" - } else if (!isFormData(options.body)) { - headers["Content-Type"] = "application/json" - } - } else if (options.formData !== undefined) { - if (options.mediaType) { - headers["Content-Type"] = options.mediaType - } - } - - return headers -} + const encoder = config.ENCODE_PATH || encodeURI; + + const path = options.url + .replace('{api-version}', config.VERSION) + .replace(/{(.*?)}/g, (substring: string, group: string) => { + if (options.path?.hasOwnProperty(group)) { + return encoder(String(options.path[group])); + } + return substring; + }); + + const url = config.BASE + path; + return options.query ? url + getQueryString(options.query) : url; +}; + +export const getFormData = (options: ApiRequestOptions): FormData | undefined => { + if (options.formData) { + const formData = new FormData(); + + const process = (key: string, value: unknown) => { + if (isString(value) || isBlob(value)) { + formData.append(key, value); + } else { + formData.append(key, JSON.stringify(value)); + } + }; + + Object.entries(options.formData) + .filter(([, value]) => value !== undefined && value !== null) + .forEach(([key, value]) => { + if (Array.isArray(value)) { + value.forEach(v => process(key, v)); + } else { + process(key, value); + } + }); + + return formData; + } + return undefined; +}; + +type Resolver = (options: ApiRequestOptions) => Promise; + +export const resolve = async (options: ApiRequestOptions, resolver?: T | Resolver): Promise => { + if (typeof resolver === 'function') { + return (resolver as Resolver)(options); + } + return resolver; +}; + +export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Promise> => { + const [token, username, password, additionalHeaders] = await Promise.all([ + // @ts-ignore + resolve(options, config.TOKEN), + // @ts-ignore + resolve(options, config.USERNAME), + // @ts-ignore + resolve(options, config.PASSWORD), + // @ts-ignore + resolve(options, config.HEADERS), + ]); + + const headers = Object.entries({ + Accept: 'application/json', + ...additionalHeaders, + ...options.headers, + }) + .filter(([, value]) => value !== undefined && value !== null) + .reduce((headers, [key, value]) => ({ + ...headers, + [key]: String(value), + }), {} as Record); + + if (isStringWithValue(token)) { + headers['Authorization'] = `Bearer ${token}`; + } + + if (isStringWithValue(username) && isStringWithValue(password)) { + const credentials = base64(`${username}:${password}`); + headers['Authorization'] = `Basic ${credentials}`; + } + + if (options.body !== undefined) { + if (options.mediaType) { + headers['Content-Type'] = options.mediaType; + } else if (isBlob(options.body)) { + headers['Content-Type'] = options.body.type || 'application/octet-stream'; + } else if (isString(options.body)) { + headers['Content-Type'] = 'text/plain'; + } else if (!isFormData(options.body)) { + headers['Content-Type'] = 'application/json'; + } + } else if (options.formData !== undefined) { + if (options.mediaType) { + headers['Content-Type'] = options.mediaType; + } + } + + return headers; +}; export const getRequestBody = (options: ApiRequestOptions): unknown => { - if (options.body) { - return options.body - } - return undefined -} + if (options.body) { + return options.body; + } + return undefined; +}; export const sendRequest = async ( - config: OpenAPIConfig, - options: ApiRequestOptions, - url: string, - body: unknown, - formData: FormData | undefined, - headers: Record, - onCancel: OnCancel, - axiosClient: AxiosInstance, + config: OpenAPIConfig, + options: ApiRequestOptions, + url: string, + body: unknown, + formData: FormData | undefined, + headers: Record, + onCancel: OnCancel, + axiosClient: AxiosInstance ): Promise> => { - const controller = new AbortController() - - let requestConfig: AxiosRequestConfig = { - data: body ?? formData, - headers, - method: options.method, - signal: controller.signal, - url, - withCredentials: config.WITH_CREDENTIALS, - } - - onCancel(() => controller.abort()) - - for (const fn of config.interceptors.request._fns) { - requestConfig = await fn(requestConfig) - } - - try { - return await axiosClient.request(requestConfig) - } catch (error) { - const axiosError = error as AxiosError - if (axiosError.response) { - return axiosError.response - } - throw error - } -} - -export const getResponseHeader = ( - response: AxiosResponse, - responseHeader?: string, -): string | undefined => { - if (responseHeader) { - const content = response.headers[responseHeader] - if (isString(content)) { - return content - } - } - return undefined -} + const controller = new AbortController(); + + let requestConfig: AxiosRequestConfig = { + data: body ?? formData, + headers, + method: options.method, + signal: controller.signal, + url, + withCredentials: config.WITH_CREDENTIALS, + }; + + onCancel(() => controller.abort()); + + for (const fn of config.interceptors.request._fns) { + requestConfig = await fn(requestConfig); + } + + try { + return await axiosClient.request(requestConfig); + } catch (error) { + const axiosError = error as AxiosError; + if (axiosError.response) { + return axiosError.response; + } + throw error; + } +}; + +export const getResponseHeader = (response: AxiosResponse, responseHeader?: string): string | undefined => { + if (responseHeader) { + const content = response.headers[responseHeader]; + if (isString(content)) { + return content; + } + } + return undefined; +}; export const getResponseBody = (response: AxiosResponse): unknown => { - if (response.status !== 204) { - return response.data - } - return undefined -} - -export const catchErrorCodes = ( - options: ApiRequestOptions, - result: ApiResult, -): void => { - const errors: Record = { - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Payload Too Large", - 414: "URI Too Long", - 415: "Unsupported Media Type", - 416: "Range Not Satisfiable", - 417: "Expectation Failed", - 418: "Im a teapot", - 421: "Misdirected Request", - 422: "Unprocessable Content", - 423: "Locked", - 424: "Failed Dependency", - 425: "Too Early", - 426: "Upgrade Required", - 428: "Precondition Required", - 429: "Too Many Requests", - 431: "Request Header Fields Too Large", - 451: "Unavailable For Legal Reasons", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported", - 506: "Variant Also Negotiates", - 507: "Insufficient Storage", - 508: "Loop Detected", - 510: "Not Extended", - 511: "Network Authentication Required", - ...options.errors, - } - - const error = errors[result.status] - if (error) { - throw new ApiError(options, result, error) - } - - if (!result.ok) { - const errorStatus = result.status ?? "unknown" - const errorStatusText = result.statusText ?? "unknown" - const errorBody = (() => { - try { - return JSON.stringify(result.body, null, 2) - } catch (e) { - return undefined - } - })() - - throw new ApiError( - options, - result, - `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`, - ) - } -} + if (response.status !== 204) { + return response.data; + } + return undefined; +}; + +export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { + const errors: Record = { + 400: 'Bad Request', + 401: 'Unauthorized', + 402: 'Payment Required', + 403: 'Forbidden', + 404: 'Not Found', + 405: 'Method Not Allowed', + 406: 'Not Acceptable', + 407: 'Proxy Authentication Required', + 408: 'Request Timeout', + 409: 'Conflict', + 410: 'Gone', + 411: 'Length Required', + 412: 'Precondition Failed', + 413: 'Payload Too Large', + 414: 'URI Too Long', + 415: 'Unsupported Media Type', + 416: 'Range Not Satisfiable', + 417: 'Expectation Failed', + 418: 'Im a teapot', + 421: 'Misdirected Request', + 422: 'Unprocessable Content', + 423: 'Locked', + 424: 'Failed Dependency', + 425: 'Too Early', + 426: 'Upgrade Required', + 428: 'Precondition Required', + 429: 'Too Many Requests', + 431: 'Request Header Fields Too Large', + 451: 'Unavailable For Legal Reasons', + 500: 'Internal Server Error', + 501: 'Not Implemented', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + 504: 'Gateway Timeout', + 505: 'HTTP Version Not Supported', + 506: 'Variant Also Negotiates', + 507: 'Insufficient Storage', + 508: 'Loop Detected', + 510: 'Not Extended', + 511: 'Network Authentication Required', + ...options.errors, + } + + const error = errors[result.status]; + if (error) { + throw new ApiError(options, result, error); + } + + if (!result.ok) { + const errorStatus = result.status ?? 'unknown'; + const errorStatusText = result.statusText ?? 'unknown'; + const errorBody = (() => { + try { + return JSON.stringify(result.body, null, 2); + } catch (e) { + return undefined; + } + })(); + + throw new ApiError(options, result, + `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}` + ); + } +}; /** * Request method @@ -329,59 +305,43 @@ export const catchErrorCodes = ( * @returns CancelablePromise * @throws ApiError */ -export const request = ( - config: OpenAPIConfig, - options: ApiRequestOptions, - axiosClient: AxiosInstance = axios, -): CancelablePromise => { - return new CancelablePromise(async (resolve, reject, onCancel) => { - try { - const url = getUrl(config, options) - const formData = getFormData(options) - const body = getRequestBody(options) - const headers = await getHeaders(config, options) - - if (!onCancel.isCancelled) { - let response = await sendRequest( - config, - options, - url, - body, - formData, - headers, - onCancel, - axiosClient, - ) - - for (const fn of config.interceptors.response._fns) { - response = await fn(response) - } - - const responseBody = getResponseBody(response) - const responseHeader = getResponseHeader( - response, - options.responseHeader, - ) - - let transformedBody = responseBody - if (options.responseTransformer && isSuccess(response.status)) { - transformedBody = await options.responseTransformer(responseBody) - } - - const result: ApiResult = { - url, - ok: isSuccess(response.status), - status: response.status, - statusText: response.statusText, - body: responseHeader ?? transformedBody, - } - - catchErrorCodes(options, result) - - resolve(result.body) - } - } catch (error) { - reject(error) - } - }) -} +export const request = (config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise => { + return new CancelablePromise(async (resolve, reject, onCancel) => { + try { + const url = getUrl(config, options); + const formData = getFormData(options); + const body = getRequestBody(options); + const headers = await getHeaders(config, options); + + if (!onCancel.isCancelled) { + let response = await sendRequest(config, options, url, body, formData, headers, onCancel, axiosClient); + + for (const fn of config.interceptors.response._fns) { + response = await fn(response); + } + + const responseBody = getResponseBody(response); + const responseHeader = getResponseHeader(response, options.responseHeader); + + let transformedBody = responseBody; + if (options.responseTransformer && isSuccess(response.status)) { + transformedBody = await options.responseTransformer(responseBody) + } + + const result: ApiResult = { + url, + ok: isSuccess(response.status), + status: response.status, + statusText: response.statusText, + body: responseHeader ?? transformedBody, + }; + + catchErrorCodes(options, result); + + resolve(result.body); + } + } catch (error) { + reject(error); + } + }); +}; \ No newline at end of file diff --git a/frontend/src/client/index.ts b/frontend/src/client/index.ts index 2228dde8b4..50a1dd734c 100644 --- a/frontend/src/client/index.ts +++ b/frontend/src/client/index.ts @@ -1,6 +1,6 @@ // This file is auto-generated by @hey-api/openapi-ts -export { ApiError } from "./core/ApiError" -export { CancelablePromise, CancelError } from "./core/CancelablePromise" -export { OpenAPI, type OpenAPIConfig } from "./core/OpenAPI" -export * from "./sdk.gen" -export * from "./types.gen" +export { ApiError } from './core/ApiError'; +export { CancelablePromise, CancelError } from './core/CancelablePromise'; +export { OpenAPI, type OpenAPIConfig } from './core/OpenAPI'; +export * from './sdk.gen'; +export * from './types.gen'; \ No newline at end of file diff --git a/frontend/src/client/schemas.gen.ts b/frontend/src/client/schemas.gen.ts deleted file mode 100644 index ca22051056..0000000000 --- a/frontend/src/client/schemas.gen.ts +++ /dev/null @@ -1,501 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export const Body_login_login_access_tokenSchema = { - properties: { - grant_type: { - anyOf: [ - { - type: "string", - pattern: "password", - }, - { - type: "null", - }, - ], - title: "Grant Type", - }, - username: { - type: "string", - title: "Username", - }, - password: { - type: "string", - title: "Password", - }, - scope: { - type: "string", - title: "Scope", - default: "", - }, - client_id: { - anyOf: [ - { - type: "string", - }, - { - type: "null", - }, - ], - title: "Client Id", - }, - client_secret: { - anyOf: [ - { - type: "string", - }, - { - type: "null", - }, - ], - title: "Client Secret", - }, - }, - type: "object", - required: ["username", "password"], - title: "Body_login-login_access_token", -} as const - -export const HTTPValidationErrorSchema = { - properties: { - detail: { - items: { - $ref: "#/components/schemas/ValidationError", - }, - type: "array", - title: "Detail", - }, - }, - type: "object", - title: "HTTPValidationError", -} as const - -export const ItemCreateSchema = { - properties: { - title: { - type: "string", - maxLength: 255, - minLength: 1, - title: "Title", - }, - description: { - anyOf: [ - { - type: "string", - maxLength: 255, - }, - { - type: "null", - }, - ], - title: "Description", - }, - }, - type: "object", - required: ["title"], - title: "ItemCreate", -} as const - -export const ItemPublicSchema = { - properties: { - title: { - type: "string", - maxLength: 255, - minLength: 1, - title: "Title", - }, - description: { - anyOf: [ - { - type: "string", - maxLength: 255, - }, - { - type: "null", - }, - ], - title: "Description", - }, - id: { - type: "string", - format: "uuid", - title: "Id", - }, - owner_id: { - type: "string", - format: "uuid", - title: "Owner Id", - }, - }, - type: "object", - required: ["title", "id", "owner_id"], - title: "ItemPublic", -} as const - -export const ItemUpdateSchema = { - properties: { - title: { - anyOf: [ - { - type: "string", - maxLength: 255, - minLength: 1, - }, - { - type: "null", - }, - ], - title: "Title", - }, - description: { - anyOf: [ - { - type: "string", - maxLength: 255, - }, - { - type: "null", - }, - ], - title: "Description", - }, - }, - type: "object", - title: "ItemUpdate", -} as const - -export const ItemsPublicSchema = { - properties: { - data: { - items: { - $ref: "#/components/schemas/ItemPublic", - }, - type: "array", - title: "Data", - }, - count: { - type: "integer", - title: "Count", - }, - }, - type: "object", - required: ["data", "count"], - title: "ItemsPublic", -} as const - -export const MessageSchema = { - properties: { - message: { - type: "string", - title: "Message", - }, - }, - type: "object", - required: ["message"], - title: "Message", -} as const - -export const NewPasswordSchema = { - properties: { - token: { - type: "string", - title: "Token", - }, - new_password: { - type: "string", - maxLength: 40, - minLength: 8, - title: "New Password", - }, - }, - type: "object", - required: ["token", "new_password"], - title: "NewPassword", -} as const - -export const TokenSchema = { - properties: { - access_token: { - type: "string", - title: "Access Token", - }, - token_type: { - type: "string", - title: "Token Type", - default: "bearer", - }, - }, - type: "object", - required: ["access_token"], - title: "Token", -} as const - -export const UpdatePasswordSchema = { - properties: { - current_password: { - type: "string", - maxLength: 40, - minLength: 8, - title: "Current Password", - }, - new_password: { - type: "string", - maxLength: 40, - minLength: 8, - title: "New Password", - }, - }, - type: "object", - required: ["current_password", "new_password"], - title: "UpdatePassword", -} as const - -export const UserCreateSchema = { - properties: { - email: { - type: "string", - maxLength: 255, - format: "email", - title: "Email", - }, - is_active: { - type: "boolean", - title: "Is Active", - default: true, - }, - is_superuser: { - type: "boolean", - title: "Is Superuser", - default: false, - }, - full_name: { - anyOf: [ - { - type: "string", - maxLength: 255, - }, - { - type: "null", - }, - ], - title: "Full Name", - }, - password: { - type: "string", - maxLength: 40, - minLength: 8, - title: "Password", - }, - }, - type: "object", - required: ["email", "password"], - title: "UserCreate", -} as const - -export const UserPublicSchema = { - properties: { - email: { - type: "string", - maxLength: 255, - format: "email", - title: "Email", - }, - is_active: { - type: "boolean", - title: "Is Active", - default: true, - }, - is_superuser: { - type: "boolean", - title: "Is Superuser", - default: false, - }, - full_name: { - anyOf: [ - { - type: "string", - maxLength: 255, - }, - { - type: "null", - }, - ], - title: "Full Name", - }, - id: { - type: "string", - format: "uuid", - title: "Id", - }, - }, - type: "object", - required: ["email", "id"], - title: "UserPublic", -} as const - -export const UserRegisterSchema = { - properties: { - email: { - type: "string", - maxLength: 255, - format: "email", - title: "Email", - }, - password: { - type: "string", - maxLength: 40, - minLength: 8, - title: "Password", - }, - full_name: { - anyOf: [ - { - type: "string", - maxLength: 255, - }, - { - type: "null", - }, - ], - title: "Full Name", - }, - }, - type: "object", - required: ["email", "password"], - title: "UserRegister", -} as const - -export const UserUpdateSchema = { - properties: { - email: { - anyOf: [ - { - type: "string", - maxLength: 255, - format: "email", - }, - { - type: "null", - }, - ], - title: "Email", - }, - is_active: { - type: "boolean", - title: "Is Active", - default: true, - }, - is_superuser: { - type: "boolean", - title: "Is Superuser", - default: false, - }, - full_name: { - anyOf: [ - { - type: "string", - maxLength: 255, - }, - { - type: "null", - }, - ], - title: "Full Name", - }, - password: { - anyOf: [ - { - type: "string", - maxLength: 40, - minLength: 8, - }, - { - type: "null", - }, - ], - title: "Password", - }, - }, - type: "object", - title: "UserUpdate", -} as const - -export const UserUpdateMeSchema = { - properties: { - full_name: { - anyOf: [ - { - type: "string", - maxLength: 255, - }, - { - type: "null", - }, - ], - title: "Full Name", - }, - email: { - anyOf: [ - { - type: "string", - maxLength: 255, - format: "email", - }, - { - type: "null", - }, - ], - title: "Email", - }, - }, - type: "object", - title: "UserUpdateMe", -} as const - -export const UsersPublicSchema = { - properties: { - data: { - items: { - $ref: "#/components/schemas/UserPublic", - }, - type: "array", - title: "Data", - }, - count: { - type: "integer", - title: "Count", - }, - }, - type: "object", - required: ["data", "count"], - title: "UsersPublic", -} as const - -export const ValidationErrorSchema = { - properties: { - loc: { - items: { - anyOf: [ - { - type: "string", - }, - { - type: "integer", - }, - ], - }, - type: "array", - title: "Location", - }, - msg: { - type: "string", - title: "Message", - }, - type: { - type: "string", - title: "Error Type", - }, - }, - type: "object", - required: ["loc", "msg", "type"], - title: "ValidationError", -} as const diff --git a/frontend/src/client/sdk.gen.ts b/frontend/src/client/sdk.gen.ts index 156003aec9..c2f498ce3a 100644 --- a/frontend/src/client/sdk.gen.ts +++ b/frontend/src/client/sdk.gen.ts @@ -1,549 +1,1467 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { CancelablePromise } from "./core/CancelablePromise" -import { OpenAPI } from "./core/OpenAPI" -import { request as __request } from "./core/request" -import type { - ItemsReadItemsData, - ItemsReadItemsResponse, - ItemsCreateItemData, - ItemsCreateItemResponse, - ItemsReadItemData, - ItemsReadItemResponse, - ItemsUpdateItemData, - ItemsUpdateItemResponse, - ItemsDeleteItemData, - ItemsDeleteItemResponse, - LoginLoginAccessTokenData, - LoginLoginAccessTokenResponse, - LoginTestTokenResponse, - LoginRecoverPasswordData, - LoginRecoverPasswordResponse, - LoginResetPasswordData, - LoginResetPasswordResponse, - LoginRecoverPasswordHtmlContentData, - LoginRecoverPasswordHtmlContentResponse, - PrivateCreateUserData, - PrivateCreateUserResponse, - UsersReadUsersData, - UsersReadUsersResponse, - UsersCreateUserData, - UsersCreateUserResponse, - UsersReadUserMeResponse, - UsersDeleteUserMeResponse, - UsersUpdateUserMeData, - UsersUpdateUserMeResponse, - UsersUpdatePasswordMeData, - UsersUpdatePasswordMeResponse, - UsersRegisterUserData, - UsersRegisterUserResponse, - UsersReadUserByIdData, - UsersReadUserByIdResponse, - UsersUpdateUserData, - UsersUpdateUserResponse, - UsersDeleteUserData, - UsersDeleteUserResponse, - UtilsTestEmailData, - UtilsTestEmailResponse, - UtilsHealthCheckResponse, -} from "./types.gen" +import type { CancelablePromise } from './core/CancelablePromise'; +import { OpenAPI } from './core/OpenAPI'; +import { request as __request } from './core/request'; +import type { AiSoulsCreateAiSoulData, AiSoulsCreateAiSoulResponse, AiSoulsGetAiSoulsData, AiSoulsGetAiSoulsResponse, AiSoulsGetAiSoulData, AiSoulsGetAiSoulResponse, AiSoulsUpdateAiSoulData, AiSoulsUpdateAiSoulResponse, AiSoulsDeleteAiSoulData, AiSoulsDeleteAiSoulResponse, ChatCreateChatMessageData, ChatCreateChatMessageResponse, ChatGetChatMessagesData, ChatGetChatMessagesResponse, ChatDeleteChatMessagesData, ChatDeleteChatMessagesResponse, CounselorGetCounselorQueueData, CounselorGetCounselorQueueResponse, CounselorGetOrganizationQueueData, CounselorGetOrganizationQueueResponse, CounselorApproveResponseData, CounselorApproveResponseResponse, CounselorModifyResponseData, CounselorModifyResponseResponse, CounselorRejectResponseData, CounselorRejectResponseResponse, CounselorEscalateCaseData, CounselorEscalateCaseResponse, CounselorGetCounselorPerformanceData, CounselorGetCounselorPerformanceResponse, CounselorGetRecentRiskAssessmentsData, CounselorGetRecentRiskAssessmentsResponse, CounselorGetHighRiskConversationsData, CounselorGetHighRiskConversationsResponse, CounselorAutoApproveExpiredResponsesResponse, CounselorListCounselorsData, CounselorListCounselorsResponse, UntaggedHealthCheckResponse, UntaggedCreateUserData, UntaggedCreateUserResponse, DocumentsUploadDocumentData, DocumentsUploadDocumentResponse, DocumentsGetDocumentsData, DocumentsGetDocumentsResponse, DocumentsDeleteDocumentData, DocumentsDeleteDocumentResponse, DocumentsGetDocumentData, DocumentsGetDocumentResponse, DocumentsSearchDocumentsData, DocumentsSearchDocumentsResponse, DocumentsGetDocumentStatsResponse, EnhancedRagSearchDocumentsData, EnhancedRagSearchDocumentsResponse, EnhancedRagProcessDocumentData, EnhancedRagProcessDocumentResponse, EnhancedRagReindexDocumentData, EnhancedRagReindexDocumentResponse, EnhancedRagDeleteDocumentIndexData, EnhancedRagDeleteDocumentIndexResponse, EnhancedRagTrackResultClickData, EnhancedRagTrackResultClickResponse, EnhancedRagGetSearchAnalyticsData, EnhancedRagGetSearchAnalyticsResponse, EnhancedRagGetRagConfigurationData, EnhancedRagGetRagConfigurationResponse, EnhancedRagUpdateRagConfigurationData, EnhancedRagUpdateRagConfigurationResponse, EnhancedRagHealthCheckResponse, EnhancedRagGetCollectionInfoResponse, EnhancedRagGetSearchSuggestionsData, EnhancedRagGetSearchSuggestionsResponse, EnhancedRagBulkProcessDocumentsData, EnhancedRagBulkProcessDocumentsResponse, ItemsReadItemsData, ItemsReadItemsResponse, ItemsCreateItemData, ItemsCreateItemResponse, ItemsReadItemData, ItemsReadItemResponse, ItemsUpdateItemData, ItemsUpdateItemResponse, ItemsDeleteItemData, ItemsDeleteItemResponse, LoginLoginAccessTokenData, LoginLoginAccessTokenResponse, LoginTestTokenResponse, LoginRecoverPasswordData, LoginRecoverPasswordResponse, LoginResetPasswordData, LoginResetPasswordResponse, LoginRecoverPasswordHtmlContentData, LoginRecoverPasswordHtmlContentResponse, PrivateCreateUserData, PrivateCreateUserResponse, TrainingSendTrainingMessageData, TrainingSendTrainingMessageResponse, TrainingGetTrainingMessagesData, TrainingGetTrainingMessagesResponse, TrainingUploadTrainingDocumentData, TrainingUploadTrainingDocumentResponse, TrainingGetTrainingDocumentsData, TrainingGetTrainingDocumentsResponse, TrainingDeleteTrainingDocumentData, TrainingDeleteTrainingDocumentResponse, UsersReadUsersData, UsersReadUsersResponse, UsersReadUserMeResponse, UsersDeleteUserMeResponse, UsersUpdateUserMeData, UsersUpdateUserMeResponse, UsersUpdatePasswordMeData, UsersUpdatePasswordMeResponse, UsersRegisterUserData, UsersRegisterUserResponse, UsersReadUserByIdData, UsersReadUserByIdResponse, UsersUpdateUserData, UsersUpdateUserResponse, UsersDeleteUserData, UsersDeleteUserResponse, UtilsHealthCheckResponse, UtilsGetSystemHealthResponse } from './types.gen'; -export class ItemsService { - /** - * Read Items - * Retrieve items. - * @param data The data for the request. - * @param data.skip - * @param data.limit - * @returns ItemsPublic Successful Response - * @throws ApiError - */ - public static readItems( - data: ItemsReadItemsData = {}, - ): CancelablePromise { - return __request(OpenAPI, { - method: "GET", - url: "/api/v1/items/", - query: { - skip: data.skip, - limit: data.limit, - }, - errors: { - 422: "Validation Error", - }, - }) - } - - /** - * Create Item - * Create new item. - * @param data The data for the request. - * @param data.requestBody - * @returns ItemPublic Successful Response - * @throws ApiError - */ - public static createItem( - data: ItemsCreateItemData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/items/", - body: data.requestBody, - mediaType: "application/json", - errors: { - 422: "Validation Error", - }, - }) - } - - /** - * Read Item - * Get item by ID. - * @param data The data for the request. - * @param data.id - * @returns ItemPublic Successful Response - * @throws ApiError - */ - public static readItem( - data: ItemsReadItemData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "GET", - url: "/api/v1/items/{id}", - path: { - id: data.id, - }, - errors: { - 422: "Validation Error", - }, - }) - } +export class AiSoulsService { + /** + * Create Ai Soul + * Create a new AI soul. + * Only trainers and admins can create souls. + * @param data The data for the request. + * @param data.requestBody + * @returns AISoulEntityPublic Successful Response + * @throws ApiError + */ + public static createAiSoul(data: AiSoulsCreateAiSoulData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/ai-souls/', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Ai Souls + * Get all AI souls with role-based interaction counts. + * Regular users see their own interaction counts. + * Admins and counselors see global interaction counts. + * @param data The data for the request. + * @param data.skip + * @param data.limit + * @returns AISoulEntityWithUserInteraction Successful Response + * @throws ApiError + */ + public static getAiSouls(data: AiSoulsGetAiSoulsData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/ai-souls/', + query: { + skip: data.skip, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Ai Soul + * Get a specific AI soul by ID with role-based interaction count. + * Regular users see their own interaction count. + * Admins and counselors see global interaction count. + * @param data The data for the request. + * @param data.aiSoulId + * @returns AISoulEntityWithUserInteraction Successful Response + * @throws ApiError + */ + public static getAiSoul(data: AiSoulsGetAiSoulData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/ai-souls/{ai_soul_id}', + path: { + ai_soul_id: data.aiSoulId + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Update Ai Soul + * Update a specific AI soul. + * Only trainers and admins can update souls. + * @param data The data for the request. + * @param data.aiSoulId + * @param data.requestBody + * @returns AISoulEntity Successful Response + * @throws ApiError + */ + public static updateAiSoul(data: AiSoulsUpdateAiSoulData): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/api/v1/ai-souls/{ai_soul_id}', + path: { + ai_soul_id: data.aiSoulId + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Delete Ai Soul + * Delete a specific AI soul. + * Only admins can delete souls. + * @param data The data for the request. + * @param data.aiSoulId + * @returns unknown Successful Response + * @throws ApiError + */ + public static deleteAiSoul(data: AiSoulsDeleteAiSoulData): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/ai-souls/{ai_soul_id}', + path: { + ai_soul_id: data.aiSoulId + }, + errors: { + 422: 'Validation Error' + } + }); + } + +} - /** - * Update Item - * Update an item. - * @param data The data for the request. - * @param data.id - * @param data.requestBody - * @returns ItemPublic Successful Response - * @throws ApiError - */ - public static updateItem( - data: ItemsUpdateItemData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "PUT", - url: "/api/v1/items/{id}", - path: { - id: data.id, - }, - body: data.requestBody, - mediaType: "application/json", - errors: { - 422: "Validation Error", - }, - }) - } +export class ChatService { + /** + * Create Chat Message + * Create a new chat message and get AI response with counselor override system. + * Any user can chat with any AI soul. + * Returns both user message and AI response to prevent message stacking. + * @param data The data for the request. + * @param data.aiSoulId + * @param data.requestBody + * @returns ChatMessagePairResponse Successful Response + * @throws ApiError + */ + public static createChatMessage(data: ChatCreateChatMessageData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/chat/{ai_soul_id}/messages', + path: { + ai_soul_id: data.aiSoulId + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Chat Messages + * Get chat messages for a specific AI soul. + * Users can only see their own chat messages. + * Messages are returned in ascending order (oldest first). + * @param data The data for the request. + * @param data.aiSoulId + * @param data.skip + * @param data.limit + * @returns ChatMessagePublic Successful Response + * @throws ApiError + */ + public static getChatMessages(data: ChatGetChatMessagesData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/chat/{ai_soul_id}/messages', + path: { + ai_soul_id: data.aiSoulId + }, + query: { + skip: data.skip, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Delete Chat Messages + * Delete all chat messages for a specific AI soul. + * Users can only delete their own chat messages. + * @param data The data for the request. + * @param data.aiSoulId + * @returns unknown Successful Response + * @throws ApiError + */ + public static deleteChatMessages(data: ChatDeleteChatMessagesData): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/chat/{ai_soul_id}/messages', + path: { + ai_soul_id: data.aiSoulId + }, + errors: { + 422: 'Validation Error' + } + }); + } + +} - /** - * Delete Item - * Delete an item. - * @param data The data for the request. - * @param data.id - * @returns Message Successful Response - * @throws ApiError - */ - public static deleteItem( - data: ItemsDeleteItemData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "DELETE", - url: "/api/v1/items/{id}", - path: { - id: data.id, - }, - errors: { - 422: "Validation Error", - }, - }) - } +export class CounselorService { + /** + * Get Counselor Queue + * Get the review queue for the current counselor. + * @param data The data for the request. + * @param data.status Status filter + * @param data.limit Maximum number of items + * @returns CounselorQueueResponse Successful Response + * @throws ApiError + */ + public static getCounselorQueue(data: CounselorGetCounselorQueueData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/counselor/queue', + query: { + status: data.status, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Organization Queue + * Get the organization-wide review queue (admin/supervisor only). + * @param data The data for the request. + * @param data.status Status filter + * @param data.priority Priority filter + * @param data.limit Maximum number of items + * @returns unknown Successful Response + * @throws ApiError + */ + public static getOrganizationQueue(data: CounselorGetOrganizationQueueData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/counselor/organization-queue', + query: { + status: data.status, + priority: data.priority, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Approve Response + * Approve an AI response without modifications. + * @param data The data for the request. + * @param data.pendingResponseId + * @param data.requestBody + * @returns unknown Successful Response + * @throws ApiError + */ + public static approveResponse(data: CounselorApproveResponseData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/counselor/{pending_response_id}/approve', + path: { + pending_response_id: data.pendingResponseId + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Modify Response + * Modify an AI response before sending to user. + * @param data The data for the request. + * @param data.pendingResponseId + * @param data.requestBody + * @returns unknown Successful Response + * @throws ApiError + */ + public static modifyResponse(data: CounselorModifyResponseData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/counselor/{pending_response_id}/modify', + path: { + pending_response_id: data.pendingResponseId + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Reject Response + * Reject an AI response and provide a replacement. + * @param data The data for the request. + * @param data.pendingResponseId + * @param data.requestBody + * @returns unknown Successful Response + * @throws ApiError + */ + public static rejectResponse(data: CounselorRejectResponseData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/counselor/{pending_response_id}/reject', + path: { + pending_response_id: data.pendingResponseId + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Escalate Case + * Escalate a case to another counselor or supervisor. + * @param data The data for the request. + * @param data.pendingResponseId + * @param data.requestBody + * @returns unknown Successful Response + * @throws ApiError + */ + public static escalateCase(data: CounselorEscalateCaseData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/counselor/{pending_response_id}/escalate', + path: { + pending_response_id: data.pendingResponseId + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Counselor Performance + * Get performance metrics for the current counselor. + * @param data The data for the request. + * @param data.days Number of days to analyze + * @returns PerformanceMetricsResponse Successful Response + * @throws ApiError + */ + public static getCounselorPerformance(data: CounselorGetCounselorPerformanceData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/counselor/performance', + query: { + days: data.days + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Recent Risk Assessments + * Get recent risk assessments for monitoring (counselor/admin only). + * @param data The data for the request. + * @param data.days Number of days to look back + * @param data.limit Maximum number of assessments + * @returns unknown Successful Response + * @throws ApiError + */ + public static getRecentRiskAssessments(data: CounselorGetRecentRiskAssessmentsData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/counselor/risk-assessments', + query: { + days: data.days, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get High Risk Conversations + * Get conversations with high risk assessments for immediate attention. + * @param data The data for the request. + * @param data.hours Number of hours to look back + * @returns unknown Successful Response + * @throws ApiError + */ + public static getHighRiskConversations(data: CounselorGetHighRiskConversationsData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/counselor/high-risk-conversations', + query: { + hours: data.hours + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Auto Approve Expired Responses + * Manually trigger auto-approval of expired responses (admin only). + * @returns unknown Successful Response + * @throws ApiError + */ + public static autoApproveExpiredResponses(): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/counselor/auto-approve-expired' + }); + } + + /** + * List Counselors + * List all counselors (admin only). + * @param data The data for the request. + * @param data.organizationId Filter by organization + * @returns unknown Successful Response + * @throws ApiError + */ + public static listCounselors(data: CounselorListCounselorsData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/counselor/counselors', + query: { + organization_id: data.organizationId + }, + errors: { + 422: 'Validation Error' + } + }); + } + } -export class LoginService { - /** - * Login Access Token - * OAuth2 compatible token login, get an access token for future requests - * @param data The data for the request. - * @param data.formData - * @returns Token Successful Response - * @throws ApiError - */ - public static loginAccessToken( - data: LoginLoginAccessTokenData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/login/access-token", - formData: data.formData, - mediaType: "application/x-www-form-urlencoded", - errors: { - 422: "Validation Error", - }, - }) - } +export class DefaultService { + /** + * Health Check + * Health check endpoint to verify the service is running. + * @returns unknown Successful Response + * @throws ApiError + */ + public static untaggedHealthCheck(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/utils/health-check/' + }); + } + + /** + * Create User + * Create a new user. + * @param data The data for the request. + * @param data.requestBody + * @returns UserPublic Successful Response + * @throws ApiError + */ + public static untaggedCreateUser(data: UntaggedCreateUserData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/users/', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + +} - /** - * Test Token - * Test access token - * @returns UserPublic Successful Response - * @throws ApiError - */ - public static testToken(): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/login/test-token", - }) - } +export class DocumentsService { + /** + * Upload Document + * Upload a PDF document for processing. + * @param data The data for the request. + * @param data.formData + * @returns DocumentPublic Successful Response + * @throws ApiError + */ + public static uploadDocument(data: DocumentsUploadDocumentData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/documents/upload/', + formData: data.formData, + mediaType: 'multipart/form-data', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Documents + * Retrieve all documents for the current user. + * @param data The data for the request. + * @param data.skip + * @param data.limit + * @returns DocumentsPublic Successful Response + * @throws ApiError + */ + public static getDocuments(data: DocumentsGetDocumentsData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/documents/', + query: { + skip: data.skip, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Delete Document + * Delete a document and its associated file. + * @param data The data for the request. + * @param data.documentId + * @returns unknown Successful Response + * @throws ApiError + */ + public static deleteDocument(data: DocumentsDeleteDocumentData): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/documents/{document_id}', + path: { + document_id: data.documentId + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Document + * Get a specific document by ID. + * @param data The data for the request. + * @param data.documentId + * @returns DocumentPublic Successful Response + * @throws ApiError + */ + public static getDocument(data: DocumentsGetDocumentData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/documents/{document_id}', + path: { + document_id: data.documentId + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Search Documents + * Search through uploaded documents using Enhanced RAG. + * @param data The data for the request. + * @param data.formData + * @returns unknown Successful Response + * @throws ApiError + */ + public static searchDocuments(data: DocumentsSearchDocumentsData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/documents/search', + formData: data.formData, + mediaType: 'application/x-www-form-urlencoded', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Document Stats + * Get document statistics for the current user. + * @returns unknown Successful Response + * @throws ApiError + */ + public static getDocumentStats(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/documents/stats/summary' + }); + } + +} - /** - * Recover Password - * Password Recovery - * @param data The data for the request. - * @param data.email - * @returns Message Successful Response - * @throws ApiError - */ - public static recoverPassword( - data: LoginRecoverPasswordData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/password-recovery/{email}", - path: { - email: data.email, - }, - errors: { - 422: "Validation Error", - }, - }) - } +export class EnhancedRagService { + /** + * Search Documents + * Search documents using enhanced RAG with hybrid retrieval. + * + * Features: + * - Semantic vector search + * - Keyword matching + * - Result reranking + * - Caching for performance + * - Analytics tracking + * @param data The data for the request. + * @param data.requestBody + * @returns SearchResponse Successful Response + * @throws ApiError + */ + public static searchDocuments(data: EnhancedRagSearchDocumentsData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/rag/search', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Process Document + * Process a document with enhanced chunking and indexing. + * + * Steps: + * 1. Extract text from document + * 2. Apply intelligent chunking + * 3. Generate embeddings + * 4. Store in vector database + * 5. Update analytics + * @param data The data for the request. + * @param data.requestBody + * @returns ProcessDocumentResponse Successful Response + * @throws ApiError + */ + public static processDocument(data: EnhancedRagProcessDocumentData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/rag/documents/process', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Reindex Document + * Reindex an existing document with current configuration. + * + * This will: + * 1. Delete existing chunks from vector database + * 2. Reprocess the document with current settings + * 3. Create new embeddings and chunks + * @param data The data for the request. + * @param data.documentId + * @returns unknown Successful Response + * @throws ApiError + */ + public static reindexDocument(data: EnhancedRagReindexDocumentData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/rag/documents/{document_id}/reindex', + path: { + document_id: data.documentId + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Delete Document Index + * Delete document chunks from the vector index. + * + * This removes all chunks and embeddings for the document + * but keeps the document record intact. + * @param data The data for the request. + * @param data.documentId + * @returns unknown Successful Response + * @throws ApiError + */ + public static deleteDocumentIndex(data: EnhancedRagDeleteDocumentIndexData): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/rag/documents/{document_id}/index', + path: { + document_id: data.documentId + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Track Result Click + * Track when a user clicks on a search result. + * + * This helps improve search relevance through user feedback + * and provides analytics on result effectiveness. + * @param data The data for the request. + * @param data.requestBody + * @returns unknown Successful Response + * @throws ApiError + */ + public static trackResultClick(data: EnhancedRagTrackResultClickData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/rag/analytics/click', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Search Analytics + * Get search analytics for the current user. + * + * Returns: + * - Total searches performed + * - Average response time + * - Click-through rate + * - Top search queries + * @param data The data for the request. + * @param data.days Number of days to analyze + * @returns unknown Successful Response + * @throws ApiError + */ + public static getSearchAnalytics(data: EnhancedRagGetSearchAnalyticsData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/rag/analytics/search', + query: { + days: data.days + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Rag Configuration + * Get RAG configuration for user or specific AI Soul. + * @param data The data for the request. + * @param data.aiSoulId AI Soul ID + * @returns unknown Successful Response + * @throws ApiError + */ + public static getRagConfiguration(data: EnhancedRagGetRagConfigurationData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/rag/configuration', + query: { + ai_soul_id: data.aiSoulId + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Update Rag Configuration + * Update RAG configuration for user or specific AI Soul. + * @param data The data for the request. + * @param data.requestBody + * @returns unknown Successful Response + * @throws ApiError + */ + public static updateRagConfiguration(data: EnhancedRagUpdateRagConfigurationData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/rag/configuration', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Health Check + * Perform health check on RAG system components. + * + * Checks: + * - Qdrant vector database connectivity + * - Redis cache availability + * - OpenAI API connectivity + * - Database connectivity + * @returns unknown Successful Response + * @throws ApiError + */ + public static healthCheck(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/rag/health' + }); + } + + /** + * Get Collection Info + * Get information about Qdrant collections. + * + * Returns collection statistics and status for monitoring. + * @returns unknown Successful Response + * @throws ApiError + */ + public static getCollectionInfo(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/rag/collections/info' + }); + } + + /** + * Get Search Suggestions + * Get search suggestions based on query prefix. + * + * Returns popular queries that start with the given prefix + * to help users with query completion. + * @param data The data for the request. + * @param data.query + * @param data.limit + * @returns unknown Successful Response + * @throws ApiError + */ + public static getSearchSuggestions(data: EnhancedRagGetSearchSuggestionsData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/rag/suggestions', + query: { + query: data.query, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Bulk Process Documents + * Process multiple documents in bulk. + * + * Useful for reprocessing documents after configuration changes + * or initial setup of large document collections. + * @param data The data for the request. + * @param data.requestBody + * @param data.chunkingStrategy + * @returns unknown Successful Response + * @throws ApiError + */ + public static bulkProcessDocuments(data: EnhancedRagBulkProcessDocumentsData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/rag/bulk-process', + query: { + chunking_strategy: data.chunkingStrategy + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + +} - /** - * Reset Password - * Reset password - * @param data The data for the request. - * @param data.requestBody - * @returns Message Successful Response - * @throws ApiError - */ - public static resetPassword( - data: LoginResetPasswordData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/reset-password/", - body: data.requestBody, - mediaType: "application/json", - errors: { - 422: "Validation Error", - }, - }) - } +export class ItemsService { + /** + * Read Items + * Retrieve items. + * @param data The data for the request. + * @param data.skip + * @param data.limit + * @returns ItemsPublic Successful Response + * @throws ApiError + */ + public static readItems(data: ItemsReadItemsData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/items/', + query: { + skip: data.skip, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Create Item + * Create new item. + * @param data The data for the request. + * @param data.requestBody + * @returns ItemPublic Successful Response + * @throws ApiError + */ + public static createItem(data: ItemsCreateItemData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/items/', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Read Item + * Get item by ID. + * @param data The data for the request. + * @param data.id + * @returns ItemPublic Successful Response + * @throws ApiError + */ + public static readItem(data: ItemsReadItemData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/items/{id}', + path: { + id: data.id + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Update Item + * Update an item. + * @param data The data for the request. + * @param data.id + * @param data.requestBody + * @returns ItemPublic Successful Response + * @throws ApiError + */ + public static updateItem(data: ItemsUpdateItemData): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/api/v1/items/{id}', + path: { + id: data.id + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Delete Item + * Delete an item. + * @param data The data for the request. + * @param data.id + * @returns Message Successful Response + * @throws ApiError + */ + public static deleteItem(data: ItemsDeleteItemData): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/items/{id}', + path: { + id: data.id + }, + errors: { + 422: 'Validation Error' + } + }); + } + +} - /** - * Recover Password Html Content - * HTML Content for Password Recovery - * @param data The data for the request. - * @param data.email - * @returns string Successful Response - * @throws ApiError - */ - public static recoverPasswordHtmlContent( - data: LoginRecoverPasswordHtmlContentData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/password-recovery-html-content/{email}", - path: { - email: data.email, - }, - errors: { - 422: "Validation Error", - }, - }) - } +export class LoginService { + /** + * Login Access Token + * OAuth2 compatible token login, get an access token for future requests + * @param data The data for the request. + * @param data.formData + * @returns Token Successful Response + * @throws ApiError + */ + public static loginAccessToken(data: LoginLoginAccessTokenData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/login/access-token', + formData: data.formData, + mediaType: 'application/x-www-form-urlencoded', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Test Token + * Test access token + * @returns UserPublic Successful Response + * @throws ApiError + */ + public static testToken(): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/login/test-token' + }); + } + + /** + * Recover Password + * Password Recovery + * @param data The data for the request. + * @param data.email + * @returns Message Successful Response + * @throws ApiError + */ + public static recoverPassword(data: LoginRecoverPasswordData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/password-recovery/{email}', + path: { + email: data.email + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Reset Password + * Reset password + * @param data The data for the request. + * @param data.requestBody + * @returns Message Successful Response + * @throws ApiError + */ + public static resetPassword(data: LoginResetPasswordData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/reset-password/', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Recover Password Html Content + * HTML Content for Password Recovery + * @param data The data for the request. + * @param data.email + * @returns string Successful Response + * @throws ApiError + */ + public static recoverPasswordHtmlContent(data: LoginRecoverPasswordHtmlContentData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/password-recovery-html-content/{email}', + path: { + email: data.email + }, + errors: { + 422: 'Validation Error' + } + }); + } + } export class PrivateService { - /** - * Create User - * Create a new user. - * @param data The data for the request. - * @param data.requestBody - * @returns UserPublic Successful Response - * @throws ApiError - */ - public static createUser( - data: PrivateCreateUserData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/private/users/", - body: data.requestBody, - mediaType: "application/json", - errors: { - 422: "Validation Error", - }, - }) - } + /** + * Create User + * Create a new user. + * @param data The data for the request. + * @param data.requestBody + * @returns UserPublic Successful Response + * @throws ApiError + */ + public static createUser(data: PrivateCreateUserData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/private/users/', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + } -export class UsersService { - /** - * Read Users - * Retrieve users. - * @param data The data for the request. - * @param data.skip - * @param data.limit - * @returns UsersPublic Successful Response - * @throws ApiError - */ - public static readUsers( - data: UsersReadUsersData = {}, - ): CancelablePromise { - return __request(OpenAPI, { - method: "GET", - url: "/api/v1/users/", - query: { - skip: data.skip, - limit: data.limit, - }, - errors: { - 422: "Validation Error", - }, - }) - } - - /** - * Create User - * Create new user. - * @param data The data for the request. - * @param data.requestBody - * @returns UserPublic Successful Response - * @throws ApiError - */ - public static createUser( - data: UsersCreateUserData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/users/", - body: data.requestBody, - mediaType: "application/json", - errors: { - 422: "Validation Error", - }, - }) - } - - /** - * Read User Me - * Get current user. - * @returns UserPublic Successful Response - * @throws ApiError - */ - public static readUserMe(): CancelablePromise { - return __request(OpenAPI, { - method: "GET", - url: "/api/v1/users/me", - }) - } - - /** - * Delete User Me - * Delete own user. - * @returns Message Successful Response - * @throws ApiError - */ - public static deleteUserMe(): CancelablePromise { - return __request(OpenAPI, { - method: "DELETE", - url: "/api/v1/users/me", - }) - } - - /** - * Update User Me - * Update own user. - * @param data The data for the request. - * @param data.requestBody - * @returns UserPublic Successful Response - * @throws ApiError - */ - public static updateUserMe( - data: UsersUpdateUserMeData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "PATCH", - url: "/api/v1/users/me", - body: data.requestBody, - mediaType: "application/json", - errors: { - 422: "Validation Error", - }, - }) - } - - /** - * Update Password Me - * Update own password. - * @param data The data for the request. - * @param data.requestBody - * @returns Message Successful Response - * @throws ApiError - */ - public static updatePasswordMe( - data: UsersUpdatePasswordMeData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "PATCH", - url: "/api/v1/users/me/password", - body: data.requestBody, - mediaType: "application/json", - errors: { - 422: "Validation Error", - }, - }) - } - - /** - * Register User - * Create new user without the need to be logged in. - * @param data The data for the request. - * @param data.requestBody - * @returns UserPublic Successful Response - * @throws ApiError - */ - public static registerUser( - data: UsersRegisterUserData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/users/signup", - body: data.requestBody, - mediaType: "application/json", - errors: { - 422: "Validation Error", - }, - }) - } - - /** - * Read User By Id - * Get a specific user by id. - * @param data The data for the request. - * @param data.userId - * @returns UserPublic Successful Response - * @throws ApiError - */ - public static readUserById( - data: UsersReadUserByIdData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "GET", - url: "/api/v1/users/{user_id}", - path: { - user_id: data.userId, - }, - errors: { - 422: "Validation Error", - }, - }) - } - - /** - * Update User - * Update a user. - * @param data The data for the request. - * @param data.userId - * @param data.requestBody - * @returns UserPublic Successful Response - * @throws ApiError - */ - public static updateUser( - data: UsersUpdateUserData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "PATCH", - url: "/api/v1/users/{user_id}", - path: { - user_id: data.userId, - }, - body: data.requestBody, - mediaType: "application/json", - errors: { - 422: "Validation Error", - }, - }) - } +export class TrainingService { + /** + * Send Training Message + * Send a training message for an AI soul. + * Only trainers and admins can send training messages. + * @param data The data for the request. + * @param data.aiSoulId + * @param data.requestBody + * @returns TrainingMessagePublic Successful Response + * @throws ApiError + */ + public static sendTrainingMessage(data: TrainingSendTrainingMessageData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/training/{ai_soul_id}/messages', + path: { + ai_soul_id: data.aiSoulId + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Training Messages + * Get training messages for an AI soul. + * Only trainers and admins can view training messages. + * @param data The data for the request. + * @param data.aiSoulId + * @param data.skip + * @param data.limit + * @returns TrainingMessagePublic Successful Response + * @throws ApiError + */ + public static getTrainingMessages(data: TrainingGetTrainingMessagesData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/training/{ai_soul_id}/messages', + path: { + ai_soul_id: data.aiSoulId + }, + query: { + skip: data.skip, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Upload Training Document + * Upload a training document for an AI soul. + * Only trainers and admins can upload training documents. + * @param data The data for the request. + * @param data.aiSoulId + * @param data.formData + * @returns TrainingDocumentPublic Successful Response + * @throws ApiError + */ + public static uploadTrainingDocument(data: TrainingUploadTrainingDocumentData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/training/{ai_soul_id}/documents', + path: { + ai_soul_id: data.aiSoulId + }, + formData: data.formData, + mediaType: 'multipart/form-data', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Get Training Documents + * Get training documents for an AI soul. + * Only trainers and admins can view training documents. + * @param data The data for the request. + * @param data.aiSoulId + * @param data.skip + * @param data.limit + * @returns TrainingDocumentPublic Successful Response + * @throws ApiError + */ + public static getTrainingDocuments(data: TrainingGetTrainingDocumentsData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/training/{ai_soul_id}/documents', + path: { + ai_soul_id: data.aiSoulId + }, + query: { + skip: data.skip, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Delete Training Document + * Delete a training document. + * Only trainers and admins can delete training documents. + * @param data The data for the request. + * @param data.aiSoulId + * @param data.documentId + * @returns unknown Successful Response + * @throws ApiError + */ + public static deleteTrainingDocument(data: TrainingDeleteTrainingDocumentData): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/training/{ai_soul_id}/documents/{document_id}', + path: { + ai_soul_id: data.aiSoulId, + document_id: data.documentId + }, + errors: { + 422: 'Validation Error' + } + }); + } + +} - /** - * Delete User - * Delete a user. - * @param data The data for the request. - * @param data.userId - * @returns Message Successful Response - * @throws ApiError - */ - public static deleteUser( - data: UsersDeleteUserData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "DELETE", - url: "/api/v1/users/{user_id}", - path: { - user_id: data.userId, - }, - errors: { - 422: "Validation Error", - }, - }) - } +export class UsersService { + /** + * Read Users + * Retrieve users. + * @param data The data for the request. + * @param data.skip + * @param data.limit + * @returns UsersPublic Successful Response + * @throws ApiError + */ + public static readUsers(data: UsersReadUsersData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/users/', + query: { + skip: data.skip, + limit: data.limit + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Read User Me + * Get current user. + * @returns UserPublic Successful Response + * @throws ApiError + */ + public static readUserMe(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/users/me' + }); + } + + /** + * Delete User Me + * Delete own user. + * @returns Message Successful Response + * @throws ApiError + */ + public static deleteUserMe(): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/users/me' + }); + } + + /** + * Update User Me + * Update own user. + * @param data The data for the request. + * @param data.requestBody + * @returns UserPublic Successful Response + * @throws ApiError + */ + public static updateUserMe(data: UsersUpdateUserMeData): CancelablePromise { + return __request(OpenAPI, { + method: 'PATCH', + url: '/api/v1/users/me', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Update Password Me + * Update own password. + * @param data The data for the request. + * @param data.requestBody + * @returns Message Successful Response + * @throws ApiError + */ + public static updatePasswordMe(data: UsersUpdatePasswordMeData): CancelablePromise { + return __request(OpenAPI, { + method: 'PATCH', + url: '/api/v1/users/me/password', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Register User + * Create new user without the need to be logged in. + * @param data The data for the request. + * @param data.requestBody + * @returns UserPublic Successful Response + * @throws ApiError + */ + public static registerUser(data: UsersRegisterUserData): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/api/v1/users/signup', + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Read User By Id + * Get a specific user by id. + * @param data The data for the request. + * @param data.userId + * @returns UserPublic Successful Response + * @throws ApiError + */ + public static readUserById(data: UsersReadUserByIdData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/users/{user_id}', + path: { + user_id: data.userId + }, + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Update User + * Update a user. + * @param data The data for the request. + * @param data.userId + * @param data.requestBody + * @returns UserPublic Successful Response + * @throws ApiError + */ + public static updateUser(data: UsersUpdateUserData): CancelablePromise { + return __request(OpenAPI, { + method: 'PATCH', + url: '/api/v1/users/{user_id}', + path: { + user_id: data.userId + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 422: 'Validation Error' + } + }); + } + + /** + * Delete User + * Delete a user. + * @param data The data for the request. + * @param data.userId + * @returns Message Successful Response + * @throws ApiError + */ + public static deleteUser(data: UsersDeleteUserData): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/users/{user_id}', + path: { + user_id: data.userId + }, + errors: { + 422: 'Validation Error' + } + }); + } + } export class UtilsService { - /** - * Test Email - * Test emails. - * @param data The data for the request. - * @param data.emailTo - * @returns Message Successful Response - * @throws ApiError - */ - public static testEmail( - data: UtilsTestEmailData, - ): CancelablePromise { - return __request(OpenAPI, { - method: "POST", - url: "/api/v1/utils/test-email/", - query: { - email_to: data.emailTo, - }, - errors: { - 422: "Validation Error", - }, - }) - } - - /** - * Health Check - * @returns boolean Successful Response - * @throws ApiError - */ - public static healthCheck(): CancelablePromise { - return __request(OpenAPI, { - method: "GET", - url: "/api/v1/utils/health-check/", - }) - } -} + /** + * Health Check + * Health check endpoint to verify the service is running. + * @returns unknown Successful Response + * @throws ApiError + */ + public static healthCheck(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/utils/health-check/' + }); + } + + /** + * Get System Health + * Get comprehensive system health metrics. + * Only admins can access system health data. + * @returns unknown Successful Response + * @throws ApiError + */ + public static getSystemHealth(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v1/utils/system-health/' + }); + } + +} \ No newline at end of file diff --git a/frontend/src/client/types.gen.ts b/frontend/src/client/types.gen.ts index 67d4abd286..8fde17c5ec 100644 --- a/frontend/src/client/types.gen.ts +++ b/frontend/src/client/types.gen.ts @@ -1,234 +1,850 @@ // This file is auto-generated by @hey-api/openapi-ts +export type AISoulEntity = { + name: string; + description?: (string | null); + persona_type: string; + specializations: string; + base_prompt: string; + is_active?: boolean; + id?: string; + user_id: string; + created_at?: string; + updated_at?: string; + last_used?: (string | null); + interaction_count?: number; +}; + +export type AISoulEntityCreate = { + name: string; + description?: (string | null); + persona_type: string; + specializations: string; + base_prompt?: (string | null); +}; + +export type AISoulEntityPublic = { + name: string; + description?: (string | null); + persona_type: string; + specializations: string; + base_prompt: string; + is_active?: boolean; + id: string; + user_id: string; + created_at: string; + updated_at: string; + last_used: (string | null); + interaction_count: number; +}; + +export type AISoulEntityUpdate = { + name?: (string | null); + description?: (string | null); + persona_type?: (string | null); + specializations?: (string | null); + base_prompt?: (string | null); + is_active?: (boolean | null); +}; + +/** + * AI Soul Entity with user-specific interaction count for role-based responses + */ +export type AISoulEntityWithUserInteraction = { + name: string; + description?: (string | null); + persona_type: string; + specializations: string; + base_prompt: string; + is_active?: boolean; + id: string; + user_id: string; + created_at: string; + updated_at: string; + last_used: (string | null); + interaction_count: number; +}; + +export type ApproveResponseRequest = { + notes?: (string | null); +}; + +export type Body_documents_search_documents = { + query: string; + limit?: number; +}; + +export type Body_documents_upload_document = { + file: (Blob | File); + description?: (string | null); +}; + export type Body_login_login_access_token = { - grant_type?: string | null - username: string - password: string - scope?: string - client_id?: string | null - client_secret?: string | null -} + grant_type?: (string | null); + username: string; + password: string; + scope?: string; + client_id?: (string | null); + client_secret?: (string | null); +}; + +export type Body_training_upload_training_document = { + file: (Blob | File); + description?: string; +}; + +export type ChatMessageCreate = { + content: string; +}; + +/** + * Response model for chat message creation containing both user and AI messages + */ +export type ChatMessagePairResponse = { + user_message: ChatMessagePublic; + ai_message: ChatMessagePublic; +}; + +export type ChatMessagePublic = { + content: string; + id: string; + user_id: string; + ai_soul_id: string; + is_from_user: boolean; + timestamp: string; + is_temporary?: boolean; +}; + +/** + * Click tracking request model. + */ +export type ClickTrackingRequest = { + search_query_id: string; + chunk_id: string; + result_position: number; + similarity_score: number; + rerank_score?: (number | null); +}; + +/** + * RAG configuration request model. + */ +export type ConfigurationRequest = { + ai_soul_id?: (string | null); + chunking_strategy?: string; + chunk_size?: number; + chunk_overlap?: number; + embedding_model?: string; + search_algorithm?: string; + similarity_threshold?: number; + max_results?: number; + enable_reranking?: boolean; +}; + +export type CounselorQueueResponse = { + queue_items: Array<{ + [key: string]: unknown; + }>; + total_count: number; + urgent_count: number; + high_priority_count: number; +}; + +export type DocumentPublic = { + filename: string; + original_filename: string; + file_size: number; + content_type: string; + description?: (string | null); + id: string; + user_id: string; + upload_timestamp: string; + processing_status: string; + chunk_count: number; +}; + +export type DocumentsPublic = { + data: Array; + count: number; +}; + +export type EscalateRequestRequest = { + escalation_reason: string; + target_counselor_id?: (string | null); +}; export type HTTPValidationError = { - detail?: Array -} + detail?: Array; +}; export type ItemCreate = { - title: string - description?: string | null -} + title: string; + description?: (string | null); +}; export type ItemPublic = { - title: string - description?: string | null - id: string - owner_id: string -} + title: string; + description?: (string | null); + id: string; + owner_id: string; +}; export type ItemsPublic = { - data: Array - count: number -} + data: Array; + count: number; +}; export type ItemUpdate = { - title?: string | null - description?: string | null -} + title?: (string | null); + description?: (string | null); +}; export type Message = { - message: string -} + message: string; +}; + +export type ModifyResponseRequest = { + modified_response: string; + notes?: (string | null); +}; export type NewPassword = { - token: string - new_password: string -} + token: string; + new_password: string; +}; + +export type PerformanceMetricsResponse = { + counselor_id: string; + period_days: number; + total_cases_reviewed: number; + approvals: number; + modifications: number; + rejections: number; + escalations: number; + approval_rate: number; + average_review_time_seconds: number; + current_queue_size: number; + cases_per_day: number; +}; export type PrivateUserCreate = { - email: string - password: string - full_name: string - is_verified?: boolean -} + email: string; + password: string; + full_name: string; + is_verified?: boolean; +}; + +/** + * Document processing request model. + */ +export type ProcessDocumentRequest = { + /** + * Document ID to process + */ + document_id: string; + /** + * Chunking strategy + */ + chunking_strategy?: (string | null); + /** + * Chunk size + */ + chunk_size?: (number | null); + /** + * Chunk overlap + */ + chunk_overlap?: (number | null); + /** + * Embedding model + */ + embedding_model?: (string | null); +}; + +/** + * Document processing response model. + */ +export type ProcessDocumentResponse = { + status: string; + chunks_created: number; + processing_time_ms: number; + embedding_model: string; + chunking_strategy: string; +}; + +export type RejectResponseRequest = { + replacement_response: string; + reason: string; +}; + +/** + * Search request model. + */ +export type SearchRequest = { + /** + * Search query + */ + query: string; + /** + * AI Soul ID for filtering + */ + ai_soul_id?: (string | null); + /** + * Additional search filters + */ + filters?: ({ + [key: string]: unknown; +} | null); + /** + * Maximum number of results + */ + limit?: number; +}; + +/** + * Search response model. + */ +export type SearchResponse = { + query: string; + results: Array<{ + [key: string]: unknown; + }>; + total_found: number; + response_time_ms: number; + search_algorithm: string; + similarity_threshold: number; + reranking_enabled: boolean; +}; export type Token = { - access_token: string - token_type?: string -} + access_token: string; + token_type?: string; +}; + +export type TrainingDocumentPublic = { + filename: string; + original_filename: string; + file_size: number; + content_type: string; + description?: (string | null); + id: string; + ai_soul_id: string; + user_id: string; + upload_timestamp: string; + processing_status: string; + chunk_count: number; +}; + +export type TrainingMessageCreate = { + content: string; + is_from_trainer?: boolean; +}; + +export type TrainingMessagePublic = { + content: string; + is_from_trainer?: boolean; + id: string; + ai_soul_id: string; + user_id: string; + timestamp: string; +}; export type UpdatePassword = { - current_password: string - new_password: string -} + current_password: string; + new_password: string; +}; export type UserCreate = { - email: string - is_active?: boolean - is_superuser?: boolean - full_name?: string | null - password: string -} + email: string; + is_active?: boolean; + is_superuser?: boolean; + full_name?: (string | null); + password: string; + role?: string; +}; export type UserPublic = { - email: string - is_active?: boolean - is_superuser?: boolean - full_name?: string | null - id: string -} + email: string; + is_active?: boolean; + is_superuser?: boolean; + full_name?: (string | null); + id: string; + role: string; + created_at: string; + updated_at: string; +}; export type UserRegister = { - email: string - password: string - full_name?: string | null -} + email: string; + password: string; + full_name?: (string | null); +}; export type UsersPublic = { - data: Array - count: number -} + data: Array; + count: number; +}; export type UserUpdate = { - email?: string | null - is_active?: boolean - is_superuser?: boolean - full_name?: string | null - password?: string | null -} + email?: (string | null); + is_active?: boolean; + is_superuser?: boolean; + full_name?: (string | null); + password?: (string | null); + role?: (string | null); +}; export type UserUpdateMe = { - full_name?: string | null - email?: string | null -} + full_name?: (string | null); + email?: (string | null); +}; export type ValidationError = { - loc: Array - msg: string - type: string -} + loc: Array<(string | number)>; + msg: string; + type: string; +}; + +export type AiSoulsCreateAiSoulData = { + requestBody: AISoulEntityCreate; +}; + +export type AiSoulsCreateAiSoulResponse = (AISoulEntityPublic); + +export type AiSoulsGetAiSoulsData = { + limit?: number; + skip?: number; +}; + +export type AiSoulsGetAiSoulsResponse = (Array); + +export type AiSoulsGetAiSoulData = { + aiSoulId: string; +}; + +export type AiSoulsGetAiSoulResponse = (AISoulEntityWithUserInteraction); + +export type AiSoulsUpdateAiSoulData = { + aiSoulId: string; + requestBody: AISoulEntityUpdate; +}; + +export type AiSoulsUpdateAiSoulResponse = (AISoulEntity); + +export type AiSoulsDeleteAiSoulData = { + aiSoulId: string; +}; + +export type AiSoulsDeleteAiSoulResponse = (unknown); + +export type ChatCreateChatMessageData = { + aiSoulId: string; + requestBody: ChatMessageCreate; +}; + +export type ChatCreateChatMessageResponse = (ChatMessagePairResponse); + +export type ChatGetChatMessagesData = { + aiSoulId: string; + limit?: number; + skip?: number; +}; + +export type ChatGetChatMessagesResponse = (Array); + +export type ChatDeleteChatMessagesData = { + aiSoulId: string; +}; + +export type ChatDeleteChatMessagesResponse = (unknown); + +export type CounselorGetCounselorQueueData = { + /** + * Maximum number of items + */ + limit?: number; + /** + * Status filter + */ + status?: string; +}; + +export type CounselorGetCounselorQueueResponse = (CounselorQueueResponse); + +export type CounselorGetOrganizationQueueData = { + /** + * Maximum number of items + */ + limit?: number; + /** + * Priority filter + */ + priority?: (string | null); + /** + * Status filter + */ + status?: string; +}; + +export type CounselorGetOrganizationQueueResponse = ({ + [key: string]: unknown; +}); + +export type CounselorApproveResponseData = { + pendingResponseId: string; + requestBody: ApproveResponseRequest; +}; + +export type CounselorApproveResponseResponse = ({ + [key: string]: unknown; +}); + +export type CounselorModifyResponseData = { + pendingResponseId: string; + requestBody: ModifyResponseRequest; +}; + +export type CounselorModifyResponseResponse = ({ + [key: string]: unknown; +}); + +export type CounselorRejectResponseData = { + pendingResponseId: string; + requestBody: RejectResponseRequest; +}; + +export type CounselorRejectResponseResponse = ({ + [key: string]: unknown; +}); + +export type CounselorEscalateCaseData = { + pendingResponseId: string; + requestBody: EscalateRequestRequest; +}; + +export type CounselorEscalateCaseResponse = ({ + [key: string]: unknown; +}); + +export type CounselorGetCounselorPerformanceData = { + /** + * Number of days to analyze + */ + days?: number; +}; + +export type CounselorGetCounselorPerformanceResponse = (PerformanceMetricsResponse); + +export type CounselorGetRecentRiskAssessmentsData = { + /** + * Number of days to look back + */ + days?: number; + /** + * Maximum number of assessments + */ + limit?: number; +}; + +export type CounselorGetRecentRiskAssessmentsResponse = ({ + [key: string]: unknown; +}); + +export type CounselorGetHighRiskConversationsData = { + /** + * Number of hours to look back + */ + hours?: number; +}; + +export type CounselorGetHighRiskConversationsResponse = ({ + [key: string]: unknown; +}); + +export type CounselorAutoApproveExpiredResponsesResponse = ({ + [key: string]: unknown; +}); + +export type CounselorListCounselorsData = { + /** + * Filter by organization + */ + organizationId?: (string | null); +}; + +export type CounselorListCounselorsResponse = ({ + [key: string]: unknown; +}); + +export type UntaggedHealthCheckResponse = ({ + [key: string]: unknown; +}); + +export type UntaggedCreateUserData = { + requestBody: PrivateUserCreate; +}; + +export type UntaggedCreateUserResponse = (UserPublic); + +export type DocumentsUploadDocumentData = { + formData: Body_documents_upload_document; +}; + +export type DocumentsUploadDocumentResponse = (DocumentPublic); + +export type DocumentsGetDocumentsData = { + limit?: number; + skip?: number; +}; + +export type DocumentsGetDocumentsResponse = (DocumentsPublic); + +export type DocumentsDeleteDocumentData = { + documentId: string; +}; + +export type DocumentsDeleteDocumentResponse = ({ + [key: string]: unknown; +}); + +export type DocumentsGetDocumentData = { + documentId: string; +}; + +export type DocumentsGetDocumentResponse = (DocumentPublic); + +export type DocumentsSearchDocumentsData = { + formData: Body_documents_search_documents; +}; + +export type DocumentsSearchDocumentsResponse = (unknown); + +export type DocumentsGetDocumentStatsResponse = (unknown); + +export type EnhancedRagSearchDocumentsData = { + requestBody: SearchRequest; +}; + +export type EnhancedRagSearchDocumentsResponse = (SearchResponse); + +export type EnhancedRagProcessDocumentData = { + requestBody: ProcessDocumentRequest; +}; + +export type EnhancedRagProcessDocumentResponse = (ProcessDocumentResponse); + +export type EnhancedRagReindexDocumentData = { + documentId: string; +}; + +export type EnhancedRagReindexDocumentResponse = (unknown); + +export type EnhancedRagDeleteDocumentIndexData = { + documentId: string; +}; + +export type EnhancedRagDeleteDocumentIndexResponse = (unknown); + +export type EnhancedRagTrackResultClickData = { + requestBody: ClickTrackingRequest; +}; + +export type EnhancedRagTrackResultClickResponse = (unknown); + +export type EnhancedRagGetSearchAnalyticsData = { + /** + * Number of days to analyze + */ + days?: number; +}; + +export type EnhancedRagGetSearchAnalyticsResponse = (unknown); + +export type EnhancedRagGetRagConfigurationData = { + /** + * AI Soul ID + */ + aiSoulId?: (string | null); +}; + +export type EnhancedRagGetRagConfigurationResponse = (unknown); + +export type EnhancedRagUpdateRagConfigurationData = { + requestBody: ConfigurationRequest; +}; + +export type EnhancedRagUpdateRagConfigurationResponse = (unknown); + +export type EnhancedRagHealthCheckResponse = (unknown); + +export type EnhancedRagGetCollectionInfoResponse = (unknown); + +export type EnhancedRagGetSearchSuggestionsData = { + limit?: number; + query: string; +}; + +export type EnhancedRagGetSearchSuggestionsResponse = (unknown); + +export type EnhancedRagBulkProcessDocumentsData = { + chunkingStrategy?: string; + requestBody: Array<(string)>; +}; + +export type EnhancedRagBulkProcessDocumentsResponse = (unknown); export type ItemsReadItemsData = { - limit?: number - skip?: number -} + limit?: number; + skip?: number; +}; -export type ItemsReadItemsResponse = ItemsPublic +export type ItemsReadItemsResponse = (ItemsPublic); export type ItemsCreateItemData = { - requestBody: ItemCreate -} + requestBody: ItemCreate; +}; -export type ItemsCreateItemResponse = ItemPublic +export type ItemsCreateItemResponse = (ItemPublic); export type ItemsReadItemData = { - id: string -} + id: string; +}; -export type ItemsReadItemResponse = ItemPublic +export type ItemsReadItemResponse = (ItemPublic); export type ItemsUpdateItemData = { - id: string - requestBody: ItemUpdate -} + id: string; + requestBody: ItemUpdate; +}; -export type ItemsUpdateItemResponse = ItemPublic +export type ItemsUpdateItemResponse = (ItemPublic); export type ItemsDeleteItemData = { - id: string -} + id: string; +}; -export type ItemsDeleteItemResponse = Message +export type ItemsDeleteItemResponse = (Message); export type LoginLoginAccessTokenData = { - formData: Body_login_login_access_token -} + formData: Body_login_login_access_token; +}; -export type LoginLoginAccessTokenResponse = Token +export type LoginLoginAccessTokenResponse = (Token); -export type LoginTestTokenResponse = UserPublic +export type LoginTestTokenResponse = (UserPublic); export type LoginRecoverPasswordData = { - email: string -} + email: string; +}; -export type LoginRecoverPasswordResponse = Message +export type LoginRecoverPasswordResponse = (Message); export type LoginResetPasswordData = { - requestBody: NewPassword -} + requestBody: NewPassword; +}; -export type LoginResetPasswordResponse = Message +export type LoginResetPasswordResponse = (Message); export type LoginRecoverPasswordHtmlContentData = { - email: string -} + email: string; +}; -export type LoginRecoverPasswordHtmlContentResponse = string +export type LoginRecoverPasswordHtmlContentResponse = (string); export type PrivateCreateUserData = { - requestBody: PrivateUserCreate -} + requestBody: PrivateUserCreate; +}; -export type PrivateCreateUserResponse = UserPublic +export type PrivateCreateUserResponse = (UserPublic); -export type UsersReadUsersData = { - limit?: number - skip?: number -} +export type TrainingSendTrainingMessageData = { + aiSoulId: string; + requestBody: TrainingMessageCreate; +}; + +export type TrainingSendTrainingMessageResponse = (TrainingMessagePublic); + +export type TrainingGetTrainingMessagesData = { + aiSoulId: string; + limit?: number; + skip?: number; +}; + +export type TrainingGetTrainingMessagesResponse = (Array); + +export type TrainingUploadTrainingDocumentData = { + aiSoulId: string; + formData: Body_training_upload_training_document; +}; -export type UsersReadUsersResponse = UsersPublic +export type TrainingUploadTrainingDocumentResponse = (TrainingDocumentPublic); -export type UsersCreateUserData = { - requestBody: UserCreate -} +export type TrainingGetTrainingDocumentsData = { + aiSoulId: string; + limit?: number; + skip?: number; +}; -export type UsersCreateUserResponse = UserPublic +export type TrainingGetTrainingDocumentsResponse = (Array); -export type UsersReadUserMeResponse = UserPublic +export type TrainingDeleteTrainingDocumentData = { + aiSoulId: string; + documentId: string; +}; -export type UsersDeleteUserMeResponse = Message +export type TrainingDeleteTrainingDocumentResponse = (unknown); + +export type UsersReadUsersData = { + limit?: number; + skip?: number; +}; + +export type UsersReadUsersResponse = (UsersPublic); + +export type UsersReadUserMeResponse = (UserPublic); + +export type UsersDeleteUserMeResponse = (Message); export type UsersUpdateUserMeData = { - requestBody: UserUpdateMe -} + requestBody: UserUpdateMe; +}; -export type UsersUpdateUserMeResponse = UserPublic +export type UsersUpdateUserMeResponse = (UserPublic); export type UsersUpdatePasswordMeData = { - requestBody: UpdatePassword -} + requestBody: UpdatePassword; +}; -export type UsersUpdatePasswordMeResponse = Message +export type UsersUpdatePasswordMeResponse = (Message); export type UsersRegisterUserData = { - requestBody: UserRegister -} + requestBody: UserRegister; +}; -export type UsersRegisterUserResponse = UserPublic +export type UsersRegisterUserResponse = (UserPublic); export type UsersReadUserByIdData = { - userId: string -} + userId: string; +}; -export type UsersReadUserByIdResponse = UserPublic +export type UsersReadUserByIdResponse = (UserPublic); export type UsersUpdateUserData = { - requestBody: UserUpdate - userId: string -} + requestBody: UserUpdate; + userId: string; +}; -export type UsersUpdateUserResponse = UserPublic +export type UsersUpdateUserResponse = (UserPublic); export type UsersDeleteUserData = { - userId: string -} - -export type UsersDeleteUserResponse = Message + userId: string; +}; -export type UtilsTestEmailData = { - emailTo: string -} +export type UsersDeleteUserResponse = (Message); -export type UtilsTestEmailResponse = Message +export type UtilsHealthCheckResponse = ({ + [key: string]: unknown; +}); -export type UtilsHealthCheckResponse = boolean +export type UtilsGetSystemHealthResponse = ({ + [key: string]: unknown; +}); \ No newline at end of file diff --git a/frontend/src/components/Admin/AddUser.tsx b/frontend/src/components/Admin/AddUser.tsx index db353a3a2c..5916e4137c 100644 --- a/frontend/src/components/Admin/AddUser.tsx +++ b/frontend/src/components/Admin/AddUser.tsx @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query" import { Controller, type SubmitHandler, useForm } from "react-hook-form" -import { type UserCreate, UsersService } from "@/client" +import { type PrivateUserCreate, DefaultService } from "@/client" import type { ApiError } from "@/client/core/ApiError" import useCustomToast from "@/hooks/useCustomToast" import { emailPattern, handleError } from "@/utils" @@ -28,41 +28,49 @@ import { } from "../ui/dialog" import { Field } from "../ui/field" -interface UserCreateForm extends UserCreate { - confirm_password: string +interface UserCreateFormData extends PrivateUserCreate { + role: string } const AddUser = () => { - const [isOpen, setIsOpen] = useState(false) const queryClient = useQueryClient() const { showSuccessToast } = useCustomToast() + const [open, setOpen] = useState(false) + const { - control, register, handleSubmit, reset, - getValues, - formState: { errors, isValid, isSubmitting }, - } = useForm({ + control, + formState: { errors, isSubmitting }, + } = useForm({ mode: "onBlur", criteriaMode: "all", defaultValues: { email: "", full_name: "", password: "", - confirm_password: "", - is_superuser: false, - is_active: false, + role: "user", + is_verified: false, }, }) const mutation = useMutation({ - mutationFn: (data: UserCreate) => - UsersService.createUser({ requestBody: data }), + mutationFn: (data: UserCreateFormData) => { + // For now, use DefaultService.untaggedCreateUser + // TODO: Implement proper role-based user creation + const userData: PrivateUserCreate = { + email: data.email, + full_name: data.full_name, + password: data.password, + is_verified: data.is_verified, + } + return DefaultService.untaggedCreateUser({ requestBody: userData }) + }, onSuccess: () => { showSuccessToast("User created successfully.") reset() - setIsOpen(false) + setOpen(false) }, onError: (err: ApiError) => { handleError(err) @@ -72,159 +80,170 @@ const AddUser = () => { }, }) - const onSubmit: SubmitHandler = (data) => { + const onSubmit: SubmitHandler = (data) => { mutation.mutate(data) } return ( - setIsOpen(open)} - > - - - - -
- - Add User - - - - Fill in the form below to add a new user to the system. - - - - - + <> + setOpen(open)} + > + + + + + + + Add User + + + Create a new user account. + + + + - - - + + + - - - + + + - - - value === getValues().password || - "The passwords do not match", - })} - placeholder="Password" - type="password" - /> - - + + ( + + )} + /> + + - - ( - - field.onChange(checked)} - > - Is superuser? - - - )} - /> - ( - - field.onChange(checked)} - > - Is active? - - - )} - /> - - + + ( + + field.onChange(checked)} + > + Is verified? + + + )} + /> + + - - + + + + - - - -
- -
-
+ + + + + + ) } +const roleOptions = [ + { label: "User", value: "user" }, + { label: "Trainer", value: "trainer" }, + { label: "Counselor", value: "counselor" }, + { label: "Admin", value: "admin" }, +] + export default AddUser diff --git a/frontend/src/components/Admin/AdvancedRAGManagement.tsx b/frontend/src/components/Admin/AdvancedRAGManagement.tsx new file mode 100644 index 0000000000..b75cf92581 --- /dev/null +++ b/frontend/src/components/Admin/AdvancedRAGManagement.tsx @@ -0,0 +1,626 @@ +import { + Badge, + Box, + Button, + Container, + Flex, + HStack, + Heading, + Input, + Spinner, + Text, + VStack, +} from "@chakra-ui/react" +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" +import React, { useState } from "react" +import { + FiActivity, + FiAlertCircle, + FiCheckCircle, + FiDatabase, + FiPlay, + FiRefreshCw, + FiSearch, + FiXCircle, +} from "react-icons/fi" + +import { + type ApiError, + type DocumentPublic, + DocumentsService, + EnhancedRagService, +} from "../../client" +import useCustomToast from "../../hooks/useCustomToast" +import { getStatusColor as getThemeStatusColor } from "../../theme/colors" +import { RoleGuard } from "../Common/RoleGuard" + +export function AdvancedRAGManagement() { + const { showSuccessToast, showErrorToast } = useCustomToast() + const queryClient = useQueryClient() + const [activeTab, setActiveTab] = useState("bulk-processing") + const [selectedDocuments, setSelectedDocuments] = useState([]) + const [searchQuery, setSearchQuery] = useState("") + + // Get all documents for bulk processing + const { data: documents, isLoading: documentsLoading } = useQuery({ + queryKey: ["documents"], + queryFn: () => DocumentsService.getDocuments(), + }) + + // Get system health status + const { + data: healthStatus, + isLoading: healthLoading, + refetch: refetchHealth, + } = useQuery({ + queryKey: ["rag-health"], + queryFn: () => EnhancedRagService.healthCheck(), + }) + + // Get collection info + const { + data: collectionInfo, + isLoading: collectionLoading, + refetch: refetchCollection, + } = useQuery({ + queryKey: ["collection-info"], + queryFn: () => EnhancedRagService.getCollectionInfo(), + }) + + // Get search suggestions + const { + data: searchSuggestions, + isLoading: suggestionsLoading, + refetch: refetchSuggestions, + } = useQuery({ + queryKey: ["search-suggestions", searchQuery], + queryFn: () => + EnhancedRagService.getSearchSuggestions({ + query: searchQuery, + limit: 20, + }), + enabled: searchQuery.length >= 2, + }) + + // Bulk process documents mutation + const bulkProcessMutation = useMutation({ + mutationFn: (documentIds: string[]) => + EnhancedRagService.bulkProcessDocuments({ + requestBody: documentIds, + chunkingStrategy: "semantic", + }), + onSuccess: (data: any) => { + showSuccessToast( + `Successfully processed ${data.total_documents} documents`, + ) + queryClient.invalidateQueries({ queryKey: ["documents"] }) + queryClient.invalidateQueries({ queryKey: ["collection-info"] }) + setSelectedDocuments([]) + }, + onError: (err: ApiError) => { + const errDetail = (err.body as any)?.detail + showErrorToast(`Failed to process documents: ${errDetail}`) + }, + }) + + const handleDocumentSelection = (documentId: string) => { + setSelectedDocuments((prev) => + prev.includes(documentId) + ? prev.filter((id) => id !== documentId) + : [...prev, documentId], + ) + } + + const handleSelectAll = () => { + if (!documents?.data) return + + if (selectedDocuments.length === documents.data.length) { + setSelectedDocuments([]) + } else { + setSelectedDocuments(documents.data.map((doc) => doc.id)) + } + } + + const handleBulkProcess = () => { + if (selectedDocuments.length === 0) { + showErrorToast("Please select documents to process") + return + } + bulkProcessMutation.mutate(selectedDocuments) + } + + const getStatusColor = (status: string) => { + return getThemeStatusColor(status) + } + + const getStatusIcon = (status: string) => { + switch (status?.toLowerCase()) { + case "healthy": + case "ok": + case "completed": + case "processed": + return + case "degraded": + case "warning": + case "processing": + return + case "unhealthy": + case "error": + case "failed": + return + default: + return + } + } + + const formatBytes = (bytes: number) => { + if (bytes === 0) return "0 Bytes" + const k = 1024 + const sizes = ["Bytes", "KB", "MB", "GB", "TB"] + const i = Math.floor(Math.log(bytes) / Math.log(k)) + return `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}` + } + + const formatNumber = (num: number) => { + return new Intl.NumberFormat().format(num) + } + + return ( + + + + + Advanced RAG Management + + + + {/* Tab Navigation */} + + + + + + + {/* Bulk Processing Tab */} + {activeTab === "bulk-processing" && ( + + + + + Document Processing + + + + {documentsLoading ? ( + + + + ) : ( + + {documents?.data?.map((doc: DocumentPublic) => ( + + + + handleDocumentSelection(doc.id)} + /> + + + {doc.original_filename} + + {doc.description && ( + + {doc.description} + + )} + + + + + {doc.processing_status} + + + {formatBytes(doc.file_size)} + + + {doc.chunk_count || 0} chunks + + + + + ))} + + )} + + + + + + + + )} + + {/* System Health Tab */} + {activeTab === "health" && ( + + {healthLoading ? ( + + + + ) : healthStatus && + typeof healthStatus === "object" && + "status" in healthStatus ? ( + + + + + {getStatusIcon((healthStatus as any).status)} + + System Status + + {( + (healthStatus as any).status || "unknown" + ).toUpperCase()} + + + + + {(healthStatus as any).components && + Object.entries((healthStatus as any).components).map( + ([component, status]) => ( + + + + + {getStatusIcon((status as any).status)} + + + {component} + + + + + {(status as any).status} + + {(status as any).response_time_ms && ( + + {(status as any).response_time_ms}ms + + )} + + + + ), + )} + + + + Last updated:{" "} + {(healthStatus as any).timestamp + ? new Date( + (healthStatus as any).timestamp, + ).toLocaleString() + : "Unknown"} + + + + ) : ( + + + + Unable to fetch system health! + + + There was an error retrieving system health information. + + + + )} + + {/* Collection Info */} + {collectionLoading ? ( + + + + ) : collectionInfo && typeof collectionInfo === "object" ? ( + + + Vector Database + + + + + Total Vectors + + + {formatNumber( + (collectionInfo as any).total_vectors || 0, + )} + + + + + Total Points + + + {formatNumber( + (collectionInfo as any).total_points || 0, + )} + + + + + Disk Usage + + + {formatBytes( + (collectionInfo as any).total_disk_size || 0, + )} + + + + + RAM Usage + + + {formatBytes( + (collectionInfo as any).total_ram_size || 0, + )} + + + + + + Collections + {(collectionInfo as any).collections && + Array.isArray((collectionInfo as any).collections) && + (collectionInfo as any).collections.map( + (collection: any) => ( + + + + {collection.name} + + + + Vectors:{" "} + {formatNumber( + collection.vectors_count || 0, + )} + + + Points:{" "} + {formatNumber(collection.points_count || 0)} + + + Disk:{" "} + {formatBytes( + collection.disk_data_size || 0, + )} + + + RAM:{" "} + {formatBytes(collection.ram_data_size || 0)} + + + + + ), + )} + + + + ) : ( + + + + Unable to fetch collection info! + + + There was an error retrieving vector database information. + + + + )} + + )} + + {/* Search Analytics Tab */} + {activeTab === "analytics" && ( + + + + Search Suggestions + + Analyze and manage popular search queries + + + + Search Query + setSearchQuery(e.target.value)} + /> + + + {searchQuery.length >= 2 && ( + + + Popular Suggestions + + {suggestionsLoading ? ( + + ) : searchSuggestions && + typeof searchSuggestions === "object" && + "suggestions" in searchSuggestions && + Array.isArray((searchSuggestions as any).suggestions) && + (searchSuggestions as any).suggestions.length > 0 ? ( + + {(searchSuggestions as any).suggestions.map( + (suggestion: any, index: number) => ( + + + {suggestion.text} + + {suggestion.count} searches + + + + ), + )} + + ) : ( + No suggestions found + )} + + )} + + + + )} + + + + ) +} diff --git a/frontend/src/components/Common/Navbar.tsx b/frontend/src/components/Common/Navbar.tsx index 7e952e005e..ec49bc22d6 100644 --- a/frontend/src/components/Common/Navbar.tsx +++ b/frontend/src/components/Common/Navbar.tsx @@ -1,32 +1,55 @@ -import { Flex, Image, useBreakpointValue } from "@chakra-ui/react" -import { Link } from "@tanstack/react-router" +import { + Box, + Container, + Flex, + HStack, + Image, + Link, + Text, +} from "@chakra-ui/react" +import { Link as RouterLink } from "@tanstack/react-router" -import Logo from "/assets/images/fastapi-logo.svg" import UserMenu from "./UserMenu" -function Navbar() { - const display = useBreakpointValue({ base: "none", md: "flex" }) - +export default function Navbar() { return ( - - - Logo - - - - - + + + + + + + Logo + + + + + + + + + ) } - -export default Navbar diff --git a/frontend/src/components/Common/RoleGuard.tsx b/frontend/src/components/Common/RoleGuard.tsx new file mode 100644 index 0000000000..f306c4f726 --- /dev/null +++ b/frontend/src/components/Common/RoleGuard.tsx @@ -0,0 +1,114 @@ +import { Box, Heading, Text, VStack } from "@chakra-ui/react" +import type React from "react" +import { FiLock } from "react-icons/fi" + +import useAuth from "../../hooks/useAuth" +import { + getRoleDisplayName, + getUserRole, + hasPermission, +} from "../../utils/roles" + +interface RoleGuardProps { + permission: string + children: React.ReactNode + fallback?: React.ReactNode +} + +/** + * Component that conditionally renders children based on user permissions + */ +export const RoleGuard: React.FC = ({ + permission, + children, + fallback, +}) => { + const { user } = useAuth() + + if (!hasPermission(user || null, permission)) { + if (fallback) { + return <>{fallback} + } + + const userRole = getUserRole(user || null) + + return ( + + + + + Access Denied + + + You don't have permission to access this feature. + + + Current role: {getRoleDisplayName(userRole)} + + + Required permission: {permission} + + + + ) + } + + return <>{children} +} + +interface RouteGuardProps { + route: string + children: React.ReactNode +} + +/** + * Component that guards entire routes based on user role + */ +export const RouteGuard: React.FC = ({ route, children }) => { + const { user } = useAuth() + + // For route guards, we'll use the canAccessRoute function + // For now, let's implement a simple version + const canAccess = hasPermission(user || null, getRoutePermission(route)) + + if (!canAccess) { + const userRole = getUserRole(user || null) + + return ( + + + + + Access Denied + + + You don't have permission to access this page. + + + Current role: {getRoleDisplayName(userRole)} + + + + ) + } + + return <>{children} +} + +/** + * Helper function to map routes to permissions + */ +function getRoutePermission(route: string): string { + switch (route) { + case "/admin": + return "manage_users" + case "/training": + return "access_training" + case "/documents": + return "access_documents" + case "/counselor": + return "access_counselor_queue" + default: + return "chat_with_souls" + } +} diff --git a/frontend/src/components/Common/Sidebar.tsx b/frontend/src/components/Common/Sidebar.tsx index 8437634f47..17cfc6e9d7 100644 --- a/frontend/src/components/Common/Sidebar.tsx +++ b/frontend/src/components/Common/Sidebar.tsx @@ -1,97 +1,27 @@ -import { Box, Flex, IconButton, Text } from "@chakra-ui/react" -import { useQueryClient } from "@tanstack/react-query" -import { useState } from "react" -import { FaBars } from "react-icons/fa" -import { FiLogOut } from "react-icons/fi" - -import type { UserPublic } from "@/client" -import useAuth from "@/hooks/useAuth" -import { - DrawerBackdrop, - DrawerBody, - DrawerCloseTrigger, - DrawerContent, - DrawerRoot, - DrawerTrigger, -} from "../ui/drawer" +import { Box, VStack } from "@chakra-ui/react" import SidebarItems from "./SidebarItems" -const Sidebar = () => { - const queryClient = useQueryClient() - const currentUser = queryClient.getQueryData(["currentUser"]) - const { logout } = useAuth() - const [open, setOpen] = useState(false) - +export default function Sidebar() { return ( - <> - {/* Mobile */} - setOpen(e.open)} - > - - - - - - - - - - - - setOpen(false)} /> - { - logout() - }} - alignItems="center" - gap={4} - px={4} - py={2} - > - - Log Out - - - {currentUser?.email && ( - - Logged in as: {currentUser.email} - - )} - - - - - - - {/* Desktop */} - - - - - - - + + + + + ) } - -export default Sidebar diff --git a/frontend/src/components/Common/SidebarItems.tsx b/frontend/src/components/Common/SidebarItems.tsx index 13f71495f5..f3405a3d36 100644 --- a/frontend/src/components/Common/SidebarItems.tsx +++ b/frontend/src/components/Common/SidebarItems.tsx @@ -1,48 +1,179 @@ -import { Box, Flex, Icon, Text } from "@chakra-ui/react" -import { useQueryClient } from "@tanstack/react-query" +import { Box, Flex, Icon, Text, Badge } from "@chakra-ui/react" import { Link as RouterLink } from "@tanstack/react-router" -import { FiBriefcase, FiHome, FiSettings, FiUsers } from "react-icons/fi" +import { + FiCpu, + FiHome, + FiSettings, + FiUsers, + FiShield, +} from "react-icons/fi" import type { IconType } from "react-icons/lib" -import type { UserPublic } from "@/client" +import useAuth from "../../hooks/useAuth" +import { + getRoleDisplayName, + getUserRole, + hasPermission, + UserRole, +} from "../../utils/roles" -const items = [ - { icon: FiHome, title: "Dashboard", path: "/" }, - { icon: FiBriefcase, title: "Items", path: "/items" }, - { icon: FiSettings, title: "User Settings", path: "/settings" }, +// Core navigation items for admin, counselor, and trainer +const coreItems = [ + { + icon: FiHome, + title: "Dashboard", + path: "/", + permission: "chat_with_souls", + roles: [UserRole.ADMIN, UserRole.COUNSELOR, UserRole.TRAINER], // Exclude regular users + }, + { + icon: FiCpu, + title: "AI Souls", + path: "/ai-souls", + permission: "chat_with_souls", + roles: [], // Available to all users + }, ] -interface SidebarItemsProps { - onClose?: () => void -} +// Content management items (temporarily hidden) +const contentItems: Item[] = [ + // { + // icon: FiUpload, + // title: "Documents", + // path: "/documents", + // permission: "access_documents", + // roles: [], + // }, +] + +// Counselor items +const counselorItems = [ + { + icon: FiShield, + title: "Counselor Dashboard", + path: "/counselor", + permission: "access_counselor_queue", + roles: [UserRole.COUNSELOR, UserRole.ADMIN], + }, +] + +// Admin-only items (Advanced RAG temporarily hidden) +const adminItems: Item[] = [ + { icon: FiUsers, title: "Admin", path: "/admin", permission: "manage_users", roles: [UserRole.ADMIN] }, + // { + // icon: FiDatabase, + // title: "Advanced RAG", + // path: "/advanced-rag", + // permission: "admin", + // roles: [UserRole.ADMIN], + // }, +] + +// Settings (always last) +const settingsItems = [ + { + icon: FiSettings, + title: "Settings", + path: "/settings", + permission: "chat_with_souls", + roles: [], // Available to all users + }, +] interface Item { icon: IconType title: string path: string + permission: string + roles?: UserRole[] // If empty, available to all roles +} + +interface SidebarItemsProps { + onClose?: () => void } const SidebarItems = ({ onClose }: SidebarItemsProps) => { - const queryClient = useQueryClient() - const currentUser = queryClient.getQueryData(["currentUser"]) + const { user } = useAuth() + + // Get all items that the user has permission to access + const getAccessibleItems = (): Item[] => { + let items: Item[] = [] + + if (user) { + const userRole = getUserRole(user) + + // Filter core items based on user role + const filteredCoreItems = coreItems.filter(item => + item.roles.length === 0 || item.roles.includes(userRole) + ) + + if (userRole === UserRole.ADMIN || user.is_superuser) { + items = [...filteredCoreItems, ...contentItems, ...counselorItems, ...adminItems, ...settingsItems] + } else if (userRole === UserRole.COUNSELOR) { + items = [...filteredCoreItems, ...counselorItems, ...settingsItems] + } else if (userRole === UserRole.TRAINER) { + items = [...filteredCoreItems, ...contentItems, ...settingsItems] + } else { + // Regular users only get filtered core items + settings + items = [...filteredCoreItems, ...settingsItems] + } + } + + // Filter by permissions as a backup, but for admin users, show all items + if (user?.is_superuser) { + return items // Skip permission filtering for superusers + } + + return items.filter((item) => + hasPermission(user || null, item.permission), + ) + } - const finalItems: Item[] = currentUser?.is_superuser - ? [...items, { icon: FiUsers, title: "Admin", path: "/admin" }] - : items + const finalItems = getAccessibleItems() + const userRole = getUserRole(user || null) + const isNonAdminUser = userRole === UserRole.USER + + const getRoleSpecificMessage = () => { + switch (userRole) { + case UserRole.ADMIN: + return "Full system access" + case UserRole.COUNSELOR: + return "Review & safety monitoring" + case UserRole.TRAINER: + return "AI training & development" + case UserRole.USER: + return "Chat with AI companions" + default: + return "Limited access" + } + } const listItems = finalItems.map(({ icon, title, path }) => ( - + {title} @@ -50,10 +181,71 @@ const SidebarItems = ({ onClose }: SidebarItemsProps) => { return ( <> - - Menu + + Navigation {listItems} + + {user && ( + + + Current User + + + {user.full_name || user.email} + + + + {getRoleDisplayName(userRole)} + + {user.is_superuser && ( + + Superuser + + )} + + + {getRoleSpecificMessage()} + + + )} ) } diff --git a/frontend/src/components/Common/UserMenu.tsx b/frontend/src/components/Common/UserMenu.tsx index 5f2b26ad44..7eb50bafc8 100644 --- a/frontend/src/components/Common/UserMenu.tsx +++ b/frontend/src/components/Common/UserMenu.tsx @@ -1,53 +1,196 @@ -import { Box, Button, Flex, Text } from "@chakra-ui/react" +import { Badge, Box, Button, Flex, HStack, Text, VStack } from "@chakra-ui/react" import { Link } from "@tanstack/react-router" import { FaUserAstronaut } from "react-icons/fa" -import { FiLogOut, FiUser } from "react-icons/fi" +import { FiLogOut, FiUser, FiSettings } from "react-icons/fi" import useAuth from "@/hooks/useAuth" +import { + getRoleColor, + getRoleDisplayName, + getUserRole, +} from "../../utils/roles" import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from "../ui/menu" const UserMenu = () => { const { user, logout } = useAuth() + const userRole = getUserRole(user || null) + const roleDisplayName = getRoleDisplayName(userRole) + const roleColor = getRoleColor(userRole) const handleLogout = async () => { logout() } + // Get user initials for avatar + const getInitials = (name: string) => { + return name + .split(' ') + .map(word => word.charAt(0)) + .join('') + .toUpperCase() + .slice(0, 2) + } + + // Custom Avatar Component + const CustomAvatar = ({ name, size = "sm", ...props }: { name: string; size?: string; [key: string]: any }) => { + const initials = getInitials(name) + const sizeMap = { + sm: { w: "32px", h: "32px", fontSize: "xs" }, + md: { w: "40px", h: "40px", fontSize: "sm" } + } + const avatarSize = sizeMap[size as keyof typeof sizeMap] || sizeMap.sm + + return ( + + {initials} + + ) + } + return ( <> {/* Desktop */} - - - - + + {/* User Info Header */} + + + + + + {user?.full_name || "User"} + + + {user?.email} + + + {roleDisplayName} + + + + + + - - My Profile + + + Settings + - - Log Out + + + Sign Out + diff --git a/frontend/src/components/Search/EnhancedSearch.tsx b/frontend/src/components/Search/EnhancedSearch.tsx new file mode 100644 index 0000000000..d5ea5eebc8 --- /dev/null +++ b/frontend/src/components/Search/EnhancedSearch.tsx @@ -0,0 +1,422 @@ +import { + Badge, + Box, + Button, + Flex, + HStack, + Heading, + Input, + Spinner, + Text, + VStack, +} from "@chakra-ui/react" +import { useMutation, useQuery } from "@tanstack/react-query" +import type React from "react" +import { useEffect, useRef, useState } from "react" +import { FiClock, FiFileText, FiSearch, FiTrendingUp } from "react-icons/fi" + +import { EnhancedRagService, type SearchRequest } from "../../client" +import useCustomToast from "../../hooks/useCustomToast" + +interface EnhancedSearchProps { + aiSoulId?: string + onResultClick?: (result: any) => void + placeholder?: string + autoFocus?: boolean +} + +export const EnhancedSearch: React.FC = ({ + aiSoulId, + onResultClick, + placeholder = "Search your documents...", + autoFocus = false, +}) => { + const [query, setQuery] = useState("") + const [showSuggestions, setShowSuggestions] = useState(false) + const [selectedSuggestionIndex, setSelectedSuggestionIndex] = useState(-1) + const inputRef = useRef(null) + const suggestionsRef = useRef(null) + const { showErrorToast } = useCustomToast() + + // Get search suggestions + const { data: suggestions, isLoading: suggestionsLoading } = useQuery({ + queryKey: ["search-suggestions", query], + queryFn: () => EnhancedRagService.getSearchSuggestions({ query, limit: 5 }), + enabled: query.length > 2, // Only fetch suggestions for queries longer than 2 characters + staleTime: 1000 * 60 * 5, // Cache suggestions for 5 minutes + }) + + // Search mutation + const searchMutation = useMutation({ + mutationFn: async (searchRequest: SearchRequest) => { + return EnhancedRagService.searchDocuments({ requestBody: searchRequest }) + }, + onError: (error: any) => { + showErrorToast(`Search failed: ${error.message}`) + }, + }) + + // Handle search submission + const handleSearch = async () => { + if (!query.trim()) return + + const searchRequest: SearchRequest = { + query: query.trim(), + ai_soul_id: aiSoulId, + filters: {}, + limit: 10, + } + + searchMutation.mutate(searchRequest) + } + + // Handle input change + const handleInputChange = (e: React.ChangeEvent) => { + const value = e.target.value + setQuery(value) + setShowSuggestions(value.length > 2) + setSelectedSuggestionIndex(-1) + } + + // Handle input focus + const handleInputFocus = () => { + if (query.length > 2) { + setShowSuggestions(true) + } + } + + // Handle input blur + const handleInputBlur = () => { + // Delay hiding suggestions to allow for clicks + setTimeout(() => { + setShowSuggestions(false) + }, 200) + } + + // Handle key navigation + const handleKeyPress = (e: React.KeyboardEvent) => { + if (!showSuggestions) { + if (e.key === "Enter") { + handleSearch() + } + return + } + + const suggestionsList = Array.isArray(suggestions) ? suggestions : [] + + switch (e.key) { + case "ArrowDown": + e.preventDefault() + setSelectedSuggestionIndex((prev) => + prev < suggestionsList.length - 1 ? prev + 1 : prev, + ) + break + case "ArrowUp": + e.preventDefault() + setSelectedSuggestionIndex((prev) => (prev > 0 ? prev - 1 : -1)) + break + case "Enter": + e.preventDefault() + if ( + selectedSuggestionIndex >= 0 && + suggestionsList[selectedSuggestionIndex] + ) { + handleSuggestionClick(suggestionsList[selectedSuggestionIndex]) + } else { + handleSearch() + } + break + case "Escape": + setShowSuggestions(false) + setSelectedSuggestionIndex(-1) + break + } + } + + // Handle suggestion click + const handleSuggestionClick = (suggestion: any) => { + const suggestionText = + typeof suggestion === "string" + ? suggestion + : suggestion.query || suggestion.text || "" + setQuery(suggestionText) + setShowSuggestions(false) + setSelectedSuggestionIndex(-1) + + // Auto-search when selecting a suggestion + const searchRequest: SearchRequest = { + query: suggestionText, + ai_soul_id: aiSoulId, + filters: {}, + limit: 10, + } + searchMutation.mutate(searchRequest) + } + + // Close suggestions when clicking outside + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if ( + suggestionsRef.current && + !suggestionsRef.current.contains(event.target as Node) && + inputRef.current && + !inputRef.current.contains(event.target as Node) + ) { + setShowSuggestions(false) + } + } + + document.addEventListener("mousedown", handleClickOutside) + return () => { + document.removeEventListener("mousedown", handleClickOutside) + } + }, []) + + // Handle result click + const handleResultClick = (result: any) => { + // Track the click for analytics + EnhancedRagService.trackResultClick({ + requestBody: { + search_query_id: searchMutation.data?.query || "", + chunk_id: result.chunk_id, + result_position: 0, + similarity_score: result.similarity_score, + }, + }).catch(console.error) + + onResultClick?.(result) + } + + const searchResults = searchMutation.data + const isLoading = searchMutation.isPending + + return ( + + {/* Search Header */} + + Enhanced Document Search + + Search through your documents with AI-powered semantic understanding + + + + {/* Search Input with Suggestions */} + + + + {/* Suggestions Dropdown */} + {showSuggestions && ( + + {suggestionsLoading ? ( + + + + Loading suggestions... + + + ) : ( + + {Array.isArray(suggestions) && suggestions.length > 0 ? ( + suggestions.map((suggestion: any, index: number) => { + const suggestionText = + typeof suggestion === "string" + ? suggestion + : suggestion.query || suggestion.text || "No text" + + return ( + handleSuggestionClick(suggestion)} + borderBottom={ + index < suggestions.length - 1 ? "1px" : "none" + } + borderColor="gray.100" + > + + + {suggestionText} + + + ) + }) + ) : ( + + + No suggestions found + + + )} + + )} + + )} + + + {/* Search Controls */} + + + + {/* Search Stats */} + {searchResults && ( + + + + {searchResults.total_found} results + + + + {searchResults.response_time_ms}ms + + + {searchResults.search_algorithm} + + + )} + + + {/* Loading State */} + {isLoading && ( + + + + Searching your documents... + + + )} + + {/* Search Results */} + {searchResults && + !isLoading && + searchResults.results && + searchResults.results.length > 0 && ( + + Search Results + {searchResults.results.map((result: any, index: number) => ( + handleResultClick(result)} + _hover={{ + bg: "gray.50", + borderColor: "blue.300", + }} + > + + + + Score:{" "} + {result.similarity_score + ? (result.similarity_score * 100).toFixed(1) + : "N/A"} + % + + + Chunk {result.chunk_index || index} + + + + {result.content || "No content available"} + + {result.document_id && ( + + Document ID: {result.document_id} + + )} + + + ))} + + )} + + {/* No Results */} + {searchResults && + !isLoading && + searchResults.results && + searchResults.results.length === 0 && ( + + + + + + No results found + + + Try adjusting your search terms or check your documents + + + + + )} + + {/* Empty State */} + {!searchResults && !isLoading && !query && ( + + + + + + Ready to search + + + Enter your search query and press Enter or click Search + + + + + )} + + ) +} diff --git a/frontend/src/components/Search/SearchAnalytics.tsx b/frontend/src/components/Search/SearchAnalytics.tsx new file mode 100644 index 0000000000..c30663b011 --- /dev/null +++ b/frontend/src/components/Search/SearchAnalytics.tsx @@ -0,0 +1,394 @@ +import { + Badge, + Box, + Button, + Flex, + Grid, + HStack, + Heading, + Select, + Text, + VStack, +} from "@chakra-ui/react" +import { useQuery } from "@tanstack/react-query" +import type React from "react" +import { useState } from "react" +import { FiClock, FiEye, FiSearch, FiTrendingUp } from "react-icons/fi" + +import { EnhancedRagService } from "../../client" + +interface AnalyticsData { + total_searches: number + avg_response_time: number + popular_queries: Array<{ + query: string + count: number + avg_response_time: number + }> + click_through_rate: number + search_trends: Array<{ + date: string + searches: number + avg_response_time: number + }> +} + +const SearchAnalytics: React.FC = () => { + const [timeRange, setTimeRange] = useState(7) // Default to 7 days + + // Get search analytics data + const { + data: analyticsData, + isLoading, + error, + } = useQuery({ + queryKey: ["search-analytics", timeRange], + queryFn: () => EnhancedRagService.getSearchAnalytics({ days: timeRange }), + }) + + if (isLoading) { + return ( + + Loading analytics data... + + ) + } + + if (error) { + return ( + + Failed to load analytics data + + ) + } + + // Since the API returns unknown, we'll mock some data structure + const mockData: AnalyticsData = { + total_searches: 1247, + avg_response_time: 342, + popular_queries: [ + { + query: "machine learning algorithms", + count: 45, + avg_response_time: 298, + }, + { + query: "data preprocessing techniques", + count: 38, + avg_response_time: 412, + }, + { + query: "neural network architectures", + count: 32, + avg_response_time: 356, + }, + { query: "deep learning frameworks", count: 28, avg_response_time: 387 }, + { + query: "computer vision applications", + count: 24, + avg_response_time: 423, + }, + ], + click_through_rate: 0.68, + search_trends: [ + { date: "2024-01-01", searches: 156, avg_response_time: 334 }, + { date: "2024-01-02", searches: 189, avg_response_time: 298 }, + { date: "2024-01-03", searches: 167, avg_response_time: 387 }, + { date: "2024-01-04", searches: 143, avg_response_time: 412 }, + { date: "2024-01-05", searches: 198, avg_response_time: 356 }, + { date: "2024-01-06", searches: 176, avg_response_time: 298 }, + { date: "2024-01-07", searches: 218, avg_response_time: 334 }, + ], + } + + const data = + (analyticsData && typeof analyticsData === "object" + ? (analyticsData as AnalyticsData) + : null) || mockData + + return ( + + + {/* Header */} + + Search Analytics + + + + {/* Key Metrics */} + + + + + + + Total Searches + + + + {data.total_searches?.toLocaleString() || "N/A"} + + + + + + + + + + Avg Response Time + + + + {data.avg_response_time ? `${data.avg_response_time}ms` : "N/A"} + + + + + + + + + + Click-Through Rate + + + + {data.click_through_rate + ? `${(data.click_through_rate * 100).toFixed(1)}%` + : "N/A"} + + + + + + + + + + Avg Daily Searches + + + + {data.search_trends + ? Math.round( + data.search_trends.reduce( + (sum, day) => sum + day.searches, + 0, + ) / data.search_trends.length, + ) + : "N/A"} + + + + + + {/* Popular Queries */} + + + Popular Search Queries + {data.popular_queries && data.popular_queries.length > 0 ? ( + + {data.popular_queries.map((query, index) => ( + + + {query.query} + + {query.count} searches • {query.avg_response_time}ms avg + + + + #{index + 1} + + + ))} + + ) : ( + No search data available + )} + + + + {/* Search Trends */} + + + Search Trends + {data.search_trends && data.search_trends.length > 0 ? ( + + {data.search_trends.map((trend, index) => ( + + + {new Date(trend.date).toLocaleDateString()} + + + + {trend.searches} searches + + + {trend.avg_response_time}ms avg + + + + ))} + + ) : ( + No trend data available + )} + + + + {/* Performance Insights */} + + + Performance Insights + + + Search Performance + + {data.avg_response_time < 500 + ? "Excellent" + : data.avg_response_time < 1000 + ? "Good" + : "Needs Improvement"} + + + + User Engagement + 0.6 + ? "green" + : data.click_through_rate > 0.3 + ? "orange" + : "red" + } + variant="subtle" + > + {data.click_through_rate > 0.6 + ? "High" + : data.click_through_rate > 0.3 + ? "Medium" + : "Low"} + + + + Search Volume + 1000 + ? "green" + : data.total_searches > 500 + ? "orange" + : "red" + } + variant="subtle" + > + {data.total_searches > 1000 + ? "High" + : data.total_searches > 500 + ? "Medium" + : "Low"} + + + + + + + + ) +} + +export default SearchAnalytics diff --git a/frontend/src/components/Training/TrainingDocumentsManagement.tsx b/frontend/src/components/Training/TrainingDocumentsManagement.tsx new file mode 100644 index 0000000000..67f8ffc829 --- /dev/null +++ b/frontend/src/components/Training/TrainingDocumentsManagement.tsx @@ -0,0 +1,457 @@ +import { + Badge, + Box, + Button, + Container, + Flex, + Grid, + HStack, + Heading, + Icon, + Input, + Text, + VStack, +} from "@chakra-ui/react" +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" +import { useState, useRef } from "react" +import { + FiActivity, + FiFileText, + FiMessageSquare, + FiTrash2, + FiUpload, +} from "react-icons/fi" + +import { + type AISoulEntity, + type ApiError, + AiSoulsService, + TrainingService, +} from "../../client" +import { RoleGuard } from "../Common/RoleGuard" +import useCustomToast from "../../hooks/useCustomToast" + +export function TrainingDocumentsManagement() { + const { showSuccessToast, showErrorToast } = useCustomToast() + const queryClient = useQueryClient() + const [selectedSoul, setSelectedSoul] = useState(null) + const [selectedFile, setSelectedFile] = useState(null) + const [isUploadingFile, setIsUploadingFile] = useState(false) + const [uploadProgress, setUploadProgress] = useState(0) + const fileInputRef = useRef(null) + + // Get user's AI souls + const { data: aiSouls } = useQuery({ + queryKey: ["ai-souls"], + queryFn: () => AiSoulsService.getAiSouls(), + }) + + // Get training documents for selected soul + const { data: trainingDocuments, refetch: refetchDocuments } = useQuery({ + queryKey: ["training-documents", selectedSoul], + queryFn: () => + selectedSoul + ? TrainingService.getTrainingDocuments({ aiSoulId: selectedSoul }) + : null, + enabled: !!selectedSoul, + }) + + // Delete training document mutation + const deleteTrainingDocMutation = useMutation({ + mutationFn: ({ + aiSoulId, + documentId, + }: { aiSoulId: string; documentId: string }) => + TrainingService.deleteTrainingDocument({ aiSoulId, documentId }), + onSuccess: () => { + showSuccessToast("Training document deleted successfully") + queryClient.invalidateQueries({ + queryKey: ["training-documents", selectedSoul], + }) + }, + onError: (err: ApiError) => { + const errDetail = (err.body as any)?.detail + showErrorToast(`Failed to delete training document: ${errDetail}`) + }, + }) + + const handleFileSelect = (event: React.ChangeEvent) => { + const file = event.target.files?.[0] + if (file) { + setSelectedFile(file) + } + } + + const handleUploadDocument = async () => { + if (!selectedFile || !selectedSoul) return + + setIsUploadingFile(true) + setUploadProgress(0) + + try { + // Simulate upload progress + const progressInterval = setInterval(() => { + setUploadProgress((prev) => { + if (prev >= 90) { + clearInterval(progressInterval) + return 90 + } + return prev + 10 + }) + }, 200) + + await TrainingService.uploadTrainingDocument({ + aiSoulId: selectedSoul, + formData: { + file: selectedFile, + description: `Training document: ${selectedFile.name}` + } + }) + + // Complete progress + clearInterval(progressInterval) + setUploadProgress(100) + + // Reset after a short delay + setTimeout(() => { + setSelectedFile(null) + setUploadProgress(0) + if (fileInputRef.current) { + fileInputRef.current.value = "" + } + }, 1000) + + showSuccessToast( + `Training document "${selectedFile.name}" uploaded successfully`, + ) + refetchDocuments() + } catch (error) { + showErrorToast("Failed to upload training document") + setUploadProgress(0) + } finally { + setIsUploadingFile(false) + } + } + + const handleDeleteDocument = async (documentId: string) => { + if (!selectedSoul) return + + deleteTrainingDocMutation.mutate({ + aiSoulId: selectedSoul, + documentId: documentId, + }) + } + + return ( + + + + + + Training Documents Management + + + + {/* AI Soul Selector */} + + + Select AI Soul: + + + {aiSouls?.map((soul: AISoulEntity) => ( + + ))} + + + + {/* Training Documents Section */} + {selectedSoul && ( + + + + + Training Documents for{" "} + {aiSouls?.find((s) => s.id === selectedSoul)?.name} + + + + + {/* Upload Progress */} + {selectedFile && ( + + + + + Selected: {selectedFile.name} + + + + {isUploadingFile && ( + + + Upload progress: {uploadProgress}% + + + + + + )} + + + )} + + {/* Training Documents Grid */} + {trainingDocuments && trainingDocuments.length > 0 ? ( + + {trainingDocuments.map((doc) => ( + + + + + + Training Doc + + + {new Date(doc.created_at).toLocaleDateString()} + + + + + + {doc.filename} + + {doc.description && ( + + {doc.description} + + )} + + + + + + File Size + + + {doc.file_size + ? `${(doc.file_size / 1024 / 1024).toFixed(2)} MB` + : "Unknown"} + + + + + + + ))} + + ) : ( + + + + + + No training documents found + + + Upload training documents to provide specialized knowledge + and improve this AI soul's responses in specific domains. + + + + + + )} + + {/* Summary Stats */} + {trainingDocuments && trainingDocuments.length > 0 && ( + + + + + + + Total Documents + + + {trainingDocuments.length} + + + + + + + + + + Total Size + + + {( + trainingDocuments.reduce( + (sum, doc) => sum + (doc.file_size || 0), + 0 + ) / + 1024 / + 1024 + ).toFixed(1)}{" "} + MB + + + + + + )} + + {/* Hidden file input */} + + + + )} + + {/* No Soul Selected State */} + {!selectedSoul && ( + + + + + + Select an AI Soul to manage training documents + + + Choose an AI soul from the list above to view, upload, and + manage its training documents. + + + + + )} + + + + ) +} \ No newline at end of file diff --git a/frontend/src/components/UserSettings/Appearance.tsx b/frontend/src/components/UserSettings/Appearance.tsx index a941741630..fbf4a41f0a 100644 --- a/frontend/src/components/UserSettings/Appearance.tsx +++ b/frontend/src/components/UserSettings/Appearance.tsx @@ -1,11 +1,19 @@ import { Container, Heading, Stack } from "@chakra-ui/react" import { useTheme } from "next-themes" +import type { FormEvent } from "react" import { Radio, RadioGroup } from "@/components/ui/radio" +type Theme = "system" | "light" | "dark" + const Appearance = () => { const { theme, setTheme } = useTheme() + const handleThemeChange = (event: FormEvent) => { + const value = (event.target as HTMLInputElement).value + setTheme(value as Theme) + } + return ( <> @@ -14,9 +22,9 @@ const Appearance = () => { setTheme(e.value)} - value={theme} - colorPalette="teal" + defaultValue={(theme as Theme) || "system"} + name="theme" + onChange={handleThemeChange} > System diff --git a/frontend/src/components/UserSettings/RAGConfiguration.tsx b/frontend/src/components/UserSettings/RAGConfiguration.tsx new file mode 100644 index 0000000000..8f5b6a078d --- /dev/null +++ b/frontend/src/components/UserSettings/RAGConfiguration.tsx @@ -0,0 +1,345 @@ +import { + Box, + Button, + Flex, + Heading, + Input, + Text, + VStack, +} from "@chakra-ui/react" +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" +import React, { useState } from "react" +import { FiRefreshCw, FiSave } from "react-icons/fi" + +import { type ConfigurationRequest, EnhancedRagService } from "../../client" +import useCustomToast from "../../hooks/useCustomToast" +import { Field } from "../ui/field" + +interface RAGConfigForm { + chunking_strategy: string + chunk_size: number + chunk_overlap: number + embedding_model: string + search_algorithm: string + similarity_threshold: number + max_results: number + enable_reranking: boolean +} + +const RAGConfiguration: React.FC = () => { + const { showSuccessToast, showErrorToast } = useCustomToast() + const queryClient = useQueryClient() + + // Get current RAG configuration + const { + data: currentConfig, + isLoading, + error, + } = useQuery({ + queryKey: ["rag-configuration"], + queryFn: () => EnhancedRagService.getRagConfiguration(), + }) + + // Initialize form with current config or defaults + const [formData, setFormData] = useState({ + chunking_strategy: "semantic", + chunk_size: 500, + chunk_overlap: 50, + embedding_model: "text-embedding-3-small", + search_algorithm: "hybrid", + similarity_threshold: 0.7, + max_results: 10, + enable_reranking: true, + }) + + // Update form when config loads + React.useEffect(() => { + if (currentConfig && typeof currentConfig === "object") { + const config = currentConfig as any + setFormData({ + chunking_strategy: config.chunking_strategy || "semantic", + chunk_size: config.chunk_size || 500, + chunk_overlap: config.chunk_overlap || 50, + embedding_model: config.embedding_model || "text-embedding-3-small", + search_algorithm: config.search_algorithm || "hybrid", + similarity_threshold: config.similarity_threshold || 0.7, + max_results: config.max_results || 10, + enable_reranking: config.enable_reranking ?? true, + }) + } + }, [currentConfig]) + + // Update configuration mutation + const updateConfigMutation = useMutation({ + mutationFn: (config: ConfigurationRequest) => + EnhancedRagService.updateRagConfiguration({ requestBody: config }), + onSuccess: () => { + showSuccessToast("RAG configuration updated successfully") + queryClient.invalidateQueries({ queryKey: ["rag-configuration"] }) + }, + onError: (error: any) => { + showErrorToast(`Failed to update configuration: ${error.message}`) + }, + }) + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + updateConfigMutation.mutate(formData) + } + + const handleInputChange = ( + field: keyof RAGConfigForm, + value: string | number | boolean, + ) => { + setFormData((prev) => ({ + ...prev, + [field]: value, + })) + } + + const resetToDefaults = () => { + setFormData({ + chunking_strategy: "semantic", + chunk_size: 500, + chunk_overlap: 50, + embedding_model: "text-embedding-3-small", + search_algorithm: "hybrid", + similarity_threshold: 0.7, + max_results: 10, + enable_reranking: true, + }) + } + + if (isLoading) { + return ( + + Loading RAG configuration... + + ) + } + + if (error) { + return ( + + Failed to load RAG configuration + + ) + } + + return ( + +
+ + {/* Document Processing Settings */} + + + Document Processing + + + + + + + + + + handleInputChange( + "chunk_size", + Number.parseInt(e.target.value), + ) + } + min={100} + max={2000} + /> + + + + + handleInputChange( + "chunk_overlap", + Number.parseInt(e.target.value), + ) + } + min={0} + max={200} + /> + + + + + + + + + + {/* Search Settings */} + + + Search Settings + + + + + + + + + + handleInputChange( + "similarity_threshold", + Number.parseFloat(e.target.value), + ) + } + min={0} + max={1} + /> + + + + + handleInputChange( + "max_results", + Number.parseInt(e.target.value), + ) + } + min={1} + max={50} + /> + + + + + + + handleInputChange("enable_reranking", e.target.checked) + } + style={{ marginRight: "8px" }} + /> + Enable result reranking + + + + + + {/* Action Buttons */} + + + + + +
+
+ ) +} + +export default RAGConfiguration diff --git a/frontend/src/components/ui/button.tsx b/frontend/src/components/ui/button.tsx index 21d5f4b550..17254b632b 100644 --- a/frontend/src/components/ui/button.tsx +++ b/frontend/src/components/ui/button.tsx @@ -16,9 +16,33 @@ export interface ButtonProps extends ChakraButtonProps, ButtonLoadingProps {} export const Button = React.forwardRef( function Button(props, ref) { - const { loading, disabled, loadingText, children, ...rest } = props + const { + loading, + disabled, + loadingText, + children, + variant = "solid", + colorScheme = "teal", + size = "md", + ...rest + } = props + return ( - + {loading && !loadingText ? ( <> @@ -28,7 +52,7 @@ export const Button = React.forwardRef( ) : loading && loadingText ? ( <> - + {loadingText} ) : ( diff --git a/frontend/src/hooks/useAuth.ts b/frontend/src/hooks/useAuth.ts index 5344493d49..0e1c11824d 100644 --- a/frontend/src/hooks/useAuth.ts +++ b/frontend/src/hooks/useAuth.ts @@ -1,6 +1,6 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" import { useNavigate } from "@tanstack/react-router" -import { useState } from "react" +import { useState, useEffect } from "react" import { type Body_login_login_access_token as AccessToken, @@ -11,21 +11,98 @@ import { UsersService, } from "@/client" import { handleError } from "@/utils" +import { getUserRole, UserRole } from "@/utils/roles" + +const TOKEN_KEY = "access_token" +const TOKEN_TIMESTAMP_KEY = "token_timestamp" const isLoggedIn = () => { - return localStorage.getItem("access_token") !== null + return localStorage.getItem(TOKEN_KEY) !== null +} + +const isTokenExpired = (user: UserPublic | null) => { + const token = localStorage.getItem(TOKEN_KEY) + const timestamp = localStorage.getItem(TOKEN_TIMESTAMP_KEY) + + if (!token || !timestamp) { + return true + } + + const tokenAge = Date.now() - parseInt(timestamp) + const userRole = getUserRole(user) + + // Role-based session timeouts (in milliseconds) + const sessionTimeouts = { + [UserRole.ADMIN]: 8 * 60 * 60 * 1000, // 8 hours for admins + [UserRole.COUNSELOR]: 6 * 60 * 60 * 1000, // 6 hours for counselors + [UserRole.TRAINER]: 4 * 60 * 60 * 1000, // 4 hours for trainers + [UserRole.USER]: 2 * 60 * 60 * 1000, // 2 hours for regular users + } + + const timeout = sessionTimeouts[userRole] || sessionTimeouts[UserRole.USER] + return tokenAge > timeout +} + +const setToken = (token: string) => { + localStorage.setItem(TOKEN_KEY, token) + localStorage.setItem(TOKEN_TIMESTAMP_KEY, Date.now().toString()) +} + +const clearToken = () => { + localStorage.removeItem(TOKEN_KEY) + localStorage.removeItem(TOKEN_TIMESTAMP_KEY) } const useAuth = () => { const [error, setError] = useState(null) const navigate = useNavigate() const queryClient = useQueryClient() - const { data: user } = useQuery({ + + const { data: user, isError, error: userError } = useQuery({ queryKey: ["currentUser"], queryFn: UsersService.readUserMe, enabled: isLoggedIn(), + retry: (failureCount, error) => { + // Don't retry on 401/403 errors (authentication/authorization issues) + if (error?.message?.includes('401') || error?.message?.includes('403')) { + return false + } + return failureCount < 3 + }, + refetchOnWindowFocus: true, + refetchInterval: 5 * 60 * 1000, // Refetch every 5 minutes to validate session }) + // Auto-logout on token expiration or authentication errors + useEffect(() => { + if (isLoggedIn() && (isTokenExpired(user || null) || isError)) { + logout() + } + }, [user, isError, userError]) + + // Session activity tracking + useEffect(() => { + if (!isLoggedIn()) return + + const updateActivity = () => { + if (user && !isTokenExpired(user || null)) { + // Update timestamp on user activity + localStorage.setItem(TOKEN_TIMESTAMP_KEY, Date.now().toString()) + } + } + + const events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'] + events.forEach(event => { + document.addEventListener(event, updateActivity, { passive: true }) + }) + + return () => { + events.forEach(event => { + document.removeEventListener(event, updateActivity) + }) + } + }, [user]) + const signUpMutation = useMutation({ mutationFn: (data: UserRegister) => UsersService.registerUser({ requestBody: data }), @@ -45,12 +122,14 @@ const useAuth = () => { const response = await LoginService.loginAccessToken({ formData: data, }) - localStorage.setItem("access_token", response.access_token) + setToken(response.access_token) } const loginMutation = useMutation({ mutationFn: login, onSuccess: () => { + // Invalidate and refetch user data + queryClient.invalidateQueries({ queryKey: ["currentUser"] }) navigate({ to: "/" }) }, onError: (err: ApiError) => { @@ -59,17 +138,31 @@ const useAuth = () => { }) const logout = () => { - localStorage.removeItem("access_token") + clearToken() + // Clear user data from cache + queryClient.removeQueries({ queryKey: ["currentUser"] }) + // Clear all cached data to prevent cross-user contamination + queryClient.clear() navigate({ to: "/login" }) } + // Force logout function for admin use + const forceLogout = (reason?: string) => { + if (reason) { + setError(reason) + } + logout() + } + return { signUpMutation, loginMutation, logout, + forceLogout, user, error, resetError: () => setError(null), + isTokenExpired: () => isTokenExpired(user || null), } } diff --git a/frontend/src/hooks/useCustomToast.ts b/frontend/src/hooks/useCustomToast.ts index fb04623516..4a523b5069 100644 --- a/frontend/src/hooks/useCustomToast.ts +++ b/frontend/src/hooks/useCustomToast.ts @@ -1,25 +1,57 @@ "use client" -import { toaster } from "@/components/ui/toaster" - -const useCustomToast = () => { - const showSuccessToast = (description: string) => { - toaster.create({ - title: "Success!", - description, - type: "success", - }) +import { useToast } from "@chakra-ui/toast" +import type { UseToastOptions } from "@chakra-ui/toast" + +export function useCustomToast() { + const toast = useToast() + + const defaultOptions: UseToastOptions = { + duration: 3000, + isClosable: true, + position: "top", } - const showErrorToast = (description: string) => { - toaster.create({ - title: "Something went wrong!", - description, - type: "error", + const success = (message: string, options: UseToastOptions = {}) => + toast({ + ...defaultOptions, + ...options, + title: message, + status: "success", + }) + + const error = (message: string, options: UseToastOptions = {}) => + toast({ + ...defaultOptions, + ...options, + title: message, + status: "error", }) - } - return { showSuccessToast, showErrorToast } + const warning = (message: string, options: UseToastOptions = {}) => + toast({ + ...defaultOptions, + ...options, + title: message, + status: "warning", + }) + + const info = (message: string, options: UseToastOptions = {}) => + toast({ + ...defaultOptions, + ...options, + title: message, + status: "info", + }) + + return { + success, + error, + warning, + info, + showSuccessToast: success, + showErrorToast: error, + } } export default useCustomToast diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 0d80ea6f8d..a3b5774022 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -12,18 +12,60 @@ import { routeTree } from "./routeTree.gen" import { ApiError, OpenAPI } from "./client" import { CustomProvider } from "./components/ui/provider" -OpenAPI.BASE = import.meta.env.VITE_API_URL +OpenAPI.BASE = (import.meta as any).env.VITE_API_URL OpenAPI.TOKEN = async () => { return localStorage.getItem("access_token") || "" } +const isTokenExpired = (token: string): boolean => { + try { + // Decode JWT token to check expiration + const payload = JSON.parse(atob(token.split('.')[1])) + const currentTime = Date.now() / 1000 + return payload.exp < currentTime + } catch { + return true // If we can't decode, consider it expired + } +} + const handleApiError = (error: Error) => { if (error instanceof ApiError && [401, 403].includes(error.status)) { - localStorage.removeItem("access_token") - window.location.href = "/login" + const token = localStorage.getItem("access_token") + + // Only logout if token is actually expired or missing + if (!token || isTokenExpired(token)) { + localStorage.removeItem("access_token") + window.location.href = "/login" + } else { + // Token is valid but we got 401/403 - might be a temporary issue + // Log the error but don't logout + console.warn("API returned 401/403 but token appears valid. This might be a temporary issue.", { + error: error.message, + status: error.status, + url: (error as any).request?.url + }) + } } } + const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: (failureCount, error) => { + // Don't retry on authentication errors + if (error instanceof ApiError && [401, 403].includes(error.status)) { + return false + } + // Retry up to 3 times for other errors + return failureCount < 3 + }, + staleTime: 5 * 60 * 1000, // 5 minutes + refetchOnWindowFocus: false, // Reduce unnecessary refetches + }, + mutations: { + retry: false, // Don't retry mutations + }, + }, queryCache: new QueryCache({ onError: handleApiError, }), diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index 0e78c9ba20..db3253ea18 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -17,9 +17,18 @@ import { Route as RecoverPasswordImport } from './routes/recover-password' import { Route as LoginImport } from './routes/login' import { Route as LayoutImport } from './routes/_layout' import { Route as LayoutIndexImport } from './routes/_layout/index' +import { Route as LayoutTrainingDocumentsImport } from './routes/_layout/training-documents' +import { Route as LayoutTrainingImport } from './routes/_layout/training' import { Route as LayoutSettingsImport } from './routes/_layout/settings' import { Route as LayoutItemsImport } from './routes/_layout/items' +import { Route as LayoutDocumentsImport } from './routes/_layout/documents' +import { Route as LayoutCreateSoulImport } from './routes/_layout/create-soul' +import { Route as LayoutCounselorImport } from './routes/_layout/counselor' +import { Route as LayoutChatImport } from './routes/_layout/chat' +import { Route as LayoutAiSoulsImport } from './routes/_layout/ai-souls' +import { Route as LayoutAdvancedRagImport } from './routes/_layout/advanced-rag' import { Route as LayoutAdminImport } from './routes/_layout/admin' +import { Route as LayoutAiSoulsEditIdImport } from './routes/_layout/ai-souls-edit.$id' // Create/Update Routes @@ -53,6 +62,16 @@ const LayoutIndexRoute = LayoutIndexImport.update({ getParentRoute: () => LayoutRoute, } as any) +const LayoutTrainingDocumentsRoute = LayoutTrainingDocumentsImport.update({ + path: '/training-documents', + getParentRoute: () => LayoutRoute, +} as any) + +const LayoutTrainingRoute = LayoutTrainingImport.update({ + path: '/training', + getParentRoute: () => LayoutRoute, +} as any) + const LayoutSettingsRoute = LayoutSettingsImport.update({ path: '/settings', getParentRoute: () => LayoutRoute, @@ -63,11 +82,46 @@ const LayoutItemsRoute = LayoutItemsImport.update({ getParentRoute: () => LayoutRoute, } as any) +const LayoutDocumentsRoute = LayoutDocumentsImport.update({ + path: '/documents', + getParentRoute: () => LayoutRoute, +} as any) + +const LayoutCreateSoulRoute = LayoutCreateSoulImport.update({ + path: '/create-soul', + getParentRoute: () => LayoutRoute, +} as any) + +const LayoutCounselorRoute = LayoutCounselorImport.update({ + path: '/counselor', + getParentRoute: () => LayoutRoute, +} as any) + +const LayoutChatRoute = LayoutChatImport.update({ + path: '/chat', + getParentRoute: () => LayoutRoute, +} as any) + +const LayoutAiSoulsRoute = LayoutAiSoulsImport.update({ + path: '/ai-souls', + getParentRoute: () => LayoutRoute, +} as any) + +const LayoutAdvancedRagRoute = LayoutAdvancedRagImport.update({ + path: '/advanced-rag', + getParentRoute: () => LayoutRoute, +} as any) + const LayoutAdminRoute = LayoutAdminImport.update({ path: '/admin', getParentRoute: () => LayoutRoute, } as any) +const LayoutAiSoulsEditIdRoute = LayoutAiSoulsEditIdImport.update({ + path: '/ai-souls-edit/$id', + getParentRoute: () => LayoutRoute, +} as any) + // Populate the FileRoutesByPath interface declare module '@tanstack/react-router' { @@ -96,6 +150,30 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LayoutAdminImport parentRoute: typeof LayoutImport } + '/_layout/advanced-rag': { + preLoaderRoute: typeof LayoutAdvancedRagImport + parentRoute: typeof LayoutImport + } + '/_layout/ai-souls': { + preLoaderRoute: typeof LayoutAiSoulsImport + parentRoute: typeof LayoutImport + } + '/_layout/chat': { + preLoaderRoute: typeof LayoutChatImport + parentRoute: typeof LayoutImport + } + '/_layout/counselor': { + preLoaderRoute: typeof LayoutCounselorImport + parentRoute: typeof LayoutImport + } + '/_layout/create-soul': { + preLoaderRoute: typeof LayoutCreateSoulImport + parentRoute: typeof LayoutImport + } + '/_layout/documents': { + preLoaderRoute: typeof LayoutDocumentsImport + parentRoute: typeof LayoutImport + } '/_layout/items': { preLoaderRoute: typeof LayoutItemsImport parentRoute: typeof LayoutImport @@ -104,10 +182,22 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LayoutSettingsImport parentRoute: typeof LayoutImport } + '/_layout/training': { + preLoaderRoute: typeof LayoutTrainingImport + parentRoute: typeof LayoutImport + } + '/_layout/training-documents': { + preLoaderRoute: typeof LayoutTrainingDocumentsImport + parentRoute: typeof LayoutImport + } '/_layout/': { preLoaderRoute: typeof LayoutIndexImport parentRoute: typeof LayoutImport } + '/_layout/ai-souls-edit/$id': { + preLoaderRoute: typeof LayoutAiSoulsEditIdImport + parentRoute: typeof LayoutImport + } } } @@ -116,9 +206,18 @@ declare module '@tanstack/react-router' { export const routeTree = rootRoute.addChildren([ LayoutRoute.addChildren([ LayoutAdminRoute, + LayoutAdvancedRagRoute, + LayoutAiSoulsRoute, + LayoutChatRoute, + LayoutCounselorRoute, + LayoutCreateSoulRoute, + LayoutDocumentsRoute, LayoutItemsRoute, LayoutSettingsRoute, + LayoutTrainingRoute, + LayoutTrainingDocumentsRoute, LayoutIndexRoute, + LayoutAiSoulsEditIdRoute, ]), LoginRoute, RecoverPasswordRoute, diff --git a/frontend/src/routes/__root.tsx b/frontend/src/routes/__root.tsx index 5059200ec4..fa5c9d5ec2 100644 --- a/frontend/src/routes/__root.tsx +++ b/frontend/src/routes/__root.tsx @@ -18,8 +18,7 @@ const loadDevtools = () => } }) -const TanStackDevtools = - process.env.NODE_ENV === "production" ? () => null : React.lazy(loadDevtools) +const TanStackDevtools = () => null // Disabled for production deployment export const Route = createRootRoute({ component: () => ( diff --git a/frontend/src/routes/_layout.tsx b/frontend/src/routes/_layout.tsx index c0634a74f3..319270cd43 100644 --- a/frontend/src/routes/_layout.tsx +++ b/frontend/src/routes/_layout.tsx @@ -1,32 +1,42 @@ -import { Flex } from "@chakra-ui/react" +import { Box, Container } from "@chakra-ui/react" import { Outlet, createFileRoute, redirect } from "@tanstack/react-router" - -import Navbar from "@/components/Common/Navbar" -import Sidebar from "@/components/Common/Sidebar" -import { isLoggedIn } from "@/hooks/useAuth" +import React from "react" +import Navbar from "../components/Common/Navbar" +import Sidebar from "../components/Common/Sidebar" +import { isLoggedIn } from "../hooks/useAuth" export const Route = createFileRoute("/_layout")({ - component: Layout, - beforeLoad: async () => { + beforeLoad: ({ location }: { location: any }) => { if (!isLoggedIn()) { throw redirect({ to: "/login", + search: { + redirect: location.href, + }, }) } }, + component: Layout, }) function Layout() { return ( - + - + - - - - - + + + + + + + ) } diff --git a/frontend/src/routes/_layout/admin.tsx b/frontend/src/routes/_layout/admin.tsx index 7a6ede7291..76942111cd 100644 --- a/frontend/src/routes/_layout/admin.tsx +++ b/frontend/src/routes/_layout/admin.tsx @@ -18,7 +18,7 @@ const usersSearchSchema = z.object({ page: z.number().catch(1), }) -const PER_PAGE = 5 +const PER_PAGE = 15 function getUsersQueryOptions({ page }: { page: number }) { return { @@ -83,7 +83,7 @@ function UsersTable() { {user.email} - {user.is_superuser ? "Superuser" : "User"} + {formatRole(user)} {user.is_active ? "Active" : "Inactive"} @@ -116,12 +116,42 @@ function UsersTable() { function Admin() { return ( - + Users Management - + + + + ) } + +// Helper function to format role display +const formatRole = (user: UserPublic) => { + // Check superuser first + if (user.is_superuser) { + return "Administrator" + } + + // Use the role field and properly capitalize it + const role = user.role || "user" + + // Handle special cases + switch (role.toLowerCase()) { + case "admin": + case "super_admin": + return "Administrator" + case "trainer": + return "Trainer" + case "counselor": + return "Counselor" + case "user": + return "User" + default: + // Fallback: capitalize first letter + return role.charAt(0).toUpperCase() + role.slice(1) + } +} diff --git a/frontend/src/routes/_layout/advanced-rag.tsx b/frontend/src/routes/_layout/advanced-rag.tsx new file mode 100644 index 0000000000..4a33a722f3 --- /dev/null +++ b/frontend/src/routes/_layout/advanced-rag.tsx @@ -0,0 +1,15 @@ +import { createFileRoute } from "@tanstack/react-router" +import { AdvancedRAGManagement } from "../../components/Admin/AdvancedRAGManagement" +import { RoleGuard } from "../../components/Common/RoleGuard" + +export const Route = createFileRoute("/_layout/advanced-rag")({ + component: AdvancedRAG, +}) + +function AdvancedRAG() { + return ( + + + + ) +} diff --git a/frontend/src/routes/_layout/ai-souls-edit.$id.tsx b/frontend/src/routes/_layout/ai-souls-edit.$id.tsx new file mode 100644 index 0000000000..63ec8aa381 --- /dev/null +++ b/frontend/src/routes/_layout/ai-souls-edit.$id.tsx @@ -0,0 +1,240 @@ +import { + Box, + Button, + Container, + HStack, + Heading, + Input, + Spinner, + Text, + Textarea, + VStack, +} from "@chakra-ui/react" +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" +import { createFileRoute, useNavigate, useParams } from "@tanstack/react-router" +import type React from "react" +import { useEffect, useState } from "react" +import { FiArrowLeft, FiSave } from "react-icons/fi" + +import { AiSoulsService } from "@/client" +import type { AISoulEntity } from "@/client" +import { Field } from "@/components/ui/field" +import useCustomToast from "@/hooks/useCustomToast" + +export const Route = createFileRoute("/_layout/ai-souls-edit/$id")({ + component: EditAiSoul, +}) + +interface AISoulFormData { + name: string + description: string + persona_type: string + specializations: string + base_prompt: string + is_active: boolean +} + +function EditAiSoul() { + const navigate = useNavigate() + const { id } = useParams({ from: "/_layout/ai-souls-edit/$id" }) + const { showSuccessToast, showErrorToast } = useCustomToast() + const queryClient = useQueryClient() + + const [formData, setFormData] = useState({ + name: "", + description: "", + persona_type: "", + specializations: "", + base_prompt: "", + is_active: true, + }) + + // Fetch AI soul data + const { + data: aiSoul, + isLoading, + error, + } = useQuery({ + queryKey: ["ai-soul", id], + queryFn: () => AiSoulsService.getAiSoul({ aiSoulId: id }), + enabled: !!id, + }) + + // Update form data when AI soul data is loaded + useEffect(() => { + if (aiSoul) { + setFormData({ + name: aiSoul.name || "", + description: aiSoul.description || "", + persona_type: aiSoul.persona_type || "", + specializations: aiSoul.specializations || "", + base_prompt: aiSoul.base_prompt || "", + is_active: aiSoul.is_active ?? true, + }) + } + }, [aiSoul]) + + // Update AI soul mutation + const updateAiSoulMutation = useMutation({ + mutationFn: (data: AISoulFormData) => + AiSoulsService.updateAiSoul({ + aiSoulId: id, + requestBody: { + ...data, + user_id: aiSoul?.user_id || "", // Preserve the user_id + } as AISoulEntity, + }), + onSuccess: () => { + showSuccessToast("AI soul updated successfully") + queryClient.invalidateQueries({ queryKey: ["ai-souls"] }) + queryClient.invalidateQueries({ queryKey: ["ai-soul", id] }) + navigate({ to: "/ai-souls" }) + }, + onError: (error: any) => { + showErrorToast(error.body?.detail || "Failed to update AI soul") + }, + }) + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + if ( + !formData.name || + !formData.persona_type || + !formData.specializations || + !formData.base_prompt + ) { + showErrorToast("Please fill in all required fields") + return + } + updateAiSoulMutation.mutate(formData) + } + + const handleInputChange = ( + field: keyof AISoulFormData, + value: string | boolean, + ) => { + setFormData((prev) => ({ + ...prev, + [field]: value, + })) + } + + if (isLoading) { + return ( + + + + Loading AI soul... + + + ) + } + + if (error) { + return ( + + Failed to load AI soul. Please try again. + + ) + } + + return ( + + + {/* Header */} + + + Edit AI Soul + + Update your AI soul's personality and behavior + + + + + + {/* Form */} + + + + handleInputChange("name", e.target.value)} + placeholder="Enter AI soul name" + /> + + + +