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)}
- >
-
-
-
-
-
-
-
-
+
+
+
+
+
+ >
)
}
+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 (
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
)
}
-
-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 */}
-
-
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
+
+
+ {/* 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) => (
+ setSelectedSoul(soul.id || null)}
+ size="md"
+ >
+ {soul.name}
+
+ ))}
+
+
+
+ {/* Training Documents Section */}
+ {selectedSoul && (
+
+
+
+
+ Training Documents for{" "}
+ {aiSouls?.find((s) => s.id === selectedSoul)?.name}
+
+ fileInputRef.current?.click()}
+ bg="#437057"
+ color="white"
+ _hover={{ bg: "#2F5249" }}
+ leftIcon={}
+ >
+ Upload Document
+
+
+
+ {/* Upload Progress */}
+ {selectedFile && (
+
+
+
+
+ Selected: {selectedFile.name}
+
+
+ Upload
+
+
+ {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"}
+
+
+ handleDeleteDocument(doc.id)}
+ isLoading={deleteTrainingDocMutation.isPending}
+ leftIcon={}
+ >
+ Delete
+
+
+
+
+ ))}
+
+ ) : (
+
+
+
+
+
+ No training documents found
+
+
+ Upload training documents to provide specialized knowledge
+ and improve this AI soul's responses in specific domains.
+
+
+ fileInputRef.current?.click()}
+ bg="#437057"
+ color="white"
+ _hover={{ bg: "#2F5249" }}
+ leftIcon={}
+ size="lg"
+ >
+ Upload First Document
+
+
+
+ )}
+
+ {/* 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 (
+
+