From 2b15db82a7c53e3da99796130649f0c4bd2f161b Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 23 Sep 2025 18:23:52 -0400 Subject: [PATCH 01/25] Fix workflow resume issue --- src/mcp_agent/executor/workflow.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/mcp_agent/executor/workflow.py b/src/mcp_agent/executor/workflow.py index 723c99bb9..eaf58a08b 100644 --- a/src/mcp_agent/executor/workflow.py +++ b/src/mcp_agent/executor/workflow.py @@ -9,6 +9,7 @@ Generic, Literal, Optional, + Sequence, TypeVar, TYPE_CHECKING, ) @@ -424,16 +425,17 @@ async def cancel(self) -> bool: return False # Add the dynamic signal handler method in the case that the workflow is running under Temporal - if "temporalio.workflow" in sys.modules: - from temporalio import workflow + try: + from temporalio import workflow as temporal_workflow from temporalio.common import RawValue - from typing import Sequence + except ImportError: # Temporal not installed or available in this environment + temporal_workflow = None # type: ignore[assignment] + RawValue = None # type: ignore[assignment] - @workflow.signal(dynamic=True) + if temporal_workflow is not None: + @temporal_workflow.signal(dynamic=True) async def _signal_receiver(self, name: str, args: Sequence[RawValue]): """Dynamic signal handler for Temporal workflows.""" - from temporalio import workflow - self._logger.debug(f"Dynamic signal received: name={name}, args={args}") # Extract payload and update mailbox @@ -450,8 +452,8 @@ async def _signal_receiver(self, name: str, args: Sequence[RawValue]): sig_obj = Signal( name=name, payload=payload, - workflow_id=workflow.info().workflow_id, - run_id=workflow.info().run_id, + workflow_id=temporal_workflow.info().workflow_id, + run_id=temporal_workflow.info().run_id, ) # Live lookup of handlers (enables callbacks added after attach_to_workflow) @@ -461,7 +463,7 @@ async def _signal_receiver(self, name: str, args: Sequence[RawValue]): else: cb(sig_obj) - @workflow.query(name="token_tree") + @temporal_workflow.query(name="token_tree") def _query_token_tree(self) -> str: """Return a best-effort token usage tree string from the workflow process. @@ -481,7 +483,7 @@ def _query_token_tree(self) -> str: except Exception: return "(no token usage)" - @workflow.query(name="token_summary") + @temporal_workflow.query(name="token_summary") def _query_token_summary(self) -> Dict[str, Any]: """Return a JSON-serializable token usage summary from the workflow process. From c9a65530226b68e582cc21965d2ff85b354e2118 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 23 Sep 2025 18:24:41 -0400 Subject: [PATCH 02/25] temp wip --- auth_spec.png | Bin 0 -> 415449 bytes docs/configuration.mdx | 43 +++ docs/oauth_support_design.md | 108 ++++++ src/mcp_agent/app.py | 44 ++- src/mcp_agent/config.py | 89 ++++- src/mcp_agent/core/context.py | 20 ++ src/mcp_agent/mcp/mcp_server_registry.py | 19 ++ src/mcp_agent/oauth/__init__.py | 19 ++ src/mcp_agent/oauth/access_token.py | 82 +++++ src/mcp_agent/oauth/callbacks.py | 53 +++ src/mcp_agent/oauth/errors.py | 21 ++ src/mcp_agent/oauth/flow.py | 218 +++++++++++++ src/mcp_agent/oauth/http/__init__.py | 5 + src/mcp_agent/oauth/http/auth.py | 68 ++++ src/mcp_agent/oauth/identity.py | 46 +++ src/mcp_agent/oauth/manager.py | 249 ++++++++++++++ src/mcp_agent/oauth/metadata.py | 60 ++++ src/mcp_agent/oauth/pkce.py | 27 ++ src/mcp_agent/oauth/records.py | 46 +++ src/mcp_agent/oauth/store/__init__.py | 11 + src/mcp_agent/oauth/store/base.py | 33 ++ src/mcp_agent/oauth/store/in_memory.py | 30 ++ src/mcp_agent/server/app_server.py | 398 +++++++++++++++++------ src/mcp_agent/server/token_verifier.py | 138 ++++++++ tests/test_oauth_utils.py | 85 +++++ 25 files changed, 1810 insertions(+), 102 deletions(-) create mode 100644 auth_spec.png create mode 100644 docs/oauth_support_design.md create mode 100644 src/mcp_agent/oauth/__init__.py create mode 100644 src/mcp_agent/oauth/access_token.py create mode 100644 src/mcp_agent/oauth/callbacks.py create mode 100644 src/mcp_agent/oauth/errors.py create mode 100644 src/mcp_agent/oauth/flow.py create mode 100644 src/mcp_agent/oauth/http/__init__.py create mode 100644 src/mcp_agent/oauth/http/auth.py create mode 100644 src/mcp_agent/oauth/identity.py create mode 100644 src/mcp_agent/oauth/manager.py create mode 100644 src/mcp_agent/oauth/metadata.py create mode 100644 src/mcp_agent/oauth/pkce.py create mode 100644 src/mcp_agent/oauth/records.py create mode 100644 src/mcp_agent/oauth/store/__init__.py create mode 100644 src/mcp_agent/oauth/store/base.py create mode 100644 src/mcp_agent/oauth/store/in_memory.py create mode 100644 src/mcp_agent/server/token_verifier.py create mode 100644 tests/test_oauth_utils.py diff --git a/auth_spec.png b/auth_spec.png new file mode 100644 index 0000000000000000000000000000000000000000..9bd276c46e5e9eae0113935298a0e4474d7fb76a GIT binary patch literal 415449 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

E?AaYo*e_l8!Qq43%NErNgHy9OW+BP;=7??kf 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

AZ{|PM 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ΠYv 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%0AS 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 agXv17^M(vJ!4D1i+*f{}^hLoe^gjS2=P~>M literal 0 HcmV?d00001 diff --git a/docs/configuration.mdx b/docs/configuration.mdx index 22225a004..698638592 100644 --- a/docs/configuration.mdx +++ b/docs/configuration.mdx @@ -123,6 +123,49 @@ mcp-agent uses two configuration files: +## OAuth Configuration + +MCP Agent exposes two complementary OAuth configuration blocks: + +- `authorization` describes how the MCP Agent server validates inbound bearer tokens and publishes protected resource metadata. +- `oauth` configures delegated authorization when the agent connects to downstream MCP servers. + +```yaml +authorization: + enabled: true + issuer_url: https://auth.example.com + resource_server_url: https://agent.example.com/mcp + required_scopes: ["mcp.read", "mcp.write"] + introspection_endpoint: https://auth.example.com/oauth/introspect + introspection_client_id: ${INTROSPECTION_CLIENT_ID} + introspection_client_secret: ${INTROSPECTION_CLIENT_SECRET} + +oauth: + callback_base_url: https://agent.example.com + flow_timeout_seconds: 180 + token_store: + backend: memory # use "redis" for multi-instance deployments + refresh_leeway_seconds: 90 + +mcp: + servers: + github: + transport: streamable_http + url: https://github.mcp.example.com/mcp + auth: + oauth: + enabled: true + scopes: ["repo", "user:email"] + client_id: ${GITHUB_MCP_CLIENT_ID} + client_secret: ${GITHUB_MCP_CLIENT_SECRET} + redirect_uri_options: + - https://agent.example.com/internal/oauth/callback +``` + +- When `authorization.enabled` is true the MCP server advertises `/.well-known/oauth-protected-resource` and enforces bearer tokens using the provided introspection or JWKS configuration. +- `oauth` enables delegated authorization flows; the default in-memory token store is ideal for local development while Redis is recommended for production clusters. +- Downstream servers opt into OAuth via `mcp.servers..auth.oauth`. Supplying a `client_id`/`client_secret` allows immediate usage; support for dynamic client registration is planned as a follow-up. + ## Configuration Reference ### Execution Engine diff --git a/docs/oauth_support_design.md b/docs/oauth_support_design.md new file mode 100644 index 000000000..5aea9b1f2 --- /dev/null +++ b/docs/oauth_support_design.md @@ -0,0 +1,108 @@ +# MCP Agent OAuth Support + +## Goals +- Protect MCP Agent Cloud servers using OAuth 2.1 so MCP clients obtain tokens via standard flows. +- Enable MCP Agent runtimes to authenticate to downstream MCP servers that require OAuth access tokens. +- Provide pluggable token storage for both local development (in-memory) and multi-instance deployments (Redis planned). +- Maintain compatibility with MCP Authorization spec (RFC 8414, RFC 9728, OAuth 2.1 + PKCE, Resource Indicators) and the proposed delegated authorization SEP. + +## Architecture Overview + +### Components +1. **Auth Server Integration** – Configure the FastMCP instance with `AuthSettings` and a custom `TokenVerifier` that calls MCP Agent Cloud auth services. +2. **Protected Resource Metadata** – Serve `/.well-known/oauth-protected-resource` using FastMCP hooks so clients can discover the auth server. +3. **Access Token Validation** – Enforce bearer tokens on every inbound MCP request via `RequireAuthMiddleware`, populating the request context with the authenticated user. +4. **OAuth Token Service** – New `mcp_agent.oauth` package with: + - `TokenStore`/`TokenRecord` abstractions + - `InMemoryTokenStore` and Redis-backed implementation (second pass) + - `TokenManager` orchestration (acquire, refresh, revoke) + - `OAuthHttpxAuth` for attaching tokens to downstream HTTP transports + - `AuthorizationFlowCoordinator` that interacts with the user via MCP `auth/request` +5. **Delegated Authorization UI Flow** – Extend the gateway/session relay so servers can send `auth/request` messages to MCP clients, capturing authorization codes via either: + - Client-returned callback URL (preferred, works with SEP-capable clients) + - MCP Agent hosted callback endpoint (`/internal/oauth/callback/{flow_id}`) as a fallback / native-app style loopback. +6. **Configuration Surface** – Extend `Settings` and per-server `MCPServerAuthSettings` to describe OAuth behaviour (scopes, preferred auth server, redirect URIs, etc.) and global token-store configuration. + +### Key Data Flow +1. **Inbound Requests** + - Client presents bearer token ⇒ `BearerAuthBackend` + `MCPAgentTokenVerifier` introspect token. + - Verified token populates context with `OAuthUserIdentity` (provider + subject + email). + - Context is propagated into workflows/sessions so downstream OAuth flows know the acting user. + +2. **Outbound HTTP (downstream MCP server)** + - `ServerRegistry` detects `auth.oauth` configuration. + - Wraps HTTP transport with `OAuthHttpxAuth` which requests an access token from `TokenManager`. + - `TokenManager` checks store; if missing/expired ⇒ `AuthorizationFlowCoordinator` performs RFC 9728 discovery, PKCE, delegated browser flow through MCP client, exchanges code for tokens, caches result. + - Requests automatically retry after token refresh when a response returns 401/invalid token. + +3. **Token Storage** + - Tokens stored per `(user_identity, resource, authorization_server)` tuple with metadata (scopes, expiry, refresh token, provider claims). + - Store implements optimistic locking to avoid concurrent refresh storms. + - Pluggable backend (`InMemoryTokenStore` initial, Redis follow-up). + +## Module Plan + +``` +src/mcp_agent/oauth/ + __init__.py + identity.py # OAuthUserIdentity, helpers to extract from auth context + records.py # TokenRecord dataclass/pydantic model + store/base.py # TokenStore protocol + store/in_memory.py # Default store + manager.py # TokenManager (get/refresh/invalidate) + flow.py # AuthorizationFlowCoordinator + http/auth.py # OAuthHttpxAuth (httpx.Auth implementation) + metadata.py # RFC 8414 + RFC 9728 discovery helpers + pkce.py # PKCE + state utilities + errors.py # Custom exception hierarchy +``` + +Integration touchpoints: +- `mcp_agent/config.py` – add OAuth settings models. +- `mcp_agent/core/context.py` – add `current_user`, `token_manager`, `token_store`, `oauth_config` fields. +- `mcp_agent/app.py` – initialize token store/manager based on settings. +- `mcp_agent/server/app_server.py` – configure FastMCP auth settings, register callback route, surface user identity, extend relay to handle `auth/request`. +- `mcp_agent/mcp/mcp_server_registry.py` & `mcp_agent/mcp/mcp_connection_manager.py` – wire `OAuthHttpxAuth` into HTTP transports and expose helper for manual token teardown. +- `mcp_agent/mcp/client_proxy.py` – add proxy helpers for `auth/request`. +- `SessionProxy` – add direct request helper for `auth/request` and ensure Temporal flow support. +- `examples/mcp_agent_server/*` – demonstrate configuration changes. +- Tests – new suite exercising token store, metadata discovery, flow orchestration (with mocked HTTP + client responses). + +## OAuth Flow Details +1. **Discovery** + - If downstream server responds 401 with `WWW-Authenticate`, parse for `resource_metadata` ⇒ GET metadata ⇒ determine auth server URL(s). + - Fetch authorization server metadata (RFC 8414). + - Perform optional dynamic client registration when configured and supported. + +2. **Authorization Request** + - Generate PKCE challenge/verifier, secure `state`, choose `redirect_uri`. + - Build authorization URL including `resource` parameter (RFC 8707) + requested scopes. + - Invoke `auth/request` via SessionProxy → MCP client opens browser. + +3. **Callback Handling** + - Preferred: MCP client returns callback URL payload via request result. + - Fallback: Authorization server redirects to `/internal/oauth/callback/{flow_id}`. + - Coordinator validates `state`, extracts `code` (and errors). + +4. **Token Exchange / Storage** + - POST token endpoint with code + PKCE verifier + resource. + - Store access token, refresh token, expiry, scope, provider metadata. + - Associate tokens with user identity for reuse. + +5. **Refresh / Revocation** + - Manager refreshes when expiry within configurable grace window. + - Invalidate token on refresh failure or when server responses indicate revocation. + - Provide method to revoke tokens via authorization server when supported. + +## Open Questions / Follow-ups +- Redis-backed `TokenStore` (requires deployment secrets) – planned second phase. +- How LastMile auth server exposes token introspection + JWKS; need concrete endpoint specs to finalize `MCPAgentTokenVerifier`. +- MCP client adoption of `auth/request` SEP – need capability detection; until widely supported we rely on hosted callback fallback & manual instructions. +- Access control DSL (include/exclude by email/domain) – to be evaluated once token identity payload finalized. + +## Testing Strategy +- Unit tests for token store concurrency + expiry handling. +- Metadata discovery + PKCE generation (pure python tests). +- Integration-style test for delegated flow using mocked HTTP server + fake MCP client (ensures `auth/request` plumbing works end-to-end). +- Tests around server 401 enforcement + WWW-Authenticate header. + diff --git a/src/mcp_agent/app.py b/src/mcp_agent/app.py index f40349a95..558691071 100644 --- a/src/mcp_agent/app.py +++ b/src/mcp_agent/app.py @@ -3,7 +3,7 @@ import sys import functools -from types import MethodType +from types import MethodType, FunctionType from typing import ( Any, Dict, @@ -40,6 +40,8 @@ from mcp_agent.tracing.telemetry import get_tracer from mcp_agent.utils.common import unwrap from mcp_agent.workflows.llm.llm_selector import ModelSelector +from mcp_agent.oauth.manager import TokenManager +from mcp_agent.oauth.store import InMemoryTokenStore from mcp_agent.workflows.factory import load_agent_specs_from_dir @@ -249,6 +251,23 @@ async def initialize(self): # Store a reference to this app instance in the context for easier access self._context.app = self + # Initialize OAuth token management helpers if configured + oauth_settings = None + try: + if self._context.config: + oauth_settings = self._context.config.oauth + except Exception: + oauth_settings = None + + if oauth_settings: + token_store = InMemoryTokenStore() + token_manager = TokenManager( + token_store=token_store, + settings=oauth_settings, + ) + self._context.token_store = token_store + self._context.token_manager = token_manager + # Provide a safe default bound context for loggers created after init without explicit context try: set_default_bound_context(self._context) @@ -557,6 +576,25 @@ async def wrapper(*args, **kwargs): # Fall back to the original function return await fn(*args, **kwargs) + # Ensure the wrapper shares the original function's globals so that + # string annotations (from __future__ import annotations) continue to + # resolve against the workflow module rather than mcp_agent.app. + original_globals = getattr(fn, "__globals__", None) + if original_globals is not None and wrapper.__globals__ is not original_globals: + rebuilt_wrapper = FunctionType( + wrapper.__code__, + original_globals, + name=wrapper.__name__, + argdefs=wrapper.__defaults__, + closure=wrapper.__closure__, + ) + rebuilt_wrapper.__kwdefaults__ = wrapper.__kwdefaults__ + rebuilt_wrapper.__annotations__ = wrapper.__annotations__ + rebuilt_wrapper.__dict__.update(wrapper.__dict__) + rebuilt_wrapper = functools.update_wrapper(rebuilt_wrapper, fn) + rebuilt_wrapper.__wrapped__ = fn + wrapper = rebuilt_wrapper + return wrapper def _create_workflow_from_function( @@ -707,9 +745,9 @@ async def _run(self, *args, **kwargs): # type: ignore[no-redef] # decorate the run method with the engine-specific run decorator. if engine_type == "temporal": try: - run_decorator = (self._decorator_registry.get_workflow_run_decorator( + run_decorator = self._decorator_registry.get_workflow_run_decorator( engine_type - )) + ) if run_decorator: fn_run = getattr(auto_cls, "run") # Ensure method appears as top-level for Temporal diff --git a/src/mcp_agent/config.py b/src/mcp_agent/config.py index 638698b4b..d72f972ec 100644 --- a/src/mcp_agent/config.py +++ b/src/mcp_agent/config.py @@ -11,7 +11,15 @@ import warnings from httpx import URL -from pydantic import AliasChoices, BaseModel, ConfigDict, Field, field_validator +from pydantic import ( + AliasChoices, + AnyHttpUrl, + BaseModel, + ConfigDict, + Field, + field_validator, + model_validator, +) from pydantic_settings import BaseSettings, SettingsConfigDict @@ -22,6 +30,79 @@ class MCPServerAuthSettings(BaseModel): """Represents authentication configuration for a server.""" api_key: str | None = None + oauth: Optional["MCPOAuthClientSettings"] = None + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + +class MCPAuthorizationServerSettings(BaseModel): + """Configuration for exposing the MCP Agent server as an OAuth protected resource.""" + + enabled: bool = False + issuer_url: AnyHttpUrl | None = None + resource_server_url: AnyHttpUrl | None = None + service_documentation_url: AnyHttpUrl | None = None + required_scopes: List[str] = Field(default_factory=list) + jwks_uri: AnyHttpUrl | None = None + introspection_endpoint: AnyHttpUrl | None = None + introspection_client_id: str | None = None + introspection_client_secret: str | None = None + token_cache_ttl_seconds: int = Field(300, ge=0) + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + @model_validator(mode="after") + def _validate_required_urls(self) -> "MCPAuthorizationServerSettings": + if self.enabled: + missing = [] + if self.issuer_url is None: + missing.append("issuer_url") + if self.resource_server_url is None: + missing.append("resource_server_url") + if missing: + raise ValueError( + " | ".join(missing) + " must be set when authorization is enabled" + ) + return self + + +class MCPOAuthClientSettings(BaseModel): + """Configuration for authenticating to downstream OAuth-protected MCP servers.""" + + enabled: bool = False + scopes: List[str] = Field(default_factory=list) + resource: AnyHttpUrl | None = None + authorization_server: AnyHttpUrl | None = None + client_id: str | None = None + client_secret: str | None = None + redirect_uri_options: List[str] = Field(default_factory=list) + extra_authorize_params: Dict[str, str] = Field(default_factory=dict) + extra_token_params: Dict[str, str] = Field(default_factory=dict) + require_pkce: bool = True + use_internal_callback: bool = True + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + +class OAuthTokenStoreSettings(BaseModel): + """Settings for OAuth token persistence.""" + + backend: Literal["memory", "redis"] = "memory" + redis_url: str | None = None + redis_prefix: str = "mcp_agent:oauth_tokens" + refresh_leeway_seconds: int = Field(60, ge=0) + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + +class OAuthSettings(BaseModel): + """Global OAuth-related settings for MCP Agent.""" + + token_store: OAuthTokenStoreSettings = Field( + default_factory=OAuthTokenStoreSettings + ) + flow_timeout_seconds: int = Field(300, ge=30) + callback_base_url: AnyHttpUrl | None = None model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) @@ -639,6 +720,12 @@ class Settings(BaseSettings): agents: SubagentSettings | None = SubagentSettings() """Settings for defining and loading subagents for the MCP Agent application""" + authorization: MCPAuthorizationServerSettings | None = None + """Settings for exposing this MCP application as an OAuth protected resource""" + + oauth: OAuthSettings | None = Field(default_factory=OAuthSettings) + """Global OAuth client configuration (token store, delegated auth defaults)""" + def __eq__(self, other): # type: ignore[override] if not isinstance(other, Settings): return NotImplemented diff --git a/src/mcp_agent/core/context.py b/src/mcp_agent/core/context.py index d449c938a..cc7bee78e 100644 --- a/src/mcp_agent/core/context.py +++ b/src/mcp_agent/core/context.py @@ -33,6 +33,7 @@ from mcp_agent.workflows.llm.llm_selector import ModelSelector from mcp_agent.logging.logger import get_logger from mcp_agent.tracing.token_counter import TokenCounter +from mcp_agent.oauth.identity import OAuthUserIdentity if TYPE_CHECKING: @@ -42,6 +43,8 @@ from mcp_agent.executor.workflow_signal import SignalWaitCallback from mcp_agent.executor.workflow_registry import WorkflowRegistry from mcp_agent.app import MCPApp + from mcp_agent.oauth.manager import TokenManager + from mcp_agent.oauth.store import TokenStore else: # Runtime placeholders for the types AgentSpec = Any @@ -50,6 +53,8 @@ SignalWaitCallback = Any WorkflowRegistry = Any MCPApp = Any + TokenManager = Any + TokenStore = Any logger = get_logger(__name__) @@ -93,6 +98,13 @@ class Context(BaseModel): gateway_url: str | None = None gateway_token: str | None = None + # Current authenticated user (set when acting as an MCP server) + current_user: Optional[OAuthUserIdentity] = None + + # OAuth helpers for downstream servers + token_store: Optional[TokenStore] = None + token_manager: Optional[TokenManager] = None + model_config = ConfigDict( extra="allow", arbitrary_types_allowed=True, # Tell Pydantic to defer type evaluation @@ -256,6 +268,14 @@ async def cleanup_context(shutdown_logger: bool = False): shutdown_logger: If True, completely shutdown OTEL infrastructure. If False, just cleanup app-specific resources. """ + global _global_context + + if _global_context and getattr(_global_context, "token_manager", None): + try: + await _global_context.token_manager.aclose() # type: ignore[call-arg] + except Exception: + pass + if shutdown_logger: # Shutdown logging and telemetry completely await LoggingConfig.shutdown() diff --git a/src/mcp_agent/mcp/mcp_server_registry.py b/src/mcp_agent/mcp/mcp_server_registry.py index a28735373..04a8cad08 100644 --- a/src/mcp_agent/mcp/mcp_server_registry.py +++ b/src/mcp_agent/mcp/mcp_server_registry.py @@ -31,6 +31,7 @@ from mcp_agent.logging.logger import get_logger from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession +from mcp_agent.oauth.http import OAuthHttpxAuth from mcp_agent.mcp.mcp_connection_manager import MCPConnectionManager if TYPE_CHECKING: @@ -215,6 +216,24 @@ async def start_server( kwargs["sse_read_timeout"] = sse_read_timeout # For Streamable HTTP, we get an additional callback for session ID + auth_handler = None + oauth_cfg = config.auth.oauth if config.auth else None + if oauth_cfg and oauth_cfg.enabled: + if context is None or getattr(context, "token_manager", None) is None: + logger.warning( + f"{server_name}: OAuth configured but token manager not available; skipping auth" + ) + else: + auth_handler = OAuthHttpxAuth( + token_manager=context.token_manager, + context=context, + server_name=server_name, + server_config=config, + scopes=oauth_cfg.scopes, + ) + if auth_handler: + kwargs["auth"] = auth_handler + async with streamablehttp_client( **kwargs, ) as (read_stream, write_stream, session_id_callback): diff --git a/src/mcp_agent/oauth/__init__.py b/src/mcp_agent/oauth/__init__.py new file mode 100644 index 000000000..7612bd080 --- /dev/null +++ b/src/mcp_agent/oauth/__init__.py @@ -0,0 +1,19 @@ +"""OAuth support utilities for MCP Agent. + +Modules export their own public APIs; this package file avoids importing them +eagerly to sidestep circular dependencies during initialization. +""" + +__all__ = [ + "access_token", + "callbacks", + "errors", + "flow", + "http", + "identity", + "manager", + "metadata", + "pkce", + "records", + "store", +] diff --git a/src/mcp_agent/oauth/access_token.py b/src/mcp_agent/oauth/access_token.py new file mode 100644 index 000000000..fe3d4bab4 --- /dev/null +++ b/src/mcp_agent/oauth/access_token.py @@ -0,0 +1,82 @@ +"""Extended access token model for MCP Agent authorization flows.""" + +from __future__ import annotations + +from datetime import datetime, timezone +from typing import Any, Dict, Iterable, List + +from mcp.server.auth.provider import AccessToken + + +class MCPAccessToken(AccessToken): + """Access token enriched with identity and claim metadata.""" + + subject: str | None = None + email: str | None = None + issuer: str | None = None + resource_indicator: str | None = None + claims: Dict[str, Any] | None = None + + @classmethod + def from_introspection( + cls, + token: str, + payload: Dict[str, Any], + *, + resource_hint: str | None = None, + ) -> "MCPAccessToken": + """Build an access token instance from an OAuth 2.0 introspection response.""" + client_id = _first_non_empty( + payload.get("client_id"), + payload.get("clientId"), + payload.get("cid"), + ) + scope_value = payload.get("scope") or payload.get("scp") + if isinstance(scope_value, str): + scopes: List[str] = [s for s in scope_value.split() if s] + elif isinstance(scope_value, Iterable): + scopes = [str(item) for item in scope_value] + else: + scopes = [] + + audience = payload.get("resource") or payload.get("aud") + if isinstance(audience, (list, tuple)): + audience_value = _first_non_empty(*audience) + else: + audience_value = audience + + resource = resource_hint or audience_value + + expires_at = payload.get("exp") + + return cls( + token=token, + client_id=str(client_id) if client_id is not None else "", + scopes=scopes, + expires_at=expires_at, + resource=resource, + subject=_first_non_empty(payload.get("sub"), payload.get("subject")), + email=_first_non_empty( + payload.get("email"), payload.get("preferred_username") + ), + issuer=payload.get("iss"), + resource_indicator=resource, + claims=payload, + ) + + def is_expired(self, *, leeway_seconds: int = 0) -> bool: + """Return True if token is expired considering optional leeway.""" + if self.expires_at is None: + return False + now = datetime.now(tz=timezone.utc).timestamp() + return now >= (self.expires_at - leeway_seconds) + + +def _first_non_empty(*values: Any) -> Any | None: + for value in values: + if value is None: + continue + if isinstance(value, str) and not value: + continue + return value + return None diff --git a/src/mcp_agent/oauth/callbacks.py b/src/mcp_agent/oauth/callbacks.py new file mode 100644 index 000000000..7cae8c992 --- /dev/null +++ b/src/mcp_agent/oauth/callbacks.py @@ -0,0 +1,53 @@ +"""Callback coordination for delegated OAuth flows.""" + +from __future__ import annotations + +import asyncio +from typing import Any, Dict + + +class OAuthCallbackRegistry: + """Manage asynchronous delivery of OAuth authorization callbacks.""" + + def __init__(self) -> None: + self._pending: Dict[str, asyncio.Future[Dict[str, Any]]] = {} + self._lock = asyncio.Lock() + + async def create_handle(self, flow_id: str) -> asyncio.Future[Dict[str, Any]]: + """Create (or reuse) a future associated with a flow identifier.""" + async with self._lock: + future = self._pending.get(flow_id) + if future is None or future.done(): + loop = asyncio.get_running_loop() + future = loop.create_future() + self._pending[flow_id] = future + return future + + async def deliver(self, flow_id: str, payload: Dict[str, Any]) -> bool: + """Set the result for a pending flow, returning False when no listener exists.""" + async with self._lock: + future = self._pending.get(flow_id) + if future is None: + return False + if not future.done(): + future.set_result(payload) + return True + + async def fail(self, flow_id: str, exc: Exception) -> bool: + async with self._lock: + future = self._pending.get(flow_id) + if future is None: + return False + if not future.done(): + future.set_exception(exc) + return True + + async def discard(self, flow_id: str) -> None: + async with self._lock: + future = self._pending.pop(flow_id, None) + if future and not future.done(): + future.cancel() + + +# Global registry used by server + flow coordinator +callback_registry = OAuthCallbackRegistry() diff --git a/src/mcp_agent/oauth/errors.py b/src/mcp_agent/oauth/errors.py new file mode 100644 index 000000000..3b1b5ce7a --- /dev/null +++ b/src/mcp_agent/oauth/errors.py @@ -0,0 +1,21 @@ +"""Custom exception types for OAuth workflows.""" + + +class OAuthFlowError(Exception): + """Base class for OAuth-related failures.""" + + +class AuthorizationDeclined(OAuthFlowError): + """Raised when the user declines an authorization request.""" + + +class CallbackTimeoutError(OAuthFlowError): + """Raised when the delegated authorization callback is not received in time.""" + + +class TokenRefreshError(OAuthFlowError): + """Raised when refreshing an access token fails irrecoverably.""" + + +class MissingUserIdentityError(OAuthFlowError): + """Raised when an OAuth flow is attempted without a known user identity.""" diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py new file mode 100644 index 000000000..424385538 --- /dev/null +++ b/src/mcp_agent/oauth/flow.py @@ -0,0 +1,218 @@ +"""Delegated OAuth authorization flow coordinator.""" + +from __future__ import annotations + +import asyncio +import time +import uuid +from typing import Any, Dict, Sequence +from urllib.parse import parse_qs, urlparse + +import httpx +from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata +from mcp.server.session import ServerSession + +from mcp_agent.config import MCPOAuthClientSettings, OAuthSettings +from mcp_agent.core.context import Context +from mcp_agent.logging.logger import get_logger +from mcp_agent.oauth.callbacks import callback_registry +from mcp_agent.oauth.errors import ( + AuthorizationDeclined, + CallbackTimeoutError, + MissingUserIdentityError, + OAuthFlowError, +) +from mcp_agent.oauth.identity import OAuthUserIdentity +from mcp_agent.oauth.pkce import ( + generate_code_challenge, + generate_code_verifier, + generate_state, +) +from mcp_agent.oauth.records import TokenRecord + +logger = get_logger(__name__) + + +class AuthorizationFlowCoordinator: + """Handles the interactive OAuth Authorization Code flow via MCP clients.""" + + def __init__(self, *, http_client: httpx.AsyncClient, settings: OAuthSettings): + self._http_client = http_client + self._settings = settings + + async def authorize( + self, + *, + context: Context, + user: OAuthUserIdentity, + server_name: str, + oauth_config: MCPOAuthClientSettings, + resource: str, + authorization_server_url: str, + resource_metadata: ProtectedResourceMetadata, + auth_metadata: OAuthMetadata, + scopes: Sequence[str], + ) -> TokenRecord: + if not user: + raise MissingUserIdentityError( + "Cannot begin OAuth flow without authenticated MCP user" + ) + + client_id = oauth_config.client_id + if not client_id: + raise OAuthFlowError( + f"No OAuth client_id configured for server '{server_name}'." + ) + + redirect_options = list(oauth_config.redirect_uri_options or []) + flow_id = uuid.uuid4().hex + internal_redirect = None + if oauth_config.use_internal_callback and self._settings.callback_base_url: + internal_redirect = f"{self._settings.callback_base_url.rstrip('/')}/internal/oauth/callback/{flow_id}" + redirect_options.insert(0, internal_redirect) + + if not redirect_options: + raise OAuthFlowError( + "No redirect URI options configured for OAuth authorization flow" + ) + + redirect_uri = redirect_options[0] + + code_verifier = generate_code_verifier() + code_challenge = generate_code_challenge(code_verifier) + state = generate_state() + scope_param = " ".join(scopes) + + authorize_url = httpx.URL( + str(auth_metadata.authorization_endpoint) + ).include_query_params( + response_type="code", + client_id=client_id, + redirect_uri=redirect_uri, + scope=scope_param, + state=state, + code_challenge=code_challenge, + code_challenge_method="S256", + resource=resource, + **(oauth_config.extra_authorize_params or {}), + ) + + callback_future = None + if internal_redirect is not None: + callback_future = await callback_registry.create_handle(flow_id) + + request_payload = { + "url": str(authorize_url), + "message": f"Authorization required for {server_name}", + "redirect_uri_options": redirect_options, + } + + result = await _send_auth_request(context, request_payload) + + try: + if result and result.get("url"): + callback_data = _parse_callback_params(result["url"]) + if callback_future is not None: + await callback_registry.discard(flow_id) + elif callback_future is not None: + timeout = self._settings.flow_timeout_seconds or 300 + try: + callback_data = await asyncio.wait_for( + callback_future, timeout=timeout + ) + except asyncio.TimeoutError as exc: + raise CallbackTimeoutError( + f"Timed out waiting for OAuth callback after {timeout} seconds" + ) from exc + else: + raise AuthorizationDeclined( + "Authorization request was declined by the user" + ) + finally: + if callback_future is not None: + await callback_registry.discard(flow_id) + + error = callback_data.get("error") + if error: + description = callback_data.get("error_description") or error + raise OAuthFlowError(f"Authorization server returned error: {description}") + + returned_state = callback_data.get("state") + if returned_state != state: + raise OAuthFlowError("State mismatch detected in OAuth callback") + + authorization_code = callback_data.get("code") + if not authorization_code: + raise OAuthFlowError("Authorization callback did not include code") + + token_endpoint = str(auth_metadata.token_endpoint) + data: Dict[str, Any] = { + "grant_type": "authorization_code", + "code": authorization_code, + "redirect_uri": redirect_uri, + "client_id": client_id, + "code_verifier": code_verifier, + "resource": resource, + } + if scope_param: + data["scope"] = scope_param + if oauth_config.extra_token_params: + data.update(oauth_config.extra_token_params) + + auth = None + if oauth_config.client_secret: + data["client_secret"] = oauth_config.client_secret + + token_response = await self._http_client.post( + token_endpoint, data=data, auth=auth + ) + token_response.raise_for_status() + payload = token_response.json() + + access_token = payload.get("access_token") + if not access_token: + raise OAuthFlowError("Token endpoint response missing access_token") + refresh_token = payload.get("refresh_token") + expires_in = payload.get("expires_in") + expires_at = None + if isinstance(expires_in, (int, float)): + expires_at = time.time() + float(expires_in) + + scope_from_payload = payload.get("scope") + if isinstance(scope_from_payload, str) and scope_from_payload.strip(): + effective_scopes = tuple(scope_from_payload.split()) + else: + effective_scopes = tuple(scopes) + + return TokenRecord( + access_token=access_token, + refresh_token=refresh_token, + expires_at=expires_at, + scopes=effective_scopes, + token_type=str(payload.get("token_type", "Bearer")), + resource=resource, + authorization_server=authorization_server_url, + metadata={"raw": payload}, + ) + + +def _parse_callback_params(url: str) -> Dict[str, str]: + parsed = urlparse(url) + params = {} + params.update({k: v[-1] for k, v in parse_qs(parsed.query).items()}) + if parsed.fragment: + params.update({k: v[-1] for k, v in parse_qs(parsed.fragment).items()}) + return params + + +async def _send_auth_request( + context: Context, payload: Dict[str, Any] +) -> Dict[str, Any]: + session = getattr(context, "upstream_session", None) + if session and isinstance(session, ServerSession): + rpc = getattr(session, "rpc", None) + if rpc and hasattr(rpc, "request"): + return await rpc.request("auth/request", payload) + raise AuthorizationDeclined( + "No upstream MCP session available to prompt user for authorization" + ) diff --git a/src/mcp_agent/oauth/http/__init__.py b/src/mcp_agent/oauth/http/__init__.py new file mode 100644 index 000000000..60479ab9e --- /dev/null +++ b/src/mcp_agent/oauth/http/__init__.py @@ -0,0 +1,5 @@ +"""HTTP client helpers for OAuth flows.""" + +from .auth import OAuthHttpxAuth + +__all__ = ["OAuthHttpxAuth"] diff --git a/src/mcp_agent/oauth/http/auth.py b/src/mcp_agent/oauth/http/auth.py new file mode 100644 index 000000000..29b2028ce --- /dev/null +++ b/src/mcp_agent/oauth/http/auth.py @@ -0,0 +1,68 @@ +"""httpx.Auth adapter that acquires tokens via TokenManager.""" + +from __future__ import annotations + +import httpx + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from mcp_agent.oauth.manager import TokenManager + from mcp_agent.core.context import Context + + +class OAuthHttpxAuth(httpx.Auth): + requires_request_body = True + + def __init__( + self, + *, + token_manager: "TokenManager", + context: "Context", + server_name: str, + server_config, + scopes=None, + ) -> None: + self._token_manager = token_manager + self._context = context + self._server_name = server_name + self._server_config = server_config + self._scopes = list(scopes) if scopes is not None else None + + async def async_auth_flow(self, request: httpx.Request): + token_record = await self._token_manager.ensure_access_token( + context=self._context, + server_name=self._server_name, + server_config=self._server_config, + scopes=self._scopes, + ) + request.headers["Authorization"] = ( + f"{token_record.token_type} {token_record.access_token}" + ) + retry_request = request.copy() + response = yield request + + if response.status_code != 401: + return + + user = self._context.current_user + if user is None: + return + + await self._token_manager.invalidate( + user=user, + resource=token_record.resource or "", + authorization_server=token_record.authorization_server, + scopes=token_record.scopes, + ) + + refreshed_record = await self._token_manager.ensure_access_token( + context=self._context, + server_name=self._server_name, + server_config=self._server_config, + scopes=self._scopes, + ) + retry_request.headers["Authorization"] = ( + f"{refreshed_record.token_type} {refreshed_record.access_token}" + ) + yield retry_request diff --git a/src/mcp_agent/oauth/identity.py b/src/mcp_agent/oauth/identity.py new file mode 100644 index 000000000..54c6d6fed --- /dev/null +++ b/src/mcp_agent/oauth/identity.py @@ -0,0 +1,46 @@ +"""Utilities for representing authenticated MCP users.""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Dict + +from .access_token import MCPAccessToken + + +@dataclass(frozen=True) +class OAuthUserIdentity: + """Canonical identifier for an authenticated user within MCP Agent.""" + + provider: str + subject: str + email: str | None = None + claims: Dict[str, Any] | None = None + + @property + def cache_key(self) -> str: + """Return a deterministic cache key for token storage.""" + return f"{self.provider}:{self.subject}" + + @classmethod + def from_access_token( + cls, token: MCPAccessToken | None + ) -> "OAuthUserIdentity" | None: + """Build an identity from an enriched access token.""" + if token is None: + return None + subject = token.subject or _claim(token, "sub") + if not subject: + return None + provider = token.issuer or _claim(token, "iss") or "unknown" + email = ( + token.email or _claim(token, "email") or _claim(token, "preferred_username") + ) + claims = token.claims or {} + return cls(provider=provider, subject=subject, email=email, claims=claims) + + +def _claim(token: MCPAccessToken, key: str) -> Any | None: + if not token.claims: + return None + return token.claims.get(key) diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py new file mode 100644 index 000000000..62d0308b9 --- /dev/null +++ b/src/mcp_agent/oauth/manager.py @@ -0,0 +1,249 @@ +"""Token management for downstream OAuth-protected MCP servers.""" + +from __future__ import annotations + +import asyncio +import time +from collections import defaultdict +from typing import Dict, Iterable, Sequence, TYPE_CHECKING + +import httpx +from httpx import URL + +from mcp_agent.config import MCPOAuthClientSettings, OAuthSettings +from mcp_agent.logging.logger import get_logger +from mcp_agent.oauth.errors import ( + MissingUserIdentityError, + OAuthFlowError, + TokenRefreshError, +) +from mcp_agent.oauth.flow import AuthorizationFlowCoordinator +from mcp_agent.oauth.identity import OAuthUserIdentity +from mcp_agent.oauth.metadata import ( + fetch_authorization_server_metadata, + fetch_resource_metadata, + normalize_resource, + select_authorization_server, +) +from mcp_agent.oauth.records import TokenRecord +from mcp_agent.oauth.store import ( + InMemoryTokenStore, + TokenStore, + TokenStoreKey, + scope_fingerprint, +) + +if TYPE_CHECKING: + from mcp_agent.core.context import Context + +logger = get_logger(__name__) + + +class TokenManager: + """High-level orchestrator for acquiring and refreshing OAuth tokens.""" + + def __init__( + self, + *, + http_client: httpx.AsyncClient | None = None, + token_store: TokenStore | None = None, + settings: OAuthSettings | None = None, + ) -> None: + self._settings = settings or OAuthSettings() + self._token_store = token_store or InMemoryTokenStore() + self._http_client = http_client or httpx.AsyncClient(timeout=30.0) + self._own_http_client = http_client is None + self._flow = AuthorizationFlowCoordinator( + http_client=self._http_client, settings=self._settings + ) + self._locks: Dict[TokenStoreKey, asyncio.Lock] = defaultdict(asyncio.Lock) + self._resource_metadata_cache: Dict[str, tuple[float, object]] = {} + self._auth_metadata_cache: Dict[str, tuple[float, object]] = {} + + async def ensure_access_token( + self, + *, + context: "Context", + server_name: str, + server_config, + scopes: Iterable[str] | None = None, + ) -> TokenRecord: + oauth_config: MCPOAuthClientSettings | None = None + if server_config and server_config.auth: + oauth_config = getattr(server_config.auth, "oauth", None) + if not oauth_config or not oauth_config.enabled: + raise OAuthFlowError( + f"Server '{server_name}' is not configured for OAuth authentication" + ) + + user = context.current_user + if not user: + raise MissingUserIdentityError( + "No authenticated MCP user available for delegated OAuth flow" + ) + + resource_hint = oauth_config.resource + server_url = getattr(server_config, "url", None) + resource = normalize_resource(resource_hint, server_url) + + metadata_url = str(URL(resource).join("/.well-known/oauth-protected-resource")) + resource_metadata = await self._get_resource_metadata(metadata_url) + auth_server_url = select_authorization_server( + resource_metadata, oauth_config.authorization_server + ) + auth_metadata = await self._get_authorization_metadata(auth_server_url) + + scope_list = ( + list(scopes) if scopes is not None else list(oauth_config.scopes or []) + ) + key = TokenStoreKey( + user_key=user.cache_key, + resource=resource, + authorization_server=auth_server_url, + scope_fingerprint=scope_fingerprint(scope_list), + ) + + lock = self._locks[key] + async with lock: + record = await self._token_store.get(key) + leeway = ( + self._settings.token_store.refresh_leeway_seconds + if self._settings and self._settings.token_store + else 60 + ) + if record and not record.is_expired(leeway_seconds=leeway): + return record + + if record and record.refresh_token: + try: + refreshed = await self._refresh_token( + record, + oauth_config=oauth_config, + auth_metadata=auth_metadata, + resource=resource, + scopes=scope_list, + ) + except TokenRefreshError: + await self._token_store.delete(key) + else: + if refreshed: + await self._token_store.set(key, refreshed) + return refreshed + await self._token_store.delete(key) + + # Need to run full authorization flow + record = await self._flow.authorize( + context=context, + user=user, + server_name=server_name, + oauth_config=oauth_config, + resource=resource, + authorization_server_url=auth_server_url, + resource_metadata=resource_metadata, + auth_metadata=auth_metadata, + scopes=scope_list, + ) + await self._token_store.set(key, record) + return record + + async def invalidate( + self, + *, + user: OAuthUserIdentity, + resource: str, + authorization_server: str | None, + scopes: Iterable[str], + ) -> None: + key = TokenStoreKey( + user_key=user.cache_key, + resource=resource, + authorization_server=authorization_server, + scope_fingerprint=scope_fingerprint(scopes), + ) + await self._token_store.delete(key) + + async def _refresh_token( + self, + record: TokenRecord, + *, + oauth_config: MCPOAuthClientSettings, + auth_metadata, + resource: str, + scopes: Sequence[str], + ) -> TokenRecord | None: + if not record.refresh_token: + return None + + token_endpoint = str(auth_metadata.token_endpoint) + data = { + "grant_type": "refresh_token", + "refresh_token": record.refresh_token, + "client_id": oauth_config.client_id, + "resource": resource, + } + if scopes: + data["scope"] = " ".join(scopes) + if oauth_config.client_secret: + data["client_secret"] = oauth_config.client_secret + if oauth_config.extra_token_params: + data.update(oauth_config.extra_token_params) + + try: + response = await self._http_client.post(token_endpoint, data=data) + except httpx.HTTPError as exc: + logger.warning("Refresh token request failed", exc_info=True) + raise TokenRefreshError(str(exc)) from exc + + if response.status_code != 200: + logger.warning( + "Refresh token request returned non-success status", + data={"status_code": response.status_code}, + ) + return None + + payload = response.json() + new_access = payload.get("access_token") + if not new_access: + return None + new_refresh = payload.get("refresh_token", record.refresh_token) + expires_in = payload.get("expires_in") + new_expires = record.expires_at + if isinstance(expires_in, (int, float)): + new_expires = time.time() + float(expires_in) + + scope_from_payload = payload.get("scope") + if isinstance(scope_from_payload, str) and scope_from_payload.strip(): + scopes_tuple = tuple(scope_from_payload.split()) + else: + scopes_tuple = record.scopes + + return TokenRecord( + access_token=new_access, + refresh_token=new_refresh, + expires_at=new_expires, + scopes=scopes_tuple, + token_type=str(payload.get("token_type", record.token_type)), + resource=record.resource, + authorization_server=record.authorization_server, + metadata={"raw": payload}, + ) + + async def _get_resource_metadata(self, url: str): + cached = self._resource_metadata_cache.get(url) + if cached and time.time() - cached[0] < 300: + return cached[1] + metadata = await fetch_resource_metadata(self._http_client, url) + self._resource_metadata_cache[url] = (time.time(), metadata) + return metadata + + async def _get_authorization_metadata(self, url: str): + cached = self._auth_metadata_cache.get(url) + if cached and time.time() - cached[0] < 300: + return cached[1] + metadata = await fetch_authorization_server_metadata(self._http_client, url) + self._auth_metadata_cache[url] = (time.time(), metadata) + return metadata + + async def aclose(self) -> None: + if self._own_http_client: + await self._http_client.aclose() diff --git a/src/mcp_agent/oauth/metadata.py b/src/mcp_agent/oauth/metadata.py new file mode 100644 index 000000000..24ac6b5c8 --- /dev/null +++ b/src/mcp_agent/oauth/metadata.py @@ -0,0 +1,60 @@ +"""Helpers for OAuth metadata discovery.""" + +from __future__ import annotations + +from typing import List + +import httpx +from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata + +from mcp_agent.logging.logger import get_logger + +logger = get_logger(__name__) + + +async def fetch_resource_metadata( + client: httpx.AsyncClient, + resource_metadata_url: str, +) -> ProtectedResourceMetadata: + response = await client.get(resource_metadata_url) + response.raise_for_status() + data = response.json() + return ProtectedResourceMetadata.model_validate(data) + + +async def fetch_authorization_server_metadata( + client: httpx.AsyncClient, + metadata_url: str, +) -> OAuthMetadata: + response = await client.get(metadata_url) + response.raise_for_status() + return OAuthMetadata.model_validate(response.json()) + + +def select_authorization_server( + metadata: ProtectedResourceMetadata, + preferred: str | None = None, +) -> str: + candidates: List[str] = list(metadata.authorization_servers or []) + if not candidates: + raise ValueError( + "Protected resource metadata did not include authorization servers" + ) + + if preferred and preferred in candidates: + return preferred + + if preferred: + logger.warning( + "Preferred authorization server not listed; falling back to first entry", + data={"preferred": preferred, "candidates": candidates}, + ) + return candidates[0] + + +def normalize_resource(resource: str | None, fallback: str | None) -> str: + if resource: + return resource.rstrip("/") + if fallback: + return fallback.rstrip("/") + raise ValueError("Unable to determine resource identifier for OAuth flow") diff --git a/src/mcp_agent/oauth/pkce.py b/src/mcp_agent/oauth/pkce.py new file mode 100644 index 000000000..1709dc332 --- /dev/null +++ b/src/mcp_agent/oauth/pkce.py @@ -0,0 +1,27 @@ +"""PKCE utilities.""" + +from __future__ import annotations + +import base64 +import hashlib +import secrets + + +def generate_code_verifier(length: int = 64) -> str: + if length < 43 or length > 128: + raise ValueError("PKCE code verifier length must be between 43 and 128") + # token_urlsafe returns ~1.3 chars per byte; adjust to reach desired length + needed_bytes = int(length * 0.8) + 1 + verifier = secrets.token_urlsafe(needed_bytes) + if len(verifier) < length: + verifier = (verifier + secrets.token_urlsafe(needed_bytes))[:length] + return verifier[:length] + + +def generate_code_challenge(verifier: str) -> str: + digest = hashlib.sha256(verifier.encode()).digest() + return base64.urlsafe_b64encode(digest).rstrip(b"=").decode() + + +def generate_state(length: int = 32) -> str: + return secrets.token_urlsafe(length) diff --git a/src/mcp_agent/oauth/records.py b/src/mcp_agent/oauth/records.py new file mode 100644 index 000000000..2a7c47be0 --- /dev/null +++ b/src/mcp_agent/oauth/records.py @@ -0,0 +1,46 @@ +"""Shared record types for OAuth token management.""" + +from __future__ import annotations + +from datetime import datetime, timezone +from typing import Any, Dict, Tuple + +from pydantic import BaseModel, Field + + +class TokenRecord(BaseModel): + """Persisted token bundle for a user/resource/authorization server combination.""" + + access_token: str + refresh_token: str | None = None + scopes: Tuple[str, ...] = () + expires_at: float | None = None + token_type: str = "Bearer" + resource: str | None = None + authorization_server: str | None = None + obtained_at: float = Field( + default_factory=lambda: datetime.now(tz=timezone.utc).timestamp() + ) + metadata: Dict[str, Any] = Field(default_factory=dict) + + def is_expired(self, *, leeway_seconds: int = 0) -> bool: + if self.expires_at is None: + return False + now = datetime.now(tz=timezone.utc).timestamp() + return now >= (self.expires_at - leeway_seconds) + + def with_tokens( + self, + *, + access_token: str, + refresh_token: str | None, + expires_at: float | None, + ) -> "TokenRecord": + return self.model_copy( + update={ + "access_token": access_token, + "refresh_token": refresh_token, + "expires_at": expires_at, + "obtained_at": datetime.now(tz=timezone.utc).timestamp(), + } + ) diff --git a/src/mcp_agent/oauth/store/__init__.py b/src/mcp_agent/oauth/store/__init__.py new file mode 100644 index 000000000..226953f43 --- /dev/null +++ b/src/mcp_agent/oauth/store/__init__.py @@ -0,0 +1,11 @@ +"""Token store implementations.""" + +from .base import TokenStore, TokenStoreKey, scope_fingerprint +from .in_memory import InMemoryTokenStore + +__all__ = [ + "TokenStore", + "TokenStoreKey", + "scope_fingerprint", + "InMemoryTokenStore", +] diff --git a/src/mcp_agent/oauth/store/base.py b/src/mcp_agent/oauth/store/base.py new file mode 100644 index 000000000..a03f7da83 --- /dev/null +++ b/src/mcp_agent/oauth/store/base.py @@ -0,0 +1,33 @@ +"""Abstract token store definition.""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Iterable, Protocol + +from ..records import TokenRecord + + +@dataclass(frozen=True) +class TokenStoreKey: + """Uniquely identifies a cached token.""" + + user_key: str + resource: str + authorization_server: str | None + scope_fingerprint: str + + +def scope_fingerprint(scopes: Iterable[str]) -> str: + """Return a deterministic fingerprint for a scope list.""" + return " ".join(sorted({scope.strip() for scope in scopes if scope})) + + +class TokenStore(Protocol): + """Persistence interface for OAuth tokens.""" + + async def get(self, key: TokenStoreKey) -> TokenRecord | None: ... + + async def set(self, key: TokenStoreKey, record: TokenRecord) -> None: ... + + async def delete(self, key: TokenStoreKey) -> None: ... diff --git a/src/mcp_agent/oauth/store/in_memory.py b/src/mcp_agent/oauth/store/in_memory.py new file mode 100644 index 000000000..d1aa40460 --- /dev/null +++ b/src/mcp_agent/oauth/store/in_memory.py @@ -0,0 +1,30 @@ +"""In-memory token store for local development and testing.""" + +from __future__ import annotations + +import asyncio +from typing import Dict + +from .base import TokenStore, TokenStoreKey +from ..records import TokenRecord + + +class InMemoryTokenStore(TokenStore): + def __init__(self) -> None: + self._records: Dict[TokenStoreKey, TokenRecord] = {} + self._lock = asyncio.Lock() + + async def get(self, key: TokenStoreKey) -> TokenRecord | None: + async with self._lock: + record = self._records.get(key) + if record is None: + return None + return record + + async def set(self, key: TokenStoreKey, record: TokenRecord) -> None: + async with self._lock: + self._records[key] = record + + async def delete(self, key: TokenStoreKey) -> None: + async with self._lock: + self._records.pop(key, None) diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index d7d83e287..dfdbccd4c 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -12,8 +12,13 @@ import asyncio from mcp.server.fastmcp import Context as MCPContext, FastMCP +from mcp.server.fastmcp.server import AuthSettings +from mcp.server.auth.middleware.auth_context import ( + AuthenticatedUser, + auth_context_var, +) from starlette.requests import Request -from starlette.responses import JSONResponse +from starlette.responses import HTMLResponse, JSONResponse from mcp.server.fastmcp.exceptions import ToolError from mcp.server.fastmcp.tools import Tool as FastTool @@ -30,6 +35,9 @@ from mcp_agent.logging.logger import get_logger from mcp_agent.logging.logger import LoggingConfig from mcp_agent.mcp.mcp_server_registry import ServerRegistry +from mcp_agent.oauth.identity import OAuthUserIdentity +from mcp_agent.oauth.callbacks import callback_registry +from mcp_agent.server.token_verifier import MCPAgentTokenVerifier if TYPE_CHECKING: from mcp_agent.core.context import Context @@ -77,8 +85,8 @@ async def _get_session(execution_id: str) -> Any | None: try: logger.debug( ( - f"Lookup session for execution_id={execution_id}: " - + (f"found session_id={id(session)}" if session else "not found") + f"Lookup session for execution_id={execution_id}: " + + (f"found session_id={id(session)}" if session else "not found") ) ) except Exception: @@ -178,6 +186,32 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: # ctx.session property might raise ValueError if context not available pass + # Capture authenticated user information if available + identity: OAuthUserIdentity | None = None + try: + auth_user = auth_context_var.get() + except LookupError: + auth_user = None + + if isinstance(auth_user, AuthenticatedUser): + access_token = getattr(auth_user, "access_token", None) + if access_token is not None: + # Prefer enriched token instances but fall back to raw data if necessary + try: + from mcp_agent.oauth.access_token import MCPAccessToken + + if isinstance(access_token, MCPAccessToken): + identity = OAuthUserIdentity.from_access_token(access_token) + else: + token_dict = getattr(access_token, "model_dump", None) + if callable(token_dict): + maybe_token = MCPAccessToken.model_validate( + access_token.model_dump() + ) + identity = OAuthUserIdentity.from_access_token(maybe_token) + except Exception: + identity = None + if session is not None: app: MCPApp | None = _get_attached_app(ctx.fastmcp) if app is not None and getattr(app, "context", None) is not None: @@ -185,13 +219,19 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: # Previously captured; no need to keep old value # Use direct assignment for Pydantic model app.context.upstream_session = session + app.context.current_user = identity return else: return + else: + # Update identity even if we failed to resolve a session + app: MCPApp | None = _get_attached_app(ctx.fastmcp) + if app is not None and getattr(app, "context", None) is not None: + app.context.current_user = identity def _resolve_workflows_and_context( - ctx: MCPContext, + ctx: MCPContext, ) -> Tuple[Dict[str, Type["Workflow"]] | None, Optional["Context"]]: """Resolve the workflows mapping and underlying app context regardless of startup mode. @@ -201,9 +241,9 @@ def _resolve_workflows_and_context( # Try lifespan-provided ServerContext first lifespan_ctx = getattr(ctx.request_context, "lifespan_context", None) if ( - lifespan_ctx is not None - and hasattr(lifespan_ctx, "workflows") - and hasattr(lifespan_ctx, "context") + lifespan_ctx is not None + and hasattr(lifespan_ctx, "workflows") + and hasattr(lifespan_ctx, "context") ): # Ensure upstream session once at resolution time try: @@ -322,6 +362,34 @@ def create_mcp_server_for_app(app: MCPApp, **kwargs: Any) -> FastMCP: A configured FastMCP server instance """ + auth_settings_config = None + try: + if app.context and app.context.config: + auth_settings_config = app.context.config.authorization + except Exception: + auth_settings_config = None + + effective_auth_settings: AuthSettings | None = None + token_verifier: MCPAgentTokenVerifier | None = None + owns_token_verifier = False + if auth_settings_config and auth_settings_config.enabled: + try: + effective_auth_settings = AuthSettings( + issuer_url=auth_settings_config.issuer_url, # type: ignore[arg-type] + resource_server_url=auth_settings_config.resource_server_url, # type: ignore[arg-type] + service_documentation_url=auth_settings_config.service_documentation_url, # type: ignore[arg-type] + required_scopes=auth_settings_config.required_scopes or None, + ) + token_verifier = MCPAgentTokenVerifier(auth_settings_config) + except Exception as exc: + logger.error( + "Failed to configure authorization server integration", + exc_info=True, + data={"error": str(exc)}, + ) + effective_auth_settings = None + token_verifier = None + # Create a lifespan function specific to this app @asynccontextmanager async def app_specific_lifespan(mcp: FastMCP) -> AsyncIterator[ServerContext]: @@ -341,7 +409,11 @@ async def app_specific_lifespan(mcp: FastMCP) -> AsyncIterator[ServerContext]: yield server_context finally: # Don't clean up the MCPApp here - let the caller handle that - pass + if owns_token_verifier and token_verifier is not None: + try: + await token_verifier.aclose() + except Exception: + pass # Helper: install internal HTTP routes (not MCP tools) def _install_internal_routes(mcp_server: FastMCP) -> None: @@ -358,6 +430,41 @@ def _get_fallback_upstream_session() -> Any | None: return None return None + @mcp_server.custom_route( + "/internal/oauth/callback/{flow_id}", + methods=["GET", "POST"], + include_in_schema=False, + ) + async def _oauth_callback(request: Request): + flow_id = request.path_params.get("flow_id") + if not flow_id: + return JSONResponse({"error": "missing_flow_id"}, status_code=400) + + payload: Dict[str, Any] = {} + try: + payload.update({k: v for k, v in request.query_params.multi_items()}) + except Exception: + payload.update(dict(request.query_params)) + + if request.method.upper() == "POST": + content_type = request.headers.get("content-type", "") + try: + if "application/json" in content_type: + body_data = await request.json() + else: + form = await request.form() + body_data = {k: v for k, v in form.multi_items()} + except Exception: + body_data = {} + payload.update(body_data) + + delivered = await callback_registry.deliver(flow_id, payload) + if not delivered: + return JSONResponse({"error": "unknown_flow"}, status_code=404) + + html = """

Authorization complete.

You may close this window and return to MCP Agent.

""" + return HTMLResponse(html) + @mcp_server.custom_route( "/internal/session/by-run/{execution_id}/notify", methods=["POST"], @@ -525,9 +632,7 @@ def _check_gateway_auth(request: Request) -> JSONResponse | None: bearer = request.headers.get("Authorization", "") bearer_token = ( - bearer.split(" ", 1)[1] - if bearer.lower().startswith("bearer ") - else "" + bearer.split(" ", 1)[1] if bearer.lower().startswith("bearer ") else "" ) header_tok = request.headers.get("X-MCP-Gateway-Token", "") @@ -542,57 +647,100 @@ def _check_gateway_auth(request: Request) -> JSONResponse | None: return None # Auth passed # Helper functions for request handling - async def _handle_request_via_rpc(session, method: str, params: dict, execution_id: str, - log_prefix: str = "request"): + async def _handle_request_via_rpc( + session, + method: str, + params: dict, + execution_id: str, + log_prefix: str = "request", + ): """Handle request via generic RPC if available.""" rpc = getattr(session, "rpc", None) if rpc and hasattr(rpc, "request"): result = await rpc.request(method, params) - logger.debug(f"[{log_prefix}] delivered via session_id={id(session)} (generic '{method}')") + logger.debug( + f"[{log_prefix}] delivered via session_id={id(session)} (generic '{method}')" + ) return result return None - async def _handle_specific_request(session, method: str, params: dict, log_prefix: str = "request"): + async def _handle_specific_request( + session, method: str, params: dict, log_prefix: str = "request" + ): """Handle specific request types with structured request/response.""" from mcp.types import ( - CreateMessageRequest, CreateMessageRequestParams, CreateMessageResult, - ElicitRequest, ElicitRequestParams, ElicitResult, - ListRootsRequest, ListRootsResult, - PingRequest, EmptyResult, ServerRequest + CreateMessageRequest, + CreateMessageRequestParams, + CreateMessageResult, + ElicitRequest, + ElicitRequestParams, + ElicitResult, + ListRootsRequest, + ListRootsResult, + PingRequest, + EmptyResult, + ServerRequest, ) if method == "sampling/createMessage": req = ServerRequest( - CreateMessageRequest(method="sampling/createMessage", params=CreateMessageRequestParams(**params))) - result = await session.send_request(request=req, - result_type=CreateMessageResult) # type: ignore[attr-defined] + CreateMessageRequest( + method="sampling/createMessage", + params=CreateMessageRequestParams(**params), + ) + ) + result = await session.send_request( + request=req, result_type=CreateMessageResult + ) # type: ignore[attr-defined] return result.model_dump(by_alias=True, mode="json", exclude_none=True) elif method == "elicitation/create": - req = ServerRequest(ElicitRequest(method="elicitation/create", params=ElicitRequestParams(**params))) - result = await session.send_request(request=req, result_type=ElicitResult) # type: ignore[attr-defined] + req = ServerRequest( + ElicitRequest( + method="elicitation/create", + params=ElicitRequestParams(**params), + ) + ) + result = await session.send_request( + request=req, result_type=ElicitResult + ) # type: ignore[attr-defined] return result.model_dump(by_alias=True, mode="json", exclude_none=True) elif method == "roots/list": req = ServerRequest(ListRootsRequest(method="roots/list")) - result = await session.send_request(request=req, - result_type=ListRootsResult) # type: ignore[attr-defined] + result = await session.send_request( + request=req, result_type=ListRootsResult + ) # type: ignore[attr-defined] return result.model_dump(by_alias=True, mode="json", exclude_none=True) elif method == "ping": req = ServerRequest(PingRequest(method="ping")) - result = await session.send_request(request=req, result_type=EmptyResult) # type: ignore[attr-defined] + result = await session.send_request( + request=req, result_type=EmptyResult + ) # type: ignore[attr-defined] return result.model_dump(by_alias=True, mode="json", exclude_none=True) else: raise ValueError(f"unsupported method: {method}") - async def _try_session_request(session, method: str, params: dict, execution_id: str, - log_prefix: str = "request", register_session: bool = False): + async def _try_session_request( + session, + method: str, + params: dict, + execution_id: str, + log_prefix: str = "request", + register_session: bool = False, + ): """Try to handle a request via session, with optional registration.""" try: # First try generic RPC passthrough - result = await _handle_request_via_rpc(session, method, params, execution_id, log_prefix) + result = await _handle_request_via_rpc( + session, method, params, execution_id, log_prefix + ) if result is not None: if register_session: try: - await _register_session(run_id=execution_id, execution_id=execution_id, session=session) + await _register_session( + run_id=execution_id, + execution_id=execution_id, + session=session, + ) # logger.debug( # f"[{log_prefix}] rebound mapping to session_id={id(session)} for execution_id={execution_id}") except Exception: @@ -600,10 +748,16 @@ async def _try_session_request(session, method: str, params: dict, execution_id: return result # Fallback to specific structured request handling - result = await _handle_specific_request(session, method, params, log_prefix) + result = await _handle_specific_request( + session, method, params, log_prefix + ) if register_session: try: - await _register_session(run_id=execution_id, execution_id=execution_id, session=session) + await _register_session( + run_id=execution_id, + execution_id=execution_id, + session=session, + ) # logger.debug( # f"[{log_prefix}] rebound mapping to session_id={id(session)} for execution_id={execution_id}") except Exception: @@ -613,7 +767,8 @@ async def _try_session_request(session, method: str, params: dict, execution_id: if "unsupported method" in str(e): raise # Re-raise unsupported method errors logger.warning( - f"[{log_prefix}] session delivery failed for execution_id={execution_id} method={method}: {e}") + f"[{log_prefix}] session delivery failed for execution_id={execution_id} method={method}: {e}" + ) raise @mcp_server.custom_route( @@ -637,33 +792,48 @@ async def _relay_request(request: Request): if latest_session is not None: try: result = await _try_session_request( - latest_session, method, params, execution_id, - log_prefix="request", register_session=True + latest_session, + method, + params, + execution_id, + log_prefix="request", + register_session=True, ) return JSONResponse(result) except Exception as e_latest: # Only log and continue to fallback if it's not an unsupported method error if "unsupported method" not in str(e_latest): logger.warning( - f"[request] latest session delivery failed for execution_id={execution_id} method={method}: {e_latest}") + f"[request] latest session delivery failed for execution_id={execution_id} method={method}: {e_latest}" + ) # Fallback to mapped session session = await _get_session(execution_id) if not session: - logger.warning(f"[request] session_not_available for execution_id={execution_id}") + logger.warning( + f"[request] session_not_available for execution_id={execution_id}" + ) return JSONResponse({"error": "session_not_available"}, status_code=503) try: result = await _try_session_request( - session, method, params, execution_id, - log_prefix="request", register_session=False + session, + method, + params, + execution_id, + log_prefix="request", + register_session=False, ) return JSONResponse(result) except Exception as e: if "unsupported method" in str(e): - return JSONResponse({"error": f"unsupported method: {method}"}, status_code=400) + return JSONResponse( + {"error": f"unsupported method: {method}"}, status_code=400 + ) try: - logger.error(f"[request] error forwarding for execution_id={execution_id} method={method}: {e}") + logger.error( + f"[request] error forwarding for execution_id={execution_id} method={method}: {e}" + ) except Exception: pass return JSONResponse({"error": str(e)}, status_code=500) @@ -687,14 +857,18 @@ async def _async_relay_request(request: Request): return auth_error try: - logger.info(f"[async-request] incoming execution_id={execution_id} method={method}") + logger.info( + f"[async-request] incoming execution_id={execution_id} method={method}" + ) except Exception: pass if method != "sampling/createMessage" and method != "elicitation/create": logger.error(f"async not supported for method {method}") - return JSONResponse({"error": f"async not supported for method {method}"}, - status_code=405) + return JSONResponse( + {"error": f"async not supported for method {method}"}, + status_code=405, + ) if not signal_name: return JSONResponse({"error": "missing_signal_name"}, status_code=400) @@ -709,11 +883,17 @@ async def _handle_async_request_task(): if latest_session is not None: try: result = await _try_session_request( - latest_session, method, params, execution_id, - log_prefix="async-request", register_session=True + latest_session, + method, + params, + execution_id, + log_prefix="async-request", + register_session=True, ) except Exception as e_latest: - logger.warning(f"[async-request] latest session delivery failed for execution_id={execution_id} method={method}: {e_latest}") + logger.warning( + f"[async-request] latest session delivery failed for execution_id={execution_id} method={method}: {e_latest}" + ) # Fallback to mapped session if latest session failed if result is None: @@ -721,37 +901,48 @@ async def _handle_async_request_task(): if session: try: result = await _try_session_request( - session, method, params, execution_id, - log_prefix="async-request", register_session=False + session, + method, + params, + execution_id, + log_prefix="async-request", + register_session=False, ) except Exception as e: - logger.error(f"[async-request] error forwarding for execution_id={execution_id} method={method}: {e}") + logger.error( + f"[async-request] error forwarding for execution_id={execution_id} method={method}: {e}" + ) result = {"error": str(e)} else: - logger.warning(f"[async-request] session_not_available for execution_id={execution_id}") + logger.warning( + f"[async-request] session_not_available for execution_id={execution_id}" + ) result = {"error": "session_not_available"} # Signal the workflow with the result using method-specific signal try: # Try to get Temporal client from the app context app = _get_attached_app(mcp_server) - if app and app.context and hasattr(app.context, 'executor'): + if app and app.context and hasattr(app.context, "executor"): executor = app.context.executor - if hasattr(executor, 'client'): + if hasattr(executor, "client"): client = executor.client # Find the workflow using execution_id as both workflow_id and run_id try: workflow_handle = client.get_workflow_handle( - workflow_id=workflow_id, - run_id=execution_id + workflow_id=workflow_id, run_id=execution_id ) await workflow_handle.signal(signal_name, result) - logger.info(f"[async-request] signaled workflow {execution_id} " - f"with {method} result using signal") + logger.info( + f"[async-request] signaled workflow {execution_id} " + f"with {method} result using signal" + ) except Exception as signal_error: - logger.warning(f"[async-request] failed to signal workflow {execution_id}:" - f" {signal_error}") + logger.warning( + f"[async-request] failed to signal workflow {execution_id}:" + f" {signal_error}" + ) except Exception as e: logger.error(f"[async-request] failed to signal workflow: {e}") @@ -763,7 +954,12 @@ async def _handle_async_request_task(): # Return immediately with 200 status to indicate request was received return JSONResponse( - {"status": "received", "execution_id": execution_id, "method": method, "signal_name": signal_name} + { + "status": "received", + "execution_id": execution_id, + "method": method, + "signal_name": signal_name, + } ) @mcp_server.custom_route( @@ -950,6 +1146,11 @@ async def _internal_human_prompts(request: Request): except Exception: pass else: + if "auth" not in kwargs and effective_auth_settings is not None: + kwargs["auth"] = effective_auth_settings + if "token_verifier" not in kwargs and token_verifier is not None: + kwargs["token_verifier"] = token_verifier + owns_token_verifier = True mcp = FastMCP( name=app.name or "mcp_agent_server", # TODO: saqadri (MAC) - create a much more detailed description @@ -976,7 +1177,7 @@ async def _internal_human_prompts(request: Request): @lowlevel_server.set_logging_level() async def _set_level( - level: str, + level: str, ) -> None: # mcp.types.LoggingLevel is a Literal[str] try: LoggingConfig.set_min_level(level) @@ -1091,10 +1292,10 @@ async def list_workflow_runs( @mcp.tool(name="workflows-run") async def run_workflow( - ctx: MCPContext, - workflow_name: str, - run_parameters: Dict[str, Any] | None = None, - **kwargs: Any, + ctx: MCPContext, + workflow_name: str, + run_parameters: Dict[str, Any] | None = None, + **kwargs: Any, ) -> Dict[str, str]: """ Run a workflow with the given name. @@ -1118,9 +1319,9 @@ async def run_workflow( @mcp.tool(name="workflows-get_status") async def get_workflow_status( - ctx: MCPContext, - run_id: str | None = None, - workflow_id: str | None = None, + ctx: MCPContext, + run_id: str | None = None, + workflow_id: str | None = None, ) -> Dict[str, Any]: """ Get the status of a running workflow. @@ -1158,11 +1359,11 @@ async def get_workflow_status( @mcp.tool(name="workflows-resume") async def resume_workflow( - ctx: MCPContext, - run_id: str | None = None, - workflow_id: str | None = None, - signal_name: str | None = "resume", - payload: Dict[str, Any] | None = None, + ctx: MCPContext, + run_id: str | None = None, + workflow_id: str | None = None, + signal_name: str | None = "resume", + payload: Dict[str, Any] | None = None, ) -> bool: """ Resume a paused workflow. @@ -1232,7 +1433,7 @@ async def resume_workflow( @mcp.tool(name="workflows-cancel") async def cancel_workflow( - ctx: MCPContext, run_id: str | None = None, workflow_id: str | None = None + ctx: MCPContext, run_id: str | None = None, workflow_id: str | None = None ) -> bool: """ Cancel a running workflow. @@ -1362,14 +1563,14 @@ def create_declared_function_tools(mcp: FastMCP, server_context: ServerContext): import time async def _wait_for_completion( - ctx: MCPContext, - run_id: str, - *, - workflow_id: str | None = None, - timeout: float | None = None, - registration_grace: float = 1.0, - poll_initial: float = 0.05, - poll_max: float = 1.0, + ctx: MCPContext, + run_id: str, + *, + workflow_id: str | None = None, + timeout: float | None = None, + registration_grace: float = 1.0, + poll_initial: float = 0.05, + poll_max: float = 1.0, ): registry = _resolve_workflow_registry(ctx) if not registry: @@ -1462,8 +1663,8 @@ async def _wrapper(**kwargs): return getattr(result, "value", None) # If status payload returned a dict that looks like WorkflowResult, unwrap safely via 'kind' if ( - isinstance(result, dict) - and result.get("kind") == "workflow_result" + isinstance(result, dict) + and result.get("kind") == "workflow_result" ): return result.get("value") return result @@ -1569,9 +1770,9 @@ async def _async_wrapper(**kwargs): if p.name in ("ctx", "context"): continue if ( - _Ctx is not None - and p.annotation is not inspect._empty - and p.annotation is _Ctx + _Ctx is not None + and p.annotation is not inspect._empty + and p.annotation is _Ctx ): continue params.append(p) @@ -1624,7 +1825,7 @@ async def _adapter(**kw): def create_workflow_specific_tools( - mcp: FastMCP, workflow_name: str, workflow_cls: Type["Workflow"] + mcp: FastMCP, workflow_name: str, workflow_cls: Type["Workflow"] ): """Create specific tools for a given workflow.""" param_source = _get_param_source_function_from_workflow(workflow_cls) @@ -1673,8 +1874,8 @@ def _schema_fn_proxy(*args, **kwargs): """, ) async def run( - ctx: MCPContext, - run_parameters: Dict[str, Any] | None = None, + ctx: MCPContext, + run_parameters: Dict[str, Any] | None = None, ) -> Dict[str, str]: _set_upstream_from_request_ctx_if_available(ctx) return await _workflow_run(ctx, workflow_name, run_parameters) @@ -1684,7 +1885,7 @@ async def run( def _get_server_descriptions( - server_registry: ServerRegistry | None, server_names: List[str] + server_registry: ServerRegistry | None, server_names: List[str] ) -> List: servers: List[dict[str, str]] = [] if server_registry: @@ -1706,7 +1907,7 @@ def _get_server_descriptions( def _get_server_descriptions_as_string( - server_registry: ServerRegistry | None, server_names: List[str] + server_registry: ServerRegistry | None, server_names: List[str] ) -> str: servers = _get_server_descriptions(server_registry, server_names) @@ -1726,10 +1927,10 @@ def _get_server_descriptions_as_string( async def _workflow_run( - ctx: MCPContext, - workflow_name: str, - run_parameters: Dict[str, Any] | None = None, - **kwargs: Any, + ctx: MCPContext, + workflow_name: str, + run_parameters: Dict[str, Any] | None = None, + **kwargs: Any, ) -> Dict[str, str]: # Use Temporal run_id as the routing key for gateway callbacks. # We don't have it until after the workflow is started; we'll register mapping post-start. @@ -1899,7 +2100,7 @@ def _normalize_gateway_url(url: str | None) -> str | None: async def _workflow_status( - ctx: MCPContext, run_id: str | None = None, workflow_id: str | None = None + ctx: MCPContext, run_id: str | None = None, workflow_id: str | None = None ) -> Dict[str, Any]: # Ensure upstream session so status-related logs are forwarded try: @@ -1939,4 +2140,5 @@ async def _workflow_status( return status + # endregion diff --git a/src/mcp_agent/server/token_verifier.py b/src/mcp_agent/server/token_verifier.py new file mode 100644 index 000000000..324f389b6 --- /dev/null +++ b/src/mcp_agent/server/token_verifier.py @@ -0,0 +1,138 @@ +"""Token verification for MCP Agent Cloud authorization server.""" + +from __future__ import annotations + +import asyncio +from datetime import datetime, timezone +from typing import Any, Dict + +import httpx + +from mcp.server.auth.provider import AccessToken +from mcp.server.auth.provider import TokenVerifier + +from mcp_agent.config import MCPAuthorizationServerSettings +from mcp_agent.logging.logger import get_logger +from mcp_agent.oauth.access_token import MCPAccessToken + +logger = get_logger(__name__) + + +class MCPAgentTokenVerifier(TokenVerifier): + """Verify bearer tokens issued by the MCP Agent Cloud authorization server.""" + + def __init__(self, settings: MCPAuthorizationServerSettings): + if not settings.introspection_endpoint: + raise ValueError( + "introspection_endpoint must be configured to verify tokens" + ) + self._settings = settings + timeout = httpx.Timeout(10.0) + self._client = httpx.AsyncClient(timeout=timeout) + self._cache: Dict[str, MCPAccessToken] = {} + self._lock = asyncio.Lock() + + async def verify_token(self, token: str) -> AccessToken | None: # type: ignore[override] + cached = self._cache.get(token) + if cached and not cached.is_expired(leeway_seconds=30): + return cached + + async with self._lock: + # Double-check cache after acquiring lock to avoid duplicate refresh + cached = self._cache.get(token) + if cached and not cached.is_expired(leeway_seconds=30): + return cached + + verified = await self._introspect(token) + if verified: + self._cache[token] = verified + else: + self._cache.pop(token, None) + return verified + + async def _introspect(self, token: str) -> MCPAccessToken | None: + data = {"token": token} + auth = None + if ( + self._settings.introspection_client_id + and self._settings.introspection_client_secret + ): + auth = httpx.BasicAuth( + self._settings.introspection_client_id, + self._settings.introspection_client_secret, + ) + + try: + response = await self._client.post( + str(self._settings.introspection_endpoint), + data=data, + auth=auth, + ) + except httpx.HTTPError as exc: + logger.warning(f"Token introspection request failed: {exc}") + return None + + if response.status_code != 200: + logger.warning( + "Token introspection returned non-success status", + data={"status_code": response.status_code}, + ) + return None + + try: + payload: Dict[str, Any] = response.json() + except ValueError: + logger.warning("Token introspection response was not valid JSON") + return None + + if not payload.get("active"): + return None + + if self._settings.issuer_url and payload.get("iss"): + if str(payload.get("iss")) != str(self._settings.issuer_url): + logger.warning( + "Token issuer mismatch", + data={ + "expected": str(self._settings.issuer_url), + "actual": payload.get("iss"), + }, + ) + return None + + token_model = MCPAccessToken.from_introspection( + token, + payload, + resource_hint=str(self._settings.resource_server_url) + if self._settings.resource_server_url + else None, + ) + + # Respect cache TTL limit if configured + ttl_seconds = max(0, self._settings.token_cache_ttl_seconds or 0) + if ttl_seconds and token_model.expires_at is not None: + now_ts = datetime.now(tz=timezone.utc).timestamp() + cache_limit = now_ts + ttl_seconds + token_model.expires_at = min(token_model.expires_at, cache_limit) + + # Optionally enforce required scopes + required_scopes = self._settings.required_scopes or [] + missing = [ + scope for scope in required_scopes if scope not in token_model.scopes + ] + if missing: + logger.warning( + "Token missing required scopes", + data={"missing_scopes": missing}, + ) + return None + + return token_model + + async def aclose(self) -> None: + await self._client.aclose() + + async def __aenter__(self) -> "MCPAgentTokenVerifier": + return self + + async def __aexit__(self, exc_type, exc, tb) -> None: + await self.aclose() diff --git a/tests/test_oauth_utils.py b/tests/test_oauth_utils.py new file mode 100644 index 000000000..87488c41a --- /dev/null +++ b/tests/test_oauth_utils.py @@ -0,0 +1,85 @@ +import time +import pathlib +import sys + +import pytest + +PROJECT_ROOT = pathlib.Path(__file__).resolve().parents[1] +SRC_ROOT = PROJECT_ROOT / "src" +if str(SRC_ROOT) not in sys.path: + sys.path.insert(0, str(SRC_ROOT)) + +try: + from mcp_agent.oauth.metadata import normalize_resource, select_authorization_server + from mcp_agent.oauth.records import TokenRecord + from mcp_agent.oauth.store import ( + InMemoryTokenStore, + TokenStoreKey, + scope_fingerprint, + ) + from mcp.shared.auth import ProtectedResourceMetadata +except ModuleNotFoundError: # pragma: no cover - optional dependency + pytest.skip("MCP SDK not installed", allow_module_level=True) + + +def test_scope_fingerprint_ordering(): + scopes = ["email", "profile", "email"] + fingerprint = scope_fingerprint(scopes) + assert fingerprint == "email profile" + + +def test_token_record_expiry(): + record = TokenRecord( + access_token="tok", + expires_at=time.time() + 5, + ) + assert not record.is_expired(leeway_seconds=0) + assert record.is_expired(leeway_seconds=10) + + +@pytest.mark.asyncio +async def test_in_memory_token_store_round_trip(): + store = InMemoryTokenStore() + key = TokenStoreKey( + user_key="provider:subject", + resource="https://example.com", + authorization_server="https://auth.example.com", + scope_fingerprint="scope", + ) + record = TokenRecord(access_token="abc123") + + await store.set(key, record) + fetched = await store.get(key) + assert fetched.access_token == record.access_token + await store.delete(key) + assert await store.get(key) is None + + +def test_select_authorization_server_prefers_explicit(): + metadata = ProtectedResourceMetadata( + resource="https://example.com", + authorization_servers=[ + "https://auth1.example.com", + "https://auth2.example.com", + ], + ) + assert ( + select_authorization_server(metadata, "https://auth2.example.com") + == "https://auth2.example.com" + ) + assert ( + select_authorization_server(metadata, "https://unknown.example.com") + == "https://auth1.example.com" + ) + + +def test_normalize_resource_with_fallback(): + assert ( + normalize_resource("https://example.com/api", None) == "https://example.com/api" + ) + assert ( + normalize_resource(None, "https://fallback.example.com") + == "https://fallback.example.com" + ) + with pytest.raises(ValueError): + normalize_resource(None, None) From 59b1251dbb759d62541b1a8c507ce4459fa51c16 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 23 Sep 2025 18:23:52 -0400 Subject: [PATCH 03/25] Fix workflow resume issue --- src/mcp_agent/executor/workflow.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mcp_agent/executor/workflow.py b/src/mcp_agent/executor/workflow.py index ad5515730..af46f64bd 100644 --- a/src/mcp_agent/executor/workflow.py +++ b/src/mcp_agent/executor/workflow.py @@ -431,7 +431,6 @@ async def cancel(self) -> bool: return False if temporal_workflow is not None: - @temporal_workflow.signal(dynamic=True) async def _signal_receiver(self, name: str, args: Sequence[RawValue]): """Dynamic signal handler for Temporal workflows.""" From f5ccb741c28b76b3e8decdb505005cf3ed3113c5 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 23 Sep 2025 18:24:41 -0400 Subject: [PATCH 04/25] temp wip --- auth_spec.png | Bin 0 -> 415449 bytes docs/configuration.mdx | 43 ++++ docs/oauth_support_design.md | 108 ++++++++++ src/mcp_agent/app.py | 40 +++- src/mcp_agent/config.py | 89 +++++++- src/mcp_agent/core/context.py | 20 ++ src/mcp_agent/mcp/mcp_server_registry.py | 19 ++ src/mcp_agent/oauth/__init__.py | 19 ++ src/mcp_agent/oauth/access_token.py | 82 ++++++++ src/mcp_agent/oauth/callbacks.py | 53 +++++ src/mcp_agent/oauth/errors.py | 21 ++ src/mcp_agent/oauth/flow.py | 218 ++++++++++++++++++++ src/mcp_agent/oauth/http/__init__.py | 5 + src/mcp_agent/oauth/http/auth.py | 68 +++++++ src/mcp_agent/oauth/identity.py | 46 +++++ src/mcp_agent/oauth/manager.py | 249 +++++++++++++++++++++++ src/mcp_agent/oauth/metadata.py | 60 ++++++ src/mcp_agent/oauth/pkce.py | 27 +++ src/mcp_agent/oauth/records.py | 46 +++++ src/mcp_agent/oauth/store/__init__.py | 11 + src/mcp_agent/oauth/store/base.py | 33 +++ src/mcp_agent/oauth/store/in_memory.py | 30 +++ src/mcp_agent/server/app_server.py | 116 ++++++++++- src/mcp_agent/server/token_verifier.py | 138 +++++++++++++ tests/test_oauth_utils.py | 85 ++++++++ 25 files changed, 1622 insertions(+), 4 deletions(-) create mode 100644 auth_spec.png create mode 100644 docs/oauth_support_design.md create mode 100644 src/mcp_agent/oauth/__init__.py create mode 100644 src/mcp_agent/oauth/access_token.py create mode 100644 src/mcp_agent/oauth/callbacks.py create mode 100644 src/mcp_agent/oauth/errors.py create mode 100644 src/mcp_agent/oauth/flow.py create mode 100644 src/mcp_agent/oauth/http/__init__.py create mode 100644 src/mcp_agent/oauth/http/auth.py create mode 100644 src/mcp_agent/oauth/identity.py create mode 100644 src/mcp_agent/oauth/manager.py create mode 100644 src/mcp_agent/oauth/metadata.py create mode 100644 src/mcp_agent/oauth/pkce.py create mode 100644 src/mcp_agent/oauth/records.py create mode 100644 src/mcp_agent/oauth/store/__init__.py create mode 100644 src/mcp_agent/oauth/store/base.py create mode 100644 src/mcp_agent/oauth/store/in_memory.py create mode 100644 src/mcp_agent/server/token_verifier.py create mode 100644 tests/test_oauth_utils.py diff --git a/auth_spec.png b/auth_spec.png new file mode 100644 index 0000000000000000000000000000000000000000..9bd276c46e5e9eae0113935298a0e4474d7fb76a GIT binary patch literal 415449 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

E?AaYo*e_l8!Qq43%NErNgHy9OW+BP;=7??kf zf{S*2$y-RsINV0t%6o`r%SFVjYR_t2y0D~XeQrqK@8&ljZ{U{U|M`g2!*{T2db3;A zs_WMN-Cs8PVjrreW)@*u^0WFnTxYXvBQ}%kUzdjI9|Xii((ZSDi@Uz}wMVPHbBPrh zb8!s5AgK&byyqK(@!GaFQVm0O5BDqqIPiJ>L2Rw%y<|J)h-7XdY4#lqwH;~IY)yv{ zdyfo{{-o)KAqUgxPgM&QM_1!q>7u3{%FT zF96>a)4}i`b+v&-GrW$8T!wiFu2Mfc`H)7BZ`9u39n>Z0`>mi~2k zfzP7%LFo3d#QXT@!FoJ$8D4~!k7@qy)szht!3!-?j~vp;EK|(fzS1rzr<=Vm3D2?f z1(xcCd$ZXL!3p0=*Yv!#d5Jc;P2=7iKe3ydfuDMMiAGC@&%>%Z3FkV_%~3D8=!)oi z|5sM_$=Z_IxgK=EA7A(CHw0Pb8-FRae{Any{lyULTi5=uX9prkb=9Ne8?DlKtL45L zo?z1z0@W$jC%nXl2xo~35SS%%EiT-dNzJ$1kP%wbds)tXe%n@d!{cOzIPY|O`I5`2 z2a$ps9WYlf)&Jk<&Vg!T45>23Dr|E>ZVc9)ls+~sS z8?8tKecZHHu;b3)S_#DR#?Li>Aq#$42ql^!|9? z_%}b?OSkG>luyXp*qwP7Gw--`^ib-p)JC(G8%$e)NwI$3{m#bvwjf$g`q z278d#Mfz3cWLmh2SX+A!S%K%tkn82MpVJ@rTE<(4uSKBxzNR7Ly9-xZR#V$ZLK~FC zZRqa^X2|ykEN{-B8M_4( zksph9fmhHYekx++7o#WU+eG+(xyZgOjUu8Bw<1)Xu*-}l+ zI(}!-dUqa%Xtg%SK$l_BOYWpRG`vu1LEmr@3VB1TPhp<%!C(p};a3u~A) zK9qsf;h$@+qwf>wFVIjswq1NA$T%-_Kk%UGW(j;KNiJhT(-)s4_emryl#FRAFGCzV z(u=;6`0A(0FYo_FGN_4r`Ne*Kdc4i52yWav{oQt=iQGG){f}H^NbbMk6RuvjRy1-j z*~SaPt#FR;|2{v3@ZFs{iPHL@VURIw19p<1bL%AN6Q037jd1hhHYH&tuU`dPx|nuT z{~eo_NX4$X#*RNGf({w_f0b*E@cmw?9r3$&ppcFpOnIfnck)O#`MeDPv=24EfDI!`)5y(><= zQoHL)R~bKrqkaBv#Sqv0r^32osG#?C#y878GS6MpymXKFy@nmKz7%>Qx(`4AM0^Z5 zkJFe?f}CtglJ6{-s+_v?-{U|^j42+o6hQ{!<1>==_%eFThcW(yG~!^c{N*;PKH^Wi z1{vC3qMGa9Ykg6kq2F};7#Z$!pqt1429dnK>ppMXAHi#hltMT?>oX1_^|@3M$)xEx zg80(U%*@wJuOoiP?eX%p&(wj(5)n_IKKhyRjt#!UuPIbYcj^p#?L`VUe)UTiG9DhX z+3k&X9!$;TVGoLXo}~@LpqQYz8;$M2J4bH&&;Xm6Or>gmIm^#d1^33Sx3}4gPId=T zQ}25E0i_}!!{44PC86Vs^>H#-&h3|E$ zn>Lu&3y+8)#uBf6Zg6d#xc%#%ij1NLth3LfdF`8>3_+RppFBC|G+@*_0s~ zO2<9OU@qRpiWMGy>%~*|Vi_@7`_%XD`m7Tao`}vjjCPbjuks@nc34uIo~T=p9%Ces z*z|>a_*<-=3ah~5=s3Ahn>WWH#eb^e8deOWcD{IzNtuLBn8&f?38lFIVaw=skbO|J z3{xftteU741CCu@Xf+j%e8s3&XD3ge4Lb))nI-f%xd#rgA&}Z@V`N_zWt`zuCbSN=*)VTAfp67r@*DlO6cxXjQ)519Xg+< ziC5KVp2wt8FFYb27jYI(t+whcFjx7SKJ5<71E_KQ$C1WOR$daU)NQ&cZA3Ns zmr*_hm(NyhIJZZ>n&otSI5@uv0Eg4<&L6bY<}JDg1~!`xQ0YJfc}zs}8rVJ@t#or8 zrLgU-sRzT4og5F8A-90Nh@LG#PdYD_gSUf#AiMhQgW0TJ2PA%^pse*?8MCObhuSHn z9609~rRCH>1`uXhr7;+=`D zA9p!#jpHJ^53mPvXfJKP-+Z#XsklP#MfD+Kqm!?t5UkzPbyF}8jhNC-N8O$XEDIi- zLD(mdJ-REi7ou#by3$L=)0YoMZ98kS=8`?=4uF=k%s!eS=x0bQ(ey`nCwSYSc`MEMTmCfAyui-?2^{(HIkyA1qWLl9}(F`E$A{j|r~ zw)^WI)AqY2yzI1n)xVH(&9_IK4S6!;*2Q>v2%*PK|Uf^HfxEV z4>XC&tq)h9IX@W@no&_eL!S+&OLvpWAD4zhw|=9)l=2(S_F(B^E`scR^k?!ZZgINX zfs-Hjw^f%fEYw%Mpm3^uzE`F(Q-zv*hXJt5foL{=ntn;0Tkm>w$D5{YY>|z&AI$W& zXKZbRU_eSUsO}|d^M`isyBnOv7(TqYy}QuY>v#K>z*S0c`}LBb{@@LQ&;IW+emipa z+*hF@d2Uk_*#4gz-bS%97JR708{zH@7BKbPt;j=!^(N>E^|?bR!+RqdzsG#QSxVIt zqCw<*oqj`@@rtNJ`?3n--Zni&13k8jB>=_cbc3@0!gqZt4QXl7_@Y^~{=uHq-Io*5 zexz7io{wLQMR#{~V_|AUap7bWeqsJS5|VLHSer`T{qI$j>$fHLdq?kjn?Is=G+Zzj z$kYlz2@me}+hwbpGsCTf8s4j%9e%0(xlzosABiy_c6l~X(Z{+p(+ln)@0kN8(1MrU zRZUt_jV^m)5=ilo6%C<>TVujpX>sbPpztHJtxB5nkz&pJ!MZn1!5C!d3!K$_yup$Q zA#D#M8bi$;cYTCJq~@b?O^l+1Y@N2#*PpKJW}Fme^Iex9i!0TcTlQrRl8RE|MC5b#Z<;C9}c44&w>nfuJnhop?oB)(r6bM>?6L8s3-wod1BGb=@ENAcq7r)q%Uf8}!2B`N$p^={NNF*b2^Y%`Gr8DbQw3TH?7$v{G1 zk@0Ss3wiuO^26Q*u$^v*%FvfaE6S|0H~RG)q8)?0X)%ZhSKf)$j2W z`(Zr?LFINN_~?RN($J{j(z0XlMTvJMB~(B7ryzn=(EOh3%-G1P;(QP1d(8Z#AMDa^ zq=HOoMG>UFr0>-(za(S~IgjfEBD$O>kc@Wv)d!Loe{u`%kG>xjnPdvwY?v?Bi*NgD z{9m>?5B}+{5t*d!MIBb)X8gHM$Crv6Ba&tn_z5Meo?c@3S{4<5utq6+2_=BD2aIJF zOZQ-S;|bY8UP8YP#HNl!^Y}S$|4u`e*DSMmz@xeKjxq||OorDCEVKSSkb%-4FWZ~p z{idosLv>^QBl2?vNIk)B9CHf)nycqs4Z$8_-E!%Ui)^_9LlWUYlvya5^pDj2#w?qx5${s0`pxlEBjg9|0N7jzu8r`*f$$}e;Ydnx)lxocU` zO`F#FE;)GOz}*#`(|cTSlzqw_N+Mhruq_$Jk#`Cq4a-qtoD>AAa6r-ZagCk+aSp2? zk@+g%ly4tbL3Y4izi%A#o%7n)#g0@0r`*^~VY9^q{fLua7c5>3;bSfn;dO{2$^9;I zdZb*|A?gUT6RhWheDO+DKQqF4{C|}JS?*BJHE}gH-HYw4GouSJv=^6|H*>VJR~!1) zHuLFC+wXMRAP+d92ysZg8`D?EMJ4`WZ9BGa&X(#op7KgVx}|ZXo{_ytMv6ZiFWL$?NV6l)b&ua`WQXecf6+ z6x6zTOeGr_A|fgihF_usnVatp`l5IgY3=M~6GCgB-Fz8#?%HbnezQ-ieFQ5yI%dbX z*Ju3&8*&Fi#~?(%5>vzj$Wa3n7tephs-Zp$S;$^&bsiCD4)iU`zL@3OCl?F(w##c1 z$r3ACiQMkR(zM_~pRs>G@S^Pf$zGj4qCT!{k%3rylyd=wGdYPM(==?aT2>ri#+sW+ z%PN(`rh%MJe*yQ|PUuPU74*61emz~_LkvvNUfnW7D!t8}V+Vnug#@;P{K=R0)3>zfeu;TeO8wv|ECbAw9LZ)(+p-l*#vXzaq8qVA>->;7p|xm)A= zBJwb#$KCI05&|%ANaAe@6R?)NUD^2d1=Xz$;3P794L|&HZNKW)##ao0+%uVXwpI;p z0hheee}6XT}yB3mWXYA zuU;>1tuXCkkQe0}9CZ_9-`y9H-$D^Do7)6Vni1if_wfp9?K3=`$ipx>k+~>71n(S; zibWp&sW0gu{3IyKKCCV%`D@-R+=EdWbFlMG?Zwg!e8!uL(_8lwYrn`N>NA^)H8rxJ zm)xL;7hZ?o41IMv`PH%7#QUt%r+}HvH+%Bnc4Iu+R|xAM(Auikog;Pw=8F6Ib^ifX z!0RStA31K63)B%k=9Dh)o=Q2LIuOypI`r75MI08Emw`1W!Z93f_RlRk!6yUEo|<~W z^@tPmKIGM2gt3GRtd67Zs?%p9S;YrKKd#f&r3{MK7k;QC4gX$R(IK376Z{g6SR`+H z7MUc7kM32ipO`Vq8UY#O!3Xtt$zl?Cv~kVb68zxMi;nx58hC#=Z`T^^P?l_k0urb> zcE>)i(M1%tBmC7DhIBUXvHsc#1k2!gnJDYaA@oh+bk|)SGs++H7461DS8ODLVcOvC zqPL(_q#xA@%_`M~UT>gA?V?L>W*&PyC2h7oxHOxy8{`2;gf5g7E~I@>aovP^BLQp- zGePkI_8_$D^xsa2qmIA3Eo(U!W$zE+H7Xa;$ytCm4H@Pw3gkp|lk!kakL#9>Z(|`gaLoUk$}*KCas4m1_bIELf9~xxam7o) z2r6(StIcvLwSuGQ&Q!);A21LUAnYfDo0ysx*{|=2HuGKBt8z=n*Yy1)07o-(NyP5SiL}`Gca^{04$AoR zbn#O8jF$r9E{3Tttu1+|Re2wOrW%f5pkeS8|E~OgK|ae-ToaD<P8f37ExbRGr_P?m)?6G$vSTGB44(*p zx5^LHl|YhZj~fRccRbAEzj4<{aA0#a5MNW{0)E2c zpWgzo(XE6p>;cw6EKjS3m4OLqJyIMnzcy_B9u{#)dkCw0(1Pm)ZdX`6VF^(Cgq{cg ziNB1(V0m%t99M-zu= z21$HfMj{W^D9RXxldk9sAwnV$ytQ9)y1z`%F*AYY&lf-b{#Gqhdgp+0HdNfz=f@m_=*ub{8B4X>CbxTIg(n2$5Qu8Z$-B z_z84Y9ClNb>Ui|2lKrVwIV7*3CeLCKWy&&K?MZQ)zA~&W;yW|$4M}g7zP$JQ-dgvMBN4qZo{}iJdp9&3o(4I!bXmdj4#e$Mg~F&d=}#aC#>q z_hCIF0xb+m%f$=iv&}l`MCF=s6rJ&OGA{kR@$MO@rzjx8h3Yo(L>oKJj=Vm zYR&`Gv;erOog3BIHlD8>QZD zJv>75HcLNt*HL8*pped#2EU$nO9b~i6=Lbw?*!0euRfyIXd!)de+Brb`h2PF`|fyu zYTXB+;vgaSk{6eoz^F{?f1z}|f9_-^un^>;*h{a3e%8w4w&~g8QB74A|BzqnQuv~P zv^tXB`q_(>(q2kB>iSy6INormU0@!Ta1(nI6)g4*D=@yY{d|G=#en!qAtddTYs@F4 z@_m(Y(8MZWPV*}ThS%En5*ZPvOSXZov(16IpnLfFjThu_O_WUUFq_R+P5Q~8#kd(= zp%$8eYB=521>xGi%ckENcG}b2vxv#Y$|UJAFrdh%L2E`Ec;fu;Wdkp}7++@*G3&?Y z3ZIn`I}e#g{f%fKXx`75AQ7NC;$`~9yILn6GVx9+}uQph)(0x^{crJ-aC>kp+OkJO6mnhggz^aLQ?h3`tRRMrg@FEep1@dE4h7i9Hmx z;CD2RkCknLM3btjpXG4nRpfH0Sm|aqz19NSWVYtzDU2Pmyk{;|K$3@ppZ!suq3VmL z4E$q-+Im3|>_X8-BWLZ$M6XrTh53hnmmJ}cXi-*PG7&vVZea|(77;pfuFc&cl15{1 zF6kEG%Jyr!-Le$pvsu0!`1l(5hz<$SCdDl3Iy6Wvr%eAp^-nWd=|SL|fY7-Hk0obU zCwRhHo!5}AG4)%bKgpu~JcCMs9imo8nQx1Ri_6M!03eV%|rZCLgD`1vVRN!0ioRe2nq|)^&xu6 zJFm9GN`nf8ID?=kx9un$hxT&nD}REf*{5x<46-9r49vpU*3<(U}VqWY#V|A{Nu}ZXO&2Qc0Ju(!-?;6 zED8X_9;QQXp}A`v3NCHHS)glSk-#1C=ckoFvW}ETq)lkAE<6*nz6? z&t&LFxi{Lj{eJi$u*Q)=MDL!hGErq+_WdfMrS4y4&=NBzjUrwlc~nXTx+X+B%lQiO zPvl)s9Wzt7wOzA{O~7(+F#zhs*x+tUvZ_R-QfmpQ9rzn4ixvk_rYil&I`%Bou4 z7_P=iNpfK)M?aG%D`H!eB_bdUphD)F+bVh-dCFspuIVGY<#k7bKI~u0f#^F9E8D_$ z>1t6e8ZAHDyjXsZ`IPssj=$}lgM_1IJx;XJny;7JPu#Q*p(V=e0Lf)>J6UU5}NoO`3n6 z@OhuEJ@9COTqHJ(V5j5QU@4*HZ)%>#7RyJz*Yi>UfU^T1`1UzP5tS6S6EHpK=6m9f zfx{%1A~8VH|8f!qEJG%L(EaO$&^!(@eK8<`S%)pd`aMV)fPD<*++$_#eVNQMR>!IT zm$NhZ8A3GR<3}iiSBxc2sbaUMTB<0567$r+v17;ltdzHs)^n|AU6esMi!a=nT=KY` z+mKr5vU!B{9+~s#8%yiF_1??`8WIhQ*6~>NHSqN7DBavP>(t#~6daZ06>^aTSP7`} zA(;LN`2R4d&KJlwy=jE$-NdnLqDU~lj7kx!U(UuouP!Z&o}(1?0i-^tTnYMwX3=J*{N;!(nO;~D9fM%=Ujj@w6BhkDoyfL_j+nl4q5HH+%wgMJiptO*-!A7BfCyq&*#68E9IT$ zI4nEhvY`E(fK1tY6w!NXzN?fK*ys47l-$QYIX3tsalV>X69pE)0geIT0+H={EQnWO zMlOb`9K}3P^_@|hF%4i}Jx3IaM50k!{Yczgio}#Jeq5@{NLOPW-8;DBJ$Hd`j+yyW zh9v0p!!dhxt-f1U_wzNXB=1(wjMZ&4ggOTjl;A`pmqhofH*o^v;zHv6BqBpkv9gKx`7lXN zsnX*lTPxldh)wHppH0a$*i7S2Ryo195Bc9e1alpAT(1bpDe&bJU&)b+$IgyB)Vr>z zeiO%ESwTsH3jYeKmh*)IczB%+J&dd!7x@o2ESuP+J{65E0>Q0{MVG+;N%j6ygy6Mq zMx_8E3wzTI5YP;J1WgPdIz2>cN( zdnM+fD}LM)CfAwd`&}Rfc5c|MpDFxtD7JTB#Pa;)x>PEfX{Zr_&xzLW*)98vrA6L# z0`?=9AU0@&2x)m1%~#;e=-t9tQORVxKV3mgE!HqeGb6299yCAjA{aAx7O_l!*-sW% zNm>NM{e&b=%?P?7B)lrH6R=jlxKceql$X~S&s>yhijq@MKEz6usNtx)-+e_ovG*B{ z<=h`SPBw(;1;zwp{-zAIe0vup+$*$Pq;yJkyn%^H^;7sEjDY%pad|G@CqP$efc=6z zkmcbG|17-q5V*K_FVXb48Uq)gCXX30VsLJ(d)qq!5mk;$3ty0T*Vs4*qHV1KAfSKT$^2BDfC--p+^zgja_0UQly0?V$ z@oh)#kN}x4(NFz&YuQkePS!(#X#IuX-B+ z3M4!v)Wai^*OZCEjkq#@Tr_%tS#TE6Xlz^pRF+hjr{i*|yV(~-*!j2vK4mZP|3$%F2Ci@Efiu&kxnRl=))+AOQ zjXML&*8WKpPpf$OnOYjqMeVAe!KXsa2>I)HnndY2a5KJ$h%|=y!`^a>@p^*GAd;r4 zxgg8>K97|DrR?U#eb8fU|I6TF-J8#M5GPiFEEdu;oO3cMCd*bF7l!l%=_u}Ye15F0 zr892Hvn}&=eb1p;+#P*;5AQ{W=Bt*AfYY3GcEa8FJTzvosU`{&)eVgbVkeP_px368 zZ3v0{N7DfMb8L<1Ui$DM`T1?BoM*f0S3zHXAq0W4w{AoL5!h1>;;o_2e|BQ*rCPf~ z@{$@8d}AENSsMo>Kg?;MMbQa*C^!DBv*OK*uBobyj&{r!e#;7UEwE9Wt_?6#RhX&{ zCROBXMYMEkbNy9OLC@8!$-3nJvW%ep2av6r<}>~0y-XWC^CRJhR$E%+0^Jr}e14=IzfgY3Lnt7n73p&uE%ns;cZiYeRg7_ES1#U^k*o`2&!>;( zG4>)nJAbbY99npw7f4P)($XN~hx7~!~Gz%E{ zuqne^GAMo6s|037lRjQdF)!LTB@wk|h4o~XO5qc*`T#VPxdl9Vzi3JZ#89W&ZGLt5 zSogqxSO;}}dfHA{5_%=cE*qXiP^S6)zYL9wXqbUmngdU6{Ma{;YCQ-S zWu_L8<2zOapUD59+q7jFw+D2&z!%c}JkMEPA?qcJPu_3we0>9V zY8AER8lYgrpJ22d=wz4UurP(zV)cAybxCrero1d)?7e-1|3h4wghla@+chX2|0^qX zzjL&Gv^gt~zeUd^1mCtc7R|5;xzk?{b{cy=e9iMTJ`elB+3P(e*VDPbEtc6v+}Wg{ z%@;uu(wwBg`M~@2GcTO?Cm()N*zBwx&ol`h3lS_&;=19kd5ST#jld;qK z{x~vD)0MWE)@Fz8jl~UXg&2fUh$kKufyM4%BBplmY|0HTj;VeurLgo`UdvA z*L_7Z^o_cXavA}xs4(E;M*reC{hm2>&(FDPVJr>dhmRhjG!9bg=;ePDvT*!RAs$qk zRKvqct^UKfGncgyZkgszKp6SUp-U;=U0?wPboFX9ht@r(w)C9QwZX6P`@dR*WRid> z+^NBvSA7|OQ`#5WEnO@o zXh$B*3cyJXI$V7mj^}lbs-lkO{q}2-9QjhHz9#Mrd&>9Zk~!@s&*?Q`#0yG(K5%9~ z<=uO1h2(!M0z`aRQuKzz3miJA+O%`ukz=O2@5njDR@11+N>}m4o3ypU0v}NpS1j=< zp=2a08F7AOZM8vL93C)`L2~8`%P0~JBonIqTyr$2+YaGE;(^2keBykqnoB>@fHM=9 zEvAxQjxTK6UD6)*PJxiPBt_=CH9K>YtEQ*z)**=zBblvZnKhN)-t1xc^ZH3X^np|d z=%-x+1DfHncaG_aGy;7gz)G=Nc^nsJ;Xt>15|82TqJCZ(QQI;txTrgKvj{c+&M@-b z7w@CVd@w+K6H3-zyOnEvbsFnbF+iwxiiM!)k|_%+-zR#Waf04I-F){()CP25Aag%dL~pi|bC=&7~&AeA)aQNA%nQpZbCjQxpbe%klA^u)}r=Bmx^7QmbX! zk%(C&{KpuN^yf5vB16Y3`Op3wzZfLk4(Qi^qK0R0_SQ&DlHK)Ye;{X=7Adz{{tg9x z>D-m#k2;hwDrI?Dm_Jt2J$1Y0V>d^aG7<*yJq56o zQrQs~MMRqC(8}3A-xuN0?%cKAzT2=R6DaK$#NX~Cv?XKA;LT>Q`tBUI{^x86*NVZs zi*h+R_@_AF9ouBI2GUga&F)iQdIQed7tS{|gLH&X=@Vipw<(q6BtpQ0F-2}nE9~^0 zCw^F=0Xx1XwtFv4s<3wHFok0SN|LB0N3Mf^3I~46l?uMwD<&2bW&$ju(_BmL zr^M({q>!vAesnsso~~z%i5rxRJxO8W%}S{tgnBxuY~s(xs%TzLN*nxM`71&H?XEb4 zX0xfzy2*gAx+*n+cVG7Z7g(YFX@9pe zjQzbrI0)2)US7jZ5BIL=0z7ROj{z{tkZ_-ZiHH?eX|lGa>bFHCML2MusZkrUe_;|) z$8GR;?!@ZmG{ecQMeRaVYFr|9)7p!{ahrexUlajQAhLmQ_&Hjo&%y!rUglKxM^|$H zhieKCV^I4hwEV{co<(MpVX9so_A4>J7u3?QzDB$XXGDh$+fdy zyq!G`#i!8yAc6OGuxvTunM&&0`JO!A>wJ{*^%<`Bu`KDJCTydiq7B~K)@1&7Eo`*Q zVjTN4b&wa_T{_+)uwChEug`$zvy8)l-z;bsFNL7+V6~OHU69d z?dutjdL4z0!w2SdSB(u@g>%71P{#-p*&Y2lD+8>_UkubN*AjmGtBIDha_YPPI#3le z{Yi9dFUg8XD9<>7x*H&wONPRa|CG^-GV6dS@jk@7z-)hl6vl#9DY3a%acDD1wuAnf~^&54yR@xn`?DksHS7+NB; zJv+3#zT!1T=6?&3Ar4%2XggkC`a3sv!0pbh$(>OCPXH#`Q?=Z&MAyk=SXM*C_&Q-v zh8QCt9r>Chuv&)=DY}N#AaYuz-ynZD#xaS-L-nK$-M?H!ro8=5GWN?ofv+9zKpW%YUXoFoH=haS&D$(&XIO z<`>tCCr2 zS|70`M6vMU(Dc%eOZeaJ?}oDQQGwzY{6Id_nD(5_&_}Q(V-oxeUh$kdiZ?(@83kYPF7r}`5i9IvA^5%1*~!T9o~utRVjl9U+aS*;&M&K)%V$0M>14M`Dl z=b`E-bRBlMgeqqqjQ?X2<`a1O)#0A||GdQ89;g!xRnV|=SED}@x_<1HY{pyMfjD|v zhj@VwLv=get#ryd^dLU<1kSY80)(!U$|M2 zYPU}^;_BKf5RlD+x0dDQfijlgZ{mPoIaBtfV2CzOhJ|(7*;Qg;N8>&f@8zbN zLNn`hhMlN~EK^OAVddoc6-eE4W#v7AXuaqPBHx&=x0FEYn!HkaMq85A-SHgzB^gzj$`qmP-9CKkcC=!fxQ8s`*!qAJG>e{ zdZ}6+rigGv-7+|Qw6LnIzO2XZYJ4@n!4l=u>r?9lUZ8q_CuDSZ8&S*|xzA5OQ)kR~ zK780*{Sse&AUEmdj_@`}|P+ zoG(8oXu%A|9t2+j`w|j!$>AqW9gOeW{=%-i2g!m8gYP$ddW_ALQoJ2JenLdVkJ=dV zrr^@1_Yw>5el{#s^T3e3|F)f=sddgUok6Yb;a&Av;^K+d@M1}5Ck^1mjN$R> zW5k*UQ-*nRnykWJU(=9&hXq7I2+`8)7=s&*O^%EqW^icP7DaHpd>?JfBZ}bMu=%vut-)>8DJmS*xUR;pi12mOa8w5O)N)Q^+SAQmTOj8x)6yQ^t2+ z!zb&x|N6Ei=Wb^Lg`F?=;`*)>S>%J8CnUSbi7ki+sfAXCs{VL`d2t2$3-}QX8A}q5`(&iL50{M+@L9HvIX&wfYZTmd?SRYQZdz4J0Zu^)yuQz3 zP~))hIY3tIGx@YubC0lsZ&x|gF1J_$15VvO__dIOf%xH_+glcpcLy&}L!8c%XZ=ye zz73YdboBn8zpu8z!f<~sc|>Pi5)Gr}*>+t*v*bmE;LhZN!4g`|d7~HL%w4YB2x4nJ z+$2k;LPXj;sm2njzv{#+cOs-xnv?-1{fD$j!qcK=HSG&GK+DPKgM=9cg=|^K?k{#c zxZX@8>o6W)gI=9|uTKEo>E++JFu9(FXZxeQzWyO6wyVCgpn0{>H};m|o)0%A;y((l zC#VXPLKBFGE(5Tx+jmqv;TuX2fP>mqC%O(%O>ELv*FbDJNUw3#tmIRx%HazEcmmd`KH2W5qh1}2Y>i`U7?tKD$O*h`&{kv1TsV!UZZP4Rkq9-$m=ERbsX!w*z zG2V()TGy(#S5d*|F-}2ry7aw3wHc=M{mW>}kytWt)TC%{6%hbZAVm_oSTDkp+&dr~ zl>%M&w)y+h{@e1)ycfFGP6Y~Ixi7RN^FPL#=*UUmA7Nln;v|PycNFKew@>HzdOz>0 zEu@A~{<*qqm1QnjA`G>NIhdAhaf<#_@E3P9{wG25vFT^CspBonK^-ina#rmjkl#2O z@i8k*`@b@AxgXJJ#3xqLaC2?PEFGG5eJlo`ex1od?Dm?};`U#BPmf-ocbrI<*9x2_(E#Q#!SyfDYxd$x^NA4@QYD&VeNHEKQY^_m@#Cd!j=tLKZZM zUJ5O)=oQQAHaf8;yd9et*}E3z6vM6f^Tw;w{UDUTh-7#W5_;;2E_ZgU4oV|njiSf{ zVZ!(L@`CT3eI1S?n6sbGiWUg(LR)})Bzvc5IW$CX?FLAlP(BpslWM4dlrwWLXJbjo zmf1J)3CI411nNC)@;E{H7{SQ`9b0s&4lDBUx()Hd)sW9f!XA;EIw-UrI$zn^6*lxB z1kSubEq7f6(g#UDUyvNG`@HCF+x3=79aw+tWM?s#HU;6d%35fW3A}AnuG)8Ph}2x-;q*t zU|aRQ!JA;88WMJvYeV|+GXrN<`EJaes5KMG8B0~~i1=T$ZoNaSvUR~<@-C% zb??oWXC>a-hWzp7fuM*`=m!7}pLUH!zYHv%Ui8wr>$#u%s^2cLTpto&05fneP2ze^ zp!~kw=SGX72yZn0n(X|9%c9?leoh75Xdn;c^3A$?I%;F|;|)d`R{2d1(*gR<*iva|it7U<$pW8Q-r)+-9uC><2r(VL{csx=PR?&j!a}9U3*h)rGs*)A)_Qxj z-1BxY4jOM!^S z0N;N+c3S73n)W<>sz-m~S#O;H*ng@Y%ymZXuxHbSVqRz+<1>5m$Meq`i2Xd}2?m|b z5Zv$XY*%*w@XI?0b2%`^%y&xZSY}K2=#J{mx`r5Er5-B44^(O)w3<)PA@*>GCwpHN zUh|G5Ng$N%UZsVoAP-yAG@fNNCwiyHI5)?Q!_@U>ns#rzMWXi*feowQ2wjcUyHQy} zB0Z#q0TT^beYe}7H=jiZS-NyEwIwUZuNZK*{x+idN33f-x;|0n-zzc@=8c?CWW)xG z=93@`*}yk}V$Zh^t2(xd{X{)+N(tp*Q)jkl^ycXI)c+7BJGTS*fwKm&< zI}f!sRQk2vm0q;%%qP9SnS9oKOkjCc_DJ@?z{CpxG7r)6Z^E_Yr1(VDW0i1q%+9$p{rlXK?BqX?$cD8jEEfz+4fr^!rjfgzwF&QVyze8J`xs!z_{zn+?^^&*LUxAPc;&7tLFBv*Gl)GsV^TCuYavV~* znqi-k?DMRt@!d~1vH7Yd;w*@4gUS%`pk&G`Rh`i_(l!426MZ__z1$V5l00p?Iz+(h z55~yAv}A?SrA{li&L$`RSmr z-ZhR`G%{Bd4;cxys{i#bBTO`*lU3|h$*kFGw6ijw@BibA=#Zx}(aGq!{>~|7baHd2 z;dfr>?WnggJ}!2mk19}2gar@kblk=?Xs`lxe?A<_2e*ZNX?UVy)h2W}-&Cn$DYbI% zfM|IKv~M4+eS^{M%qBAI+Ao3fWp!<_m`;U+N+H+z#@a^sM<`Mejwafy@i9s+HhGZW zwJH^Ktp;A5mp(F?MUR&yk}EzpoOxwhFpHOiid6=|mv===j{dHC-UNo-EooE{BbP#w@zazupz=q89bfNWKUG(dd!F z)E60wSgjb!S+sO5XD zppK&09v9-gkDqKuAn(T0_aQK8=GsyzIb&OQW|nL`i2m}F-~3|2d&Bk2$-CwBRyiS6 zf%a zIY`e(-PAgDKE~K}eG@bHAM246YM!aATF?NdG&nr)>=#I+%hV8Z<#v#!?I?2_o2k=6 zuLt-AGGOzd8uk-iA6u#KqgeQxdyRBiM@j`a{T7*_q^k!;O;j~tZx zEyPEERXR9*i~X&xUiEqRV6;FNenyWa2aWkAx*shrF3wq68nc(I8!JZA7U z_Wwy#OI=79JE0Kky5#2ex2r9q|L8X?j9gnx+hxpIZtpU@8&3fq2cCt1eB3**Jr6$Q z8G-h!502I!i%&?VB%DTgfW(;pIe4F7l1vF`MySOJor!~HyB%6vXRcK04vVMDs*EaI z;2#{9n)5d(Jjeug$)@-n$~|4}h5;@D|3Hflh6eAZ2t-F`ml2Xgzg2WAUkh<}eQ;2` zeqCgVp!wv$?+16ydo4ufr(lLs5Ex;ivT~IuPV<+ zm3__i8c|8xD>J?)h_xN5hfTM)cw;eXYQf(!#7}+--|XdPd|JR3TrEqzzw~gqj+Hm` z{ul~jhF4_2hxgh2if@drP}Oqtt5dy{I%&VKA%8q|1g9)=ol81 z&5YNsvSsI#?5waT9gX$X^7=>fo`d>sNW-sQbzJP{3dJ{Hi?TCLm{uxrEy`iGY*>(< zM~N0b%zWuv6^Xeg=z|Kvj@3_YhW*sy>j6l>Xy$ZTYDXf#){TJpTQGJVw!zOFmw=0nB)9KCGx3!nEI`ziIRgvbXx>qeU6hS;I^*q>N#QxI5%G&RI zW9_`i%mW|N6D2y`k6T4qX{8pvP+1}9JwT&PCLcoUujB0(9&-~j99@FS|LvyjhI>dp zX4MNyUY;RXqCPb?KbYCJFST*C+2Pw<_{iJ}b=`cr$S0zE&lY7$95{-6f19N8t zA-){hZkpUu(Wx-u7`W>3uJF zeO2Yrml)pcc5m!%T=%)G(S>1JC^^EsiE}ta8?){_=xFyQ^(c4U%hL7QN*2Lk{dhFa!tP=1zy8AX!D2cv&7^HUbJrstW^zNOF(RZ67>(fJ|iS8{Hc7 z4%lOyRFkZuRT^DfeHbr>Rvd(6%m?xh-1Bb)?`=6y0R^xk%uMjR*eSfFxCKOwcz>yA zSB=TTh(@86QaN7lauV2|&bfncFq2d6FI?UqZ1MEX$@_Cc4%Kz;VM=h=Hr^2x%tt0C z19dywRmT%nxuTJ>&3SOnuT#zmfjPPI3kn=~Z%6e<7k6B@DuMM=SwU>KWFu-&vJtsp zv6T7J)Y^R?_vX%wb@Q1dJe{N$hMoqEdp{WcxYbrNLi`-OVw-D%sKD)y4^3PY1dB#2 z=l=g_baJCCTHFI$jFB_Vr$^(HKgtlSG~HBvr8Z9QIoODVyF)%1pyEHn6Aqt z!?=}LW`KL0R*CgpbH;5UJ)KD!yZ?}^l^{D3;LB;@#X~0{2|v{0>c0qg+nI8EcMc(aL&uhfZ-4*1P2Lvq*Kug{ zx=znx#9BI^xk|GV800qC`&p(G>bKs7+=$9DNulm{*vk1-IeK`4xxKTAvE6#K!y+)~ zcG9YqyGpf0+3;=Ge#FinhExA*R4XnwM>oxnYqrked)5zjm2P^NP4bnwh*(#*#wa;Z zf;&N7N|pieE~0w}_bVb+orm*r*)A_@w*1YijyCZ(f4QA(>Qgv}7f;O?(@HD{XWG(L zC4zmmr>PQQ*bZ--_Kh~7aJFOtug1ak6rZ#>-@rR8NeFYn%c-)dG#}s^IiKJSdfM~8 z&13V1Z0v{0t9PwDW=AW85o@_AN>&hxN$+FZ6JxkYf*73EXg(VN;{y z8^KOT;-NVFq+MxP+m=iUTW3DBiQ_owtzjB4Z(0#SR#AOkQ(ONFh1Qzez4wq$cnjZd z8N66bG~&82;!U-oCRw>0xVfvlDz+%2UYvww*tz4f!A}pV3jleJ@tX>z?y_jFmlo z;!B1ng4q(%v^i|u5c1>>-0~oP<7-;+hV?)%)Fu{i3ZLz8@S@r5IIJtS zo;}w8$MmYgA%glkb~eL#1#VP(IVvHKAdf-R!5&oBTZ<%fwH}vDzJXlqTN*1738QDW zmYOwoCqb>17rKgw>KG*z*-hQ2|Fm5Rq?n3!u`D)1QCDp#MP*_S(?-81a>iywW&}35 zdmIAeA_N99gFz7*Y$-}4;~}wOSxXitw;nuwT2SUn;a8y4U8&>x)wE3;H;GCXc*YaM z6Opu4H|>m(}+2+JkfsP)cw& zUKWUabq(q6zhsV&{V_|>px~h(3dFT}9Y3|R{2Rjiey`odhq_N-H>4GEpJzT?NafC% z^f`O>j&QfxRby48H~lTfAKZpqdW}rc60go$^Zp_dvf}ddA2F%Njmr&+CO&T#Jn|GQ zUoW0~Tlir&7w|F z`#QxY$M1+oZs%?zbSwK$^0)<7-8S|o%a&d=ZFf+o;BU7rZNuF}{8rzmC9gVno&M37 zJpqp&c*}orY)!e?vP_$GMaF5|fsHT_KZ1xj81M9TPV_xbRoGk&|D5Pf_j|qKT)ppX z@|7}$i>;oFE-+rKYy!z^jcPi@({2+Rwr_uYbziXbs`J@~3hOCS{jGNlzGRe#LHD@*c!Z(W?J=b@{&(i5U^46*z-A9w4fIclJ9wNsC|g7fXZ z^(rNxb-@o=U`GXo3g?JqnC`me)q(u1=Gi+IcedCJ<^=Lh&LU^uq#~Wy;W96GGv*rd zxcImzIv$|VTU!m&14EOA{jHypRUR|5B&$<`0?_s@H;$444{ekvN_$ghV}ajwbE^5g zH6!Kfs?p0ReLT9QjQ@w&0F8QWQ%s9{`+gcIt?@pGOQNpCb%#0+V zG0?CEjj7MD)tEhhkZ`5_RC%oobl93+#Ts!dv+cTWg}R}jZ;w^IDhI794LT%UgFYEK zY_tkG)_qN07oBXVv0bjccsJ`njj(ZfWO--H!wtnP%+UrpYFFA+4YM`D_Vxa=_HYRX zjJ=%d#PS`SflzNlraUr0N~^xL+RJ1K`T8cH$EL^D#QA+m7!+|dErFojgUosSK)FA- zt}4xUR$0Sy#+IToTJrcVBt%{FWNEYNZqz;K)t3(sZ9_g@b1Qhr*wSF;x)%IdOPn_R zYVH8B`w2(j>WW~NMxYpadmZ}pj7Fj2;$XD;Y0mY}EwF-``xb8>}JA__o`?lOUvc|$g zzBY}d?B}w&H{9{V|JmF9Zdj>ni!?EaJUh&-a#`@JH}AP0%n-dQwsSj5KI{>-G9pT~ zG3uJOg7BjTb&d#mRq0@gu9%;1CoP$Px&2PNjU9*iPUi!(1C?>MMb~zQCh_cU#gb)5eYag= zIb?MtMyej!AFBqPZrXhhAlsBWanlAJv-Y+y*>RA)RQ)1aGg1m#u$xjr?K~?`{+}0s zn1Q{cm;H`MU54v(y6ZY;PVPJ{FA)mpo!_3T;4b~D3ALXTSJmu=%KEYEXTHAjBg2(V z^GdG4$>}Z+cQN-Aao4+zxM^Xz6PNKGjc-gR7DEmPRFwtZD15!Z`;!-` zD76vZG;95Oh@bCi$vr7`abv8Oflt2gR^Le(#dPY*X?6^ONp;7Ye`$M}S7QsKGjGIF z=am*uc4;O_vxa_+jhNMegM0zY45Q%n9Pq@PsTDpy~$$cVgbcSk`H5&c>W zo&EneM(x6pQ$%Ea8KGtkz}`2TQaAc9C?Si!w^oI~XkjI`+U-WY2KzD3ECq&`+b29%DuAp(Bh%RT!EpgaI6^#K4Z~H3dabw9e{vY`ih0@~E+)=ladI7fgy9 z1{VG)nf4PoAZkA4s&>s@w`MpjjfAZvDWZRmv@laLKIq;f3y-I} zrz{R}MZd_+Qd_|ZAjS>=lb}C+F`rD039K##Fcvi>n@ZASCaIuXVOA4^zQd}{V_M*{ zP%;NQpcVZ^_&7_||L@gqVr+DBhvD*@k`mpzfPA%{|Mn^y`i;osRt);$^8e|tAq>SU zAa5`F+7#s3=({*OSX?2Q@|Dd9l=&fsJ{N9yZu5Wt5;lGS`l%rPf9!pARFvKK?<=B$ zpb`d1iNGMz-Jmp5DpHaHL(kA%q8Lcm(4aVgkMAqKzxBI! z-QQaG&--0#7VBBVJSX2G3Y--{0|j@to(-;|06E{Q9A$8i_q?pA5k+tT+-f(*A~#{9;&d1XT1iS zk<9B$U2z50Zo{sgMF;2Gp0YsOE%Y%_A|#q4=`idzaQU`tF=U%>lbHYffnyGFfE1b4 zv-PO_0z0>x{gLe2)9xiwCTirrb~)~V;11)VWa9!l6o-Bvhw;6RO8x1HM@A-|{GdfE zaGA7HnodW9N}N!eHV0?cL~`&8p|AJ9>4Lq?NOu72g^juP-jrP%rh8Sc)2ExTL~}Kf zYPT7AWXFNE(Qi;upjT!A?x6kvM*0NyuaWj)D$|V?QoTEH7JDhBK@s#6TMxP!2sSch z%EJr_)2-bGJUxr-cA^e1Cg1;ielyGtE%FN>=~|*zWUgG~;u(2O<@)WJz*u4M|L1p1 z+TpfI?ES{y3~XOyw3iNPZ0^iWkn{^(xoBJ%>+Be~ez!^QCXEKcl5Za8?91u4vYc9R zF5}2Cy4hg!z;z#&)7$iVGp2h!SBCUCt+nl<7u!!vsDIN`8gJ#B`+RCLYNmA+{ytBy z1mDGmj^KLnw?S4nLH1$dRi?p00ir`}vg;-~j-#C$9!we3Q(;0dy(K_>2pqm>HaCNZ zNC_@mlpP%#)+B7_*Sj1Mb<=SL+!W@BqS9elbZngMi&F$&mcXK%WE?-7fXC%oml`?2 zi`EL*6Q|kBQh%JH<*KYN_fRWB8j4=QxX>k!O`hg^fB#24nXdO>g+=@HLL#D6FRJB> zq@18k#TliiI5<8rA%m1#!r!pSr?<;uA!C|^lmFJ4XX4Z9Vl`eM1CZY=c0WmLq) zCIz)6X0$n-5R{j_W_S)VsK}^J5ZJbsEDics6qoN~*^{P+VwNYI@{=+u6|eDFf2txZ zxX~YO+jj0*)WxpFDld7MV2293{V$v9h{&L@CXd-8;7e6hkZvZ5o4w7gQ1ip^y)!xjr-Z@!%sSK)i)Vg5PxIk0+FsREpW-WPCqd(Jg1 zwEALQ+uuU~Vt^YnCSbL)TDXQxA9gi>}(a2a&zEgxttxMKLB zAo8x|#?A<;JaiGte@+usQ1!K&uH$Tb9*SYqEZ}UbkWN`lB6+TQefg5G5CgKa!ROf;4>i8TE?DsvM~Aq#+JR)m{&3BQ zp#1`@$I9KJwUcMQ?>&o8MXh~C-4Bl#z5irq{{h+02HWhYqRy(~R1>!m1l+KuGl*6H z9~1lUkUeSe<0Ki_oz%72C{Mq^U5hMi-nx3O&dinZN2jiB{QVp7H$)(S+R@q5`B2n0 zQEP|;p>6E0Rg|YH&~_Q(0yE{;s;6}|wFeK@7`Qnp5q(19v6czTJ}I$+#I_uJ(Fz)Z zz`V~s?=LpSenLgg&|%4rv6@5p(CbwE!Qb@#hsrW_a>^EX+WYUn z4(-7A!6e+<1pWX0i8q2qL9@3mK?sYz#fN4U#CG>%i00;kJ-w=^!LNl+K9r*Pl{x>r ziLdV91z*KP0+7`BdvvguV6cRz_zeNU-hnsx$zadGH)uJ&1F9Q<5&;ux-~UYsNwD!O zkw0)FIUd6u(4;2yrVF4%B6w5og?ovOw%X z>Mce`K&b}aO#dvdl>&q}$04gI335Q4Tc(}=J%s z`p`Yt&H{Yb@~PGGf6u`Wq9SX1%%$IJ!($EFWaUhs(*W%Ux-{0IfzO^Aqm;>T61*>Y zw~9^T_h7-wy;cNtl6=yNJf4*%Agb5R&#CG!>f|7|{Krpqt=a47teeAgi!-3JQ3IzP zgWm*)<{%AGG1{W_4@X0h*yzjO)>%PEGGb;X_aU0xVeSqO0PoY^7`;gUd$53)zA^zi z(cgxb9nUHo5LGhvkw%uRNjhj-!^I;j#~Ey(w0u*;@`c>F zcqX1QVgSBKQsGKF7922>A5e_LuS-?$cpammI9b>A#6!T>a!Qt@s%IgZ1ex#h-UaWU zY)JZaEV*FRUJxTQy<7aHMxi!%V!=4G_!j3}h*Sl@n?dK7AGmVKc;$Rb=|FOUFWOn+ zI*$ns`dA0L%0=2bGw+zN%1mG#t;yB=LHj@*oc@nG_@Al+g|Ir7ID@Wa$42V*1aN0X z-ouidLCZ8>U=|K$+KTsMjK@GsvZX!kXn)q?1)ZA}(%~tM04M_6{oEG=%-ESO74Cd^ z3aG}>4v#bJGV_pmS!c}RtU&uZ{d2kZ053jKeXUqKT{l;p3qz5NzYDkt`_U%p@EpF6U3<-d@ zp?XC)jcclE{5wQv1^l-^Gt7%rw5TDw>`HpI50G7gsQ$2zB-~Z+OFxUG*jMhaw$be2 z3S9GT1rf$GdtVl}d=ATM4-oL8*;H?BuA;4$TELo#Fd4D8kT3L)M$Iad{(Fb=IRUuo z%3ti2zeA~zG9nED@>cgXbNmG5_QA6Mn9pu^8nR}8np?QPX0s&8Qeu+29Xe3#5?u$f znrVq;H5>WuyiK&-v<`JA+L`EAUe1)3RU;7JD_j>6Yr%W%pdS3#{`eVbt3!ZR6ROV$ zHG$0|-7ANBv7m5b)6HBBa1q)}GgG*oAGqj7=VP_YT-QxryoSkg<#J6s-IBwL8Gx_w zV>V_HU6bzGu$11@1E)5dv=pG8gkA{dg_*?J=1!m(*rqxL|+vl53Ks)LMdJ)7Q(w^HlRXofRkUJGe+=l0t#k0R#|j6^ zc>B|ptLfW^TebdcTmDB|f|V|ApKEq|F+vQ7KVQ%ggcbWOnlTIwA8wY}6WymSGTv#` zu@N0YRw6EaB~0P4?$S8D3E;EC65}T>yqnM%l-~b-A$LFmT!okGfoi|=q*a8awYp&6 zdu(r1Ym-x<5pQ?;?N9rv+QSWuFvHPyQxZtsa>dTM4I%osGJ_hdvr@EK&zT(kP?WA1 z1YB>Uu-9g^iM^S6G-H35*_aps#!)-s^YbY~9wm_x7(3Ui2v}R~-pH~LBt{D&{HWO> zzm;HPfwbM8ESu*$vJAUl6)d)7%F+(kv)c7XS5X$=WFUr8j8+k{_JyF`m@T>r7)3mz zfFqm4{j3jq!2`x3vi4bBGI*Mmi-tVftrj{{rvCOXi*sgYLO+75(hGwzm zUu_bQK=tg;2-jw}@fk0B^#h!&a-CVYWa&=Y(N0?8IW?QHRa9ACn{sqwJ$6xVZ+Ou{ z*p`0%^%*TsMWyHfzPAi(@l8Eq2VrGycwFN2O>Z3bD_jtng_-B9-X0IJ7)(5?52B&uuz1+KQNQ3S`+kSmLY^4!E#qF+p#kr*@^-{cS+iT2 z5`ObF4V=h(bAiK z97!>-?cEE%ivwH#duS6SVL=@zLQtc33NZXtHUhtUl~9yt(9#IUVOWYDbS;Z*&q2h+ z8apZGBv`Bd%V??#giNcSe`z>uJ!CwXWH|cpO1{lXdZ$GLx#W^1uGP}-mJ;aGZfm3& zw}Dzw{i`*il(fvwVz2_WfQpe4QEMLa#0 zY;!c=483l7Sx8J)C-#}+$8UT;gjNn0Ev5BYeo8KTcFt&*RcK8=iB|RS?bo4cQN4LI zGIn6t9u`M@&~EQnw1hFl*;~5~ORc}T&@1##h0ddxwpaE>S(nxq4oPIKc4BZL2Yi)A zhYyw42Sf0S-u}|8Yv2zMt$knYx^x&MCijDl_f6@d2{G~1Z~0op;gXRD(P{f=6g!v5 za`o0|`{Ca57_HZjH?iy%%;Miw3&7D)ITwBGDEge4S!u*&9bQ;tY(94w@pb(){IUqs zVW{F{+WXR~50)Q-lP0I>mOT{VZ$_lDR3$=`Ri-D$#|C9g41iJ%S3!4m0Q1NQ7*I-H*eb^Gs?`R8^ag)Ta2(V?$?yRqgh#mLFD31(*=+p<+Tc98Rv zxm>)=O?l3}dcjajH7Y+>2UC!)GsDxONaUr!!>0a_A{=p=?~P@P^?jX6sh4BYg-V~c|!S<snEP+Rn@?gQ`x=;M?!Qh;?`4LNPG4>oCBffjj7|EAcUnP^*{N5+d;CQ<=d zGyi<*9za@R{%5%BtUg%9wMQ4cbq!DBY`J~sRD>mH2Cxknuio68m{>t}@pvBOGlA?a zu*X%u`gEmg{FGL5`|}BRVe0()_aPe6`i%IoaR2?u+*_NX%PlS}bwRS9dML*6QB8=! z6q&@jqKhBC+%wfe|X8XC{HJ^9r1z)CeVgvZqGblvAFfUUZT-J8advq=JX3^Moqp&vlkVRDVfn15I<6f&= zX-Mf8j}8695vhJ=G$>Wj?|;xQxI|c#=U{fbQHqPunUy9=PaJ-ea;?5rsO??f`KHH0 zd#dau)m)c7uD0P`WS3HOO|41qf0pj?kKS#3JrFT$TA;e(CPA$NF2k|RztU-ckry+D zmQJv@+h3?Xw7t}Ypl*B;uV-qYzn2Cv?xA9ed)5}GgY+4J zrl_rarHN;?!_T_QQ|AO0FWy&ywWY$S;NsB*_16bkpT@=%WAZE#Cipb)?3BY@-wAnm z%gGoI%79LB-LXm2Nps?4$Tz?F8uBjO4`Y zFE1pf7?U_GjietODkhs|(Uw$X0F%Xg0r}RHCTzTXD=VT@Re121DW`Swu&s7q<-l4L*+xnU z#~O|8_LU*Yy7Lq_>tIFh(E%Vcq80;Hj#ryiD9B-BqYOyv$ z?NMKU`4zAY8Pp<-w4{MQ9$woTQ=;lzXkT`JUY}c~9e;Mn zBaF;dck0%_;t&U!tHuY6c8)*A&g0%7pCno}8t+}cj^>g9<>fb)@M`e6hn=D1Dc0~IvX7!- zGSw4T{fnpYcB89!;q5UZ%k&YdpH=f6YOu=LM@c;^Jy}vET=qxUxavIhCwIemO(?lJ zR3CmF1GA@3X_#7O0vec zXiWW$LDsfDsX&23Mba`AgxMY4vaYa;EKxxtgZfz!Fg{}I^v)X80qjwbenKfqF?ED1 z>f2$U@Vz@k6kYXR?3%r7wz{w~yHRZ=${e{hTjM=kg&kJx!0**;uJOVA%{YdYmx>Q~ zkqI+ktFtT#M>INH8aqV$hLL!BcPX=KWwUux3lk*%h%wARhqd><)HToOhPT(V(p%9vg=3dGxY&i;>u|3rI_p5a!t6Nf0l9d_rz&;5# zFYZ>)EkyDs4Ry}fO3`$CbdE00N~*-0{alT!tr9JkSkpgUUigR!4R;ZrF}Kv$y9VrM z5}@B4gC5|hLDY{OJR2#)YwxjwAkjSeojrvoz>ro7WDEt~=I>87^v?}h6T1^%E_Vec zau`x1{){TIO@KRT!E(nwiairh&LLGHr>sDi&PtZ?QBcXm8WabXPRA(=>0!;&Gh$nm zIzJ;ak~*WlItTr@yy+wJFopRCz^7@&NusRP-s9E-ey~V$a;tgFzlF!A?N71loEU7i zO~6gPvolJMcpO8l^5kLaE@a$X8o+wQ2GdFHvdTUjd%r>oDtTH9Bba~SWsww7^W8!i z$`)qU0_mfj&LqiJ=X}To?zhw9Al|Zlh}Ad5shHTjVEM|)i->+?%QOV^DDqSHTBx$_ z;J`>=u`iJ&^(Vdn@wmk$c_r_e;?3YrXcxZO2&Wh-J|RnRHElCtikX9)LkdPpMMI@` zc4QR?qx;ek0o#F#be6g5W0TPKtni3d52_0=Ix1&ubLg1^SdUt<$H;<_&RAT#>So)^ z{<1T`nsYUv>7IZOH>5)9HT#)q*}6AHvLZ7;Zy%%eWqQ%+m2;I>xW|ME-4LK$}VhaNz!YUw~}S?uYJFm z(RY(o03p<2w~wkayqb8i$!BxMnYlQlJvM6$MzNh-+B_~b9iwRjbEaW%{h=w$$T=!k zSQEK~{nDb9&{s`l?OT*rk}(#v{X%l_QAsUM{Znv~s_E+C`_Jcd^@evfW^9TqJ@vH> zPM515z6HhAxq6WXp6VY82P}%)68nXG=So`)SSv$W@B^T7{=!)7qfZ}!H)3qoC-vDN z1v?pJ*J+P}BSV_svo_GNhNYEN;}NbDrytp?lDDJ&Vy$TC?V5x6|0s%2_L|S$@ZfQj zF(mIANssMsOaZI-L6HX!VI`s5hEU|bw*gqAaNDV_r8khCyt(w?IQ$DmfX@IC6|I|^ zj%4N0SJGEcAY&Qf;8kscFn_=OkwZx)_Xl7pV^h$ zRy8!%pZ;X%8((vPx5xN41xHA&ec@klt_`g|c|pQKwlb7Gn&73C*_9;8J8tE?!ruJ6 zAE_7vmA%Y#j6;SXS4;5nuI1tl4ZC_>2Dm8YfRT5b{^)&HUa~G2RdWPvnC@g_{9yu7 zK=|RKalr&|00=X8;TtADEWuo^uSE4wnc3NABM$*JMc_%+X*oS}L?t+b?%*mQC>_Sc#eqzLm@Q zqG8%O7Nm#OR1kb)qc;Usjk<}?5&o?;u$TV+eOTe55#PpFtj~usUxX*AF!XVe^D+%;hN5`m3Dv(`CY zclAvT+_XcJS`8LcHXsD_Y9BE@>On{k8q@{!ikMZtSH8aNq;h06S- zh|P+cAC-0{PFmWcj2d2B*U=jR=KW`$T#^2A&~wI@oMvJ$({9fuHzR+gC~ZsadR>Cj z74B#f9syAq&sJXRx*Dne@{+2sA5=)N% zv&7O+Gx@bCbFw|<4@*^R9W;cwU-a}+%$WjIW+DTa-;wHcGQk*zLT|;wRmRCP`JNnf zz=F3Rvm@3g|046^OSy^Ai?PqlWR$ROqWsP{47aA&O#t~>N{QYQUuc#WwfWuy|Lg=7Q*PFLVN6(qJSbCJ1ow0yBkc-!j+9sN4 zJx!uFTsy|*DZHWAmhXg{kgqV({BmyeW1ScM`$>!T)0mdCu+#679+c&kdWD`y+oJ!@ zk=n}otRXXYVty_4i(A6nZoX>5%4jXU27|m%%%b%sRg~ zWA4&~T zi>F=b9>naq&w8i$RF7^NrnDB7_}ZWH_Fc*8?|sDKx><&ZPAf%umJPV{4VGj25h-cb zZ5yM4g>xKbc$FcAgSimB*}X&Lny0VrSkgho){0e|-H?!Rn(uQL`^g?ub`8pVFSQ^0 ztWE?9RJ^#65efnoBp`iSP4;lmJqFq-oLss}BN@lzib;T}4WqYK`j_tt*>l#RKD(0V z2y3<*xce-{J1=*2f8ARDg(2US2MJDNW=(aVzTQFY$10)e^dbGFLOipkc^f?3{FJQz zC!3@ywKSw;Zk`$3@lglP<=sGy814NzTX02Vl$HrBz1hV)0oN7KCpZ0G&oAsZ_yzQFfRH4)dQ1(m=sKr#~}64}ni2Gee-*!naVhhyU8UyPM`hp=Ls}2o*UNp0l_YVq|xYg zpPipX;DP>)37YLKgpY7Bi$?uP3fBohsijP-EX?uzNT96AT~lyfk&Fqb_MsH+71&kt zJ07a`8=b@OC%4W79f>fPiF|(SxP@E;BO@ohlXwx3S00S1jL29@LIxV#4Jzx_9}u-h z2GH>1J{ft`p!u=k=4^k@uMSsYn*^>Gc~?I1iak*)S6dJyM(t1>dVH+$$7cn2A-qIp zfJ%`tBn8A#Rb&K7pz+ZdWus$E5b#u}q`-K-^J_rz^7kiLaooLj&v0$0)4!(t=O>aR zU?aT$mA?fk*>b%?Q+XX;I>u^`!aMEYg{KfggsOnebsLQGMW=*d7$azqm-J!czxa(3 zN*xhAP2@VJ?ic0pU+KNg(lSBm!VoxdbR1)d+Dy{AsTCQ2-BFhbgVf5ZOV3s0s5t#-BoI*WaW0!$R~YWOhOL-Pw8l zo1(BjqC~3*m5=@yYX6OKxT09#Ie^^EG5=LSNz5&K3nt@qme)`7D@m zJ`MEvGa;*y7eaVEzpWAtq~afGH6eif1(Uno8OO?3l-T9$oEvLr1d3Wsb?k?Na88>C zv@x`gdM}UI71>nIJaO(9noTRp1P5gz`ztXvC{T(wp&OB~13XN!KM^?2-^~99S@Ngf zDI!og!P2lV*?+X5o#ALdX~sP(t;fJ~`Vv!rpTLdZ1%5H~bc> zy^7*gQ(gWr876493j*GbMaxoqg8gF$u=bp3ap9rm_k1#5ls2A>fC9rngM{nXca4^V zhfaAI=EW_@x;{^}bIg*E8cHVz=-xp~L)`vKh_rCi;m@S@73p0I=Y~t*jLGGg2geM- z!$S~f=%(ikc0|D|#y%^_t`S{rD9&8d-O@AkJ;R6Nm6zD6-HW=phUAqxl{xK!@Em*J zo{%(Pg6@u92!P-@pN~lat@=eG15UKc^Y!v8g0qG$3eF!{EK!+;qG#JxX#S|x*BHVM zk;#x55V?4`1~S-Q9ZoG)gWt~3dzch~WB+z;L$2W#J5h9r_$Wq6)}ktMpw^^7r%kNd z)^q#dVRkm!UG_DQrH)%bfQ~;@rwH;Rq-HzggyW1WN(cS2GB!H3^+RPAx}N{}(GTtb zXc^kY$96hq;?2Sa(c?hz>X7^9>W}2S{Bf|rk9Nm7_RnCWRDHkgEUb~vslA+j2Htms zm@e#|N>U}zN=phXm}hkykR|l&Q_R=*S$}XcaAyr zwCdk-2Qsz7Af>hbJW(5fCl*WkjkIJKATR+a1<{>nR9&H0?gaM?Y0+-qu{0h{_U}j} znmbp&8V8L8LUwh0QyCHmJn!DsJSJ;$9*o5Kamznw*1yLi3+bN+!`U3adC(*h${X*E z9r+d6^yXNEOKw_ij<}C0Xs>f39fK|U4c!q$Hl2~B`TE}S&PL#%u_9+L*xrtjISqgU z)$!|^TLaJ*oOCzi&7XWI%FPRd%)y4BIWPU{{&E+Y-p%#s><}C_o zKot@x9zu%?Au?F6y_}N)BTfk*Baj5`FP*sW_FvQ_bYLuiN&VDupGnE_| z1H2*Zs~-SKg1DYO1XENhV_t<&>&M732uerx102QzhY+zUztuP-Gj)K5pq|IgKU~B} zpkv@DUu4mqXpx&=YBNLm4H3*5Me~h=*_;Uzx%6kp z;e{0Pd80&tTl@OY(Kts^X!m;bwQK4-WT{B4_53nV{+Zl+Ht>d8!c^=ZzO@3s|9_d4 z8Dx#nRtZP~&>m!L73i)`9Gfklp+K3>O!hBh>$gVL1aBnqwXh!(obf9VIi&KGB_P`| zDiDH6GJZV?TBN@Qhq&|j697$2Wa7c^ZHPBr@fW)Fa0{cj8h6kukR z>rhdUV_+PF6eJ3u2YbZUUu>2C8ZQxPGHAVyJnPBv#CRbk()dxO8#GV>)^+I>3-__* zAmIaO`Pnk{>ap4a3-B+*%I_uR1j~++^85T>N)d(s}u2Y@iRs(^pAHa~QU`JJnJck&S$I5#3Cs>^eX`VKq^<&N+fXsnR z)zv$H)JQS-{r`^&Vv+;>3orPIgxd~av8rZp{WWeyPSdTB=ES{=-Yg$~LXxP$RgNz2 z1JzOND)FW58F5B90Fd*yt`Z(A_1Rh7O<++$_3&|3E@F4w>~RMrldEmq_8rnk`#=K= z(n!5UsKjw0piL4&7`h$};z!=E(faF^Aq^q>rPs+FXPspMTDC16^;!tsG^%t%IDeDB z(kq2AuC384wbLtV7aHmTg#w&4>7Q?wJu3cuUfg8~`)!Q3PCsFDqsaMlk5v5Ro4i5% z!mxk5{}mF)Z(O|ZcdAvrJ4I)cEqZgb+QHl;Vqih!3b???ZBlQ3ArPLI?%^#4MW{9< z)d%L&3NyIO=*`T|JDYv0r8~Ll8e-(L(jX`lrrC4{qu-`Eh>*k=_BL)W7IhXh;42mi zO2RgMxoynEEee0SBlN1hTqQBZc&j$Ctzl=|B)X?5g=;lyD&8R;V=L2w{>u`IuJr7O zNZKFnvzg~Qn51Ss^ob}Dcim?_vx_=YHr7|&c`phleJGiw;00j9BZGt`Z2$MN{@=9# z+PIREpL(--t89H7Da;Su4UVqyI(O11G+6ym|KaRnXKovVtCg&@5MJnXh{mj!FI7gq z&@j?6!2Gf28m&4N=;Qfplnb66Gt z0nNA5MpWkQcL`h?(O~_z22lvC6CtsVn$=9(eE`as`M%qMa_f-gKQQ(DL(&eEUraO$ z6V3DlFuP$0LDNpmn*6m23YwzTm zF0@?&@Fn5? z%Fzv*vEr1!BsO|9lQ6z`+jhq$Ivqu3g$v#TpJ!-OSW`Vr*FeX$&U|u0MRL4u>?ROB+@x)s7L!{wG{OQ z$T(iBXO(gs&!=pH{IzxvM;+V;Vab9J02UP|ts3n(JHPx^zCvn-H$2;H|6919%h;sc zgH)$hwsxJG)mX6;QvnxzOyEACI(YxejIPL3glx{R0J0Xsya8j_Juzu?J=4`7`eQY+ zbstbqC!C}yPd6%42rqKDJ(&anPqkDba@zxIQQt12QrGIOhlu(igpb_mimU1I0T3x< zD#$qsLumzJfu}#+xEx8X)&M?jdq&;8qWd)Qf}pGK_(=vUq*HW~0F-;aIvWOI6g{Vy z7|QQeCMPZKC3N~^(r3-PN|ZHW@6@h@+6#0rl~wfS&#x$KZ(^zYaqo=7b|8pA3F&NZ z`-p0wW2ysEz=+ssv3?uMw83{nEG5iN_P6I-I!m!O{(^;4jX~KE&!CHL=LNWu7nb~w z_JsGAYmZ>jRzg`d$h4K}Re%f1a}uiAEu>~@tkbF8?VX|D`k;uHm2SoBP{WF;(qPge z{d-HctT)$l!|t)M0&vFlNH?%0tp|gRxK=4MxdEyTFhH(!V0QcU=wD!m57y0y{9`=v zv=BDxDMgb)slBAFs#(eQT%(Pgo8A_dRxKQR03|oz14@k{0hCx#076>*GMjh$%4)Qp zMGdr~4xudSG~Yco71YHjWzV&wu_}v7@&xAV2|s4UcWz0I01!ZdUJP^SK@d^b%MXm7 z47Vtmu|v%qX)KH_6nIf6=BaI-6*w<68uOMLK%!_8q5M%KUiol%t7a=dAx;W|n7VoU zCny_NTK+8*`Cx1haAFUc8*U{gOCqCG(;`VK8VRm&Q@A8F?^}10{w@o=Ovod2-Lpx2 z^j_QHQ0>9cO}zNlCCX_CxSKn%RT%EO_!S!_KJ*R0Tz_%L9mq>b>+L-B0)i=R3viDyy9QlJ@_s+3^5Z%)9j|uAw#HNz$BVqYh5X{385&J zV|$~b+E#S{fUbJ1_ah!QmITpMBe5oGPp%cW++V#{E@ak)zSQ*g%giq<8-<<_cCyhi zPZF0MTE7E{^^7aV+i=a@f6HC#W*PoH2CEv#NOH8oa8$U2;ZQAkDp4Hnq$D<*2#8Yc zihb4p5ESXHFLQhy+8EGs4S^D9nHRxcpg(Musm@dr?~qvg;#I&CAYb|u!uyJ?)Xie% z4ES|+APo3Ic~AL5+TmQ9jZaTT*p=Gt2EkHppYJ4B*sNWt`T0!j zJCXG4>|n0gm)@~wHA_{tt0#8sX*bOHQFjsCPl!`zT|U?qbi07 zXbr+W?!6(kijwp9v`W2Fnyuq5qIMRX2{ZF%A^b`Ssa`lAQaQ}ce~;Wu?xpI4c0o3# zy^p!L8M$f-+{X_JL9&5tn&LrK5TLsK7vu>WBpellhK)3DRgU118{ux`;pSt|+;7rX zXN5v|q)X3mwcJQ14l_`R8xw|U%8c`bv>fJMWj2l6(br1_(8gyF;u@)IV<LyOyJ~-MUvYM34JKHuQe1}knNWI8 z*Q>T2XD@9(JgDeh@-ed-cT1s@1>MW2zH7pCUw;ry>oXKYHDBtwgyGzbme2MZT;FA+ zOspF6-5Ob_f4pF{RZ${o6gRl+!KdJOKNYKAn&SBGlF^2=uf+Vjw>GGvAS%8Z{WpmH zwsFDJvczQ+-S@;PRVXBA#k#a zl^$U6{f#HBH=b#>-6RPtzQm9Uw3U_uVi-4>MJHTRw<>Kmyi*sy?vCgZcHDHY3Z+97 zWm7U?tl#>^;$0D+=K+XHsl89=`_${F=WPm{QxiAsdFhoH5HnrzJt^k7!oC-40GXn#k;}B*P62hL`|PZ>e0ml#N<-M!a`mOrxA9 zUbLyR<3mtwMX?_3x(*$_{0+V~=V!6;tfzM6!_t&J+!=Q1-Z#rI4-wSC;>E6blZ^a{ z$+6A;(}n!>Rhbe^FRY z&hLKwKJy!;S#6me$;Vai7ln9lKc*B#e=^W#uP|4vwB~*q(|kSK{A832asoPVU<0sY zTfMby>xj5+*y)!dZHZ$5oS&;#XZ}jnqATzNV;QQyKEnn;h^)@V~aNTxo5gD*+#?A_FUo?`PVzhb?2Sbkz{#QnB1xwSUXF(Esv3!ZS&IgChi@+Ie_G>?dnautil9Pjy&;zQR^^ZnM&3n|1C@AE7_G~R2ALxJX<~>O>raSaKnazl=8E-FP#tIu{VlrM& zztU^gpz9>@of+AoH4t%>AJ`+c92^${>cV?C)^vqQzLM)dPbowzjbmF16E~9)-DLd9 z>xe8$bF^3uDEvX?P$kkC#LYG@vL?D1bhqg}vC#a=L+>j6(vg)(iHv;g{>EI-^-O~U$C9~mwO$=%EKnJdkNzqf9YaTLqQ08 z)SXQh$KnAQ++(MrLr~#bI;WWtO`N1o-Xr>BfAkhs_blo`>?36dj~QOiUN$t`{0N+f zvcF_sls26capTN=x(xquOhIH*H_$)3?)&oStq+l6!-r z9R)QS^UXp4ZNfm%P=mheiPsz8lWJ*otId+cTW?frdqpa0fWu$8flRqAipD5qX50Z(JpR zi+rM&N5nXoX~g8+%>N`jVqKAem{&$!+I)&a2ghM#PW92sIGrR*Rs|)#GjvBHN`I_6 z%c$w)$}Ov)O2-~GCHCldpLE4JyY2F#yr+^J(ILR2&3h#{?65LyIuY`KPrD&CChCCw zurYgNSU(3<k9u0|9EXE}*^(4`vwBl5h z@%2SDH?BN|CR%bqu2jf0n?uDOSi_itri=7b)PoD2H8^;(o@>BjeZObpj)H&c&KJwR z!h8#&S0{6}$R+-q#!i(IT5tCpg*?(5_3L+7=F7kc}s`{jOdx&8!V%oY}RD zddv%JD~;V{ek&A_jSHvd#UWuOH#9QK+G}8s!F3zEO7E_|Ma>IcuCj0rbKW<)$jqm>jI6O>sY&?!{&_BXaeX^Yc|YvsM;Ey2{Ci&7yGn_{sLnqZ%qT@0Z(_$}z zf`l4#ZnI%*yVRb&qBjdUtj5f{WMPlP7{eSzEXBF%3E2@%^*dk9N$^ZHq3#k&CKzjb zZ&FcM=t)Od9$oIl<6P$i-aPgDBTj36SM6K*zsYc{f8@QLg0!3=oSIkx<$|0#>8L2f`8=Xjj_czDtTI&f8WmhM ziZ>8klSt$;WS-w*=WFkI8c)ws*@=B8NAO)hUy1S&^VM=@{d{L8UC1HSzATrXbYvb7 z`k3lDz=k_q%jy|>r9}}=+s9xk+jyN=E^#1Smr0rkVfyR=qu_q^6-KqZi0cCpn)AY! zU+Vcc8)8$hMV<;N3MKn2KP17ef0}_;-f0h|6cvTMn6N9?843+ofr+Gg zelGKK(Ndc%5}WX@(n~?rRocn_+xG$)7Y;iw75Q?A^%^uD^fCs755F5Txf@ zX7kwbPR^hb67SA2E|0t!ZGsZT7Y)o~3i-X6=$WEgn~?#^&O3d(W}ko?|{#NA=Osu`GBQLkkvmr)U-b_A1733ljNenwW$6{fwoh<-Op zQd(&#*>qgL2mhl}mMhv^Cl+?NANnZ-z9GtCbLIuXZSK<>J)&-e20e;O;f4cU|MGF- zMF^s=p@XysosgzwQ6=YMl2(ufLoextt1ayV`>z4qy7Wj0E3G-pF5TlV*UXxUK7}ze zPg#`d(~Nvz)o3O~_&}IZ{;x#m@hO~WWs)crhM>fb(7z%PN~lOXEK$(4q4$C7zYuIM zEH6h#nloCf$jr0PDaKn}$i96)0wJ^-t9#uX$f}*$e zE8$8*ohxr^Ha+XHe#Eys`GhSF7zZ9c%B{s6etjWT{7Q_k_)^y<;~ORZHj`*mtUVnQ zPQ95TzVUe>D3FuW`RcDmo=Etj8)er3nK?{KBojxKRP{!U+v6jNjpVMX>D3pl-!7XK z7)lw3)c4d!`tQW~XD1|T3)DS%yiUoz*YcQ^Ajr#+!oR81EcRU~Td+sp8NSE|TZtdY z3JG(lTD!C}w^~%;3zdHH2GkGo7Sc^2b`HL%XY)Sq&PmO>HidnND4M^%*IP!$ z7+TI!M{LSB^oo#AcjI&U9DqgmBZqU?IPY|fkc#nw96=&trSKiI)8KG z(L_|5d8OZWa-La|{{p68$v7DvS+>GdpEBvwNp-Z@>yBx8c=^KQ*o@?u3QRNTS%@#? zDGU2XmYt<-e&VKW)=uBiv!or29f*0Cnquy-#?;=cv`Jwk>4W7TJwAWjYkbyEY>lY9 zWxUbuez65#^|lt~JfL{cVb*wSw)~^WMgFF|MXT^zWZbSLV+d0_r;rblHFD_eg2P@{6N*8x5R>0^ERa1AGT@Oo`#F}3#kz9Hp z4~w|Dr>UGpl*Z`iPhFo0!%5|yyz*Ii5dm|17%)*@i_biVresqpjrbaveb6$hZG}r) zj~ub~AACYcc|wVqI<7vUvup@lRrDbeZnyeaisIfBMPa_0>7pdX3lUqEGHj@8h>{v# z5GhkCZ~y7*Et%DUm1Z*1;M{@vYrY004vu?ycsWUOO9SiNffgKdoRSVN-;#0}(5wW8 zwISa(%NOzo1Vm*oXOgO|<_-0gme6VVEnn8>OS|Yw8`UZm9=RE9jvWita>8)xOG_%^ zJ}~9OgS{^cCMcSVA&DPSbb2-vW@CiXv9U*o2vX6*X7h~+?l99kuPI*0aT156V2QMw z!U`=(BXhC$EJ>{I$1Rp%CY9|%7)e9rCuJ45TdZiQ&$Lo<&tAb-WU^FZl$AhS1l*hy z6IV6GLZh8c_H+vs;xs9nrfiDfQ3$c674P)jg&WVxQC?b<{eWv);o9q)F&LMyz&>}r zVKgxi93hmM{DQU#{mv{`5@z$g=y2A+oc3j!<2wzUyn)$l!gv@%G=&9;H81L!D&az0 z&|mni$2LB~RQjgN}-2Z*ZA5@okLuB za>(^%TUy21;E} zNxOeO@pm9S-g3Q@C)QU;pQ|~C*~=V$USBEtB>KW5Ii5kKlhmH(q}H#i^Z#0)eO!Oy zggmOmDL+;PIpH0~89ALP)gpt7ctprK$1Yn`WB`w_HMdDRH{9yY7x0>q!bcmnU_djM zgB*-xR!aIlu%tmsE{KlKGl&Xz=@v45up?)|j&2FpzB?FK_tjp{#ay|Pu(Fh*=YNs* z)?raLU)=a3qJStVB^`ny4bsg53kXO`2#A1yv@}adFS(?Igu)^vUDDmKNH<7GcP+Kc z@80M8)ceQpkN0}7>;7Y|*}dmJbLPxBpL1sB3`>D;{PE>#1q%x=NN;**-=G7hS57bN z%A0B=x#6s;q-Z1)Y%3JkWsajlSOXk((w_%KmCvfC8?(W~WPV!(Mh@wM`w_M^wLt=5 z^1j3fbMgyze1pi-LH-YAEcq|qZ#>Min_gC{TyoG18Zc{1_+kqq+#Q$Vvy)`BlZsPb zYqV8hnn)JpvY>&e(|QO`aNK&~Mx4f{4czR+xo)e8brJGeRV+&6u$h(7Zs5%%7iveC z>0U3N8SFZ~YTGB^k$U+jTYfbI$*spw8gy|)b)4f;hZ&0FI?bji(Hnx&cx z61N9oAHEmL9Op_Y&&Vt^>PjE5+;L=G!Lzh$RZ9a-;0<52m&tcs+SXg&X0%Q*bF!|m zrWNWkd?xM0s1b#Saw!&=FkrMh!qS+}$W7p;UXWZp@Rpt7eE}woLA3AkZlAN%Bx{ql;@t{l5o#R}5ZaQ_G)2$h>9 zh)==w<>gh|nGDx6GivBaA<9$%i?PKVO^IpoN&sQLUI zB0JN;L>g1df2(WT+@=1ZFR(>+i|^anlSPS3R>L`7+fgBukZ$R#OgE7m&*(a{RJa?$ zT12?pI=b2dLN$`z0Jyf84XuF04r2EAiHsek zXkfMog=;8%R*3$Hk1_|OTJQgmYEg_-TRe^XUctYI9j_f{!B*%oC7U|%A#fq;+D%_i z=%^Q;#JVZUg%OHJRo+X|ZYQ{u|GV~^{c1eOek)!G#C4cgQa;whl38&vFW2??cOGg! zZhmGwJRlf%Q@4)fRS=!h*gaYc8zBw30b(0F-S;K32K6V?&W4@wr4`y-?}GBA_#WV~ z@3LZBpo!(MDVDN|ieK6*`(_buI<&^l2hRV#5WAH0(Z!C~df^9P|bG zV$LS>-=Y8(x_yJ9eMy{yhz{qvGJ05Z%|qXQ)R?`CiXG0U8R&p=ur7jMPDia~s6xX0 z=75Wp&JxG>&#jZRbnkASVp5gpjKy|#rJ1R|=yAvz63mSGl=vNucwAqj4YnyPV^)jC zivu=o-MMkQ7AZC#eXEk!+t4NbVz%u2E@jHYgS2(=+&;mPsFvdf^S6^zyiRR;YzsU| zw`{WloF;3nLy;YFuM<_L!Xw6M8%k`~?=xk9&m79fN4nCp8YRyo8y&9;wt+e0(!E`MZMGbGRF&i0yJs9+$?JdXRz4j`RYlay zH{*TN{JCI2x@OKl+w|IxBvnq{jhhR~(47&pk2LwrYfs`oB}%U9#;Dq>*RM=Hshi59 zVIj#_BoS0Jl?=}^*=2nf{Yt!d<&4r{5vc{~K^g~DI%gh#52L=c;8S@PeX0sv($Mg9 zvI&tMjgLB}{r&pwwQzIt*xR?bGP`=OGI#^NI(>byu8$(E=}w9~#@v|oY0&O<)gu4p zXhvpb>$!7-BA7Y;&qPome{HB)c>^d|!VnwfbRI0O1t3WaN8To|ks8=u^XC(Z*)E!5 zk&SbB-+H-y(04h;%BY9cCQ6SP%VNdV9)!0k{q|h0I8MT@`cdneekO|`mGnq25wKR; zUI>l5#c5MJ-xFrc5ASuvlBMnV^rA-BJKlCCha*c)kX}U5_=Fvfmx;+eqw`CzE%BUL z=fppaiL_TB3t_XxG;Y2J1lrtth?&BkRGB=3@2V8g0q5O#t$v%8$fjPiq43Q35`U3R zUe+7MMsyH=1@mo*`2&zpb%Mx^rC!oZQMe}Vr%hJ?nthVrAd2&YV%lL+l(I|gvfleb z9}CbUHh8>m|C7XgWg1g~$+-D0=!Y=2>7??+)AWRR|Alv6r1n7q)9eu>&jQMTgCdcJ zZ?z1~k8E<2iTw=O;Z>9Twx?9;ev#@QbbJJOsPg$jI)7S@tGxc~!bm-N`0Nau!O4ogyUgtZ z>HXO^JQhf_bGubiOiahEx|a!|6isnTeO2CsXZc~=v(=;eAwOOi?Zu8y0AO1rm7;DL zpY1-DOZDh(=^$Ex60v$l&FkhB%GIK;Z+3vd#>37DMQ#!NC%9Pb4B=0h@;(LxyluH2 z5V7q1sGm8MHp-vvJM_m|8tJ?H$ue0`23#meiNxK1Kf~Zrs4Iow02lxKjjz<4#kcyp zEp68a4r=p;ATkOaaC?GJx#>qx)Y{{{Zl;Hqk7wjk1xE>liF~5pL}hR;m~oWGs{~1cUz)tumMaD!?HnsDvxR$uOcv3>Ivkb%(RvLV(MA7-KS)xcbV5C$gmBx8xaOs`7+6gFDse zc|&=~V|oYhp*9)ML1Jc!<(^GS@k8r`8XLn*lzm_Q^6Y#b9})OMXvTv$vDSicpe zW$Ui>w$&_DfP(Es!AUX^?hTH)ZuDSU-B0#c`Bo1ey{dUsRd9Yo6`^!{{5~0hb_%j3b5u%#Kae zMo}BUpn&Zp#nc%qTAAcbTm$U_gPplz%f=|IgJV{GdoHu!JFJg++aeR1cLKvXLL>t4 zc$F@Cj5Q}oilQiGCmac}$5S=kv;@oPmE@=4=khZ@eP{aiq4Z}i^0r6ug3J|ATTn7n z2k~q8^H7OXIKc^C9075VIS6+olqcZ#R*(Qw_#NCzYR@2B)_aK%=C4$S9DhiUIW0b6 z{sW7>IYyyLlVWS=0+)LW26{~9BN`;&BV+WGuofKdfo=ORs{a_IaHop|i{KEJ%#zOg zU5l_wtnHJP#g($w%~Z5$$-=r{ft&M0*2~faSC%>@+lo1YRSzWV^CRp|eTO#-+?rw~^(dwmKKO0_O&Euzy3`1Id>;i9vgfj?R~oOn z{>Z!o-dt-U3g%Uv{XyZ3g|F~K>X@}Wy~lD*f2M0O>@pWdrFi|-PfuD_!ozo|f0-cp zD3WouR=tww_8Q0Cw*+kWGLXp>*7)KVFW#!Xlld6r^4?+F9V41gOt45se)k)?KNABA z7Tvm!yP?3(k)m3v#Q(}J2W!kj#wgHl6-SUVI`B!|G6+oCI|b~AI=CaI;Q&n;tL*jG zP&el{`E{Hl)|T~yc;sR``O>|w3CN%pKq*(96E4uf_!e8^Ba1>DE|LbpVAU2CEna}v=C$go%q%sfj8fj?Iy*D?tbKuVu8Jhvvq zLCW|t*Zm+2cvySe4`FsK-$2xfD}hZR`{`0s5bHiw6lLJk<@-*R-xB6Ef*!Bjc7lN$ zx<;FrTZnRFf97W3itedmTd=@4AzhD$6QP$@{@4MLXS{0QU3~mKe*riwHk;-|>=+0^_*e4|W*dtSvm~-Fk@i zQ`X5K)Qnt-N9f4gk-Lj!B?0*)zR8kK`U`1izg|``$G2Z^i2s-z?dC98k{|#9XZwk| zz%SSMW^Oxsko=C+{?-IK9Jv|0BQqfJtKC^4vvexdGI>4nSdX$pT*c&|Vbs#`jo&U9 z3`2SbT$ca571p2p%{S6yt1qpW-~V8ZO=BMH+(mbqMQ}mbg>7dM$y-xO$t1c#zlOi& znKc;O$5HyLR`yf8QlQsM%b6}8{Xg2Kem!4vm}xndHGCQ>bzmBuOHVX1z>WKUCd7M9 z#Pqcz*Gf>Znxmv?rzIl_8u`sWQYFJI`Ouq()%`3OZ@|nk*I|PnRC5*+?WHRvFO3cQ z;*AU38BJ(8pReEBY3tO@(! zV_{+wxVi!hWAhQc_t$8vB^A#m4z{++(%Zy=2fzBg%^zw+gYb@mAucbu_d=mE93;Ep z1K>%SX()CFmdPqJttKHHyDivCj)ihp=EzBMnV~r^VE9*SVBp7Par1#x0&^VVmdevTJ^gT3|AESnqepzW7Y}>&5NrW3zBl0yL0KAi z*O^||lJf>e%I+{aZ6d*!KuXxpAB1663wbxOQ$0r;(rZ+%LrxjtS`=X9BZN&7%&ED_`hiJfXIi{zuu>!K6nh z9LA7=RjQ>o_C1+Rsbx^8Jd{tD5_z3*^X0)pKJ%*R?%Ny zBXSyhl=gzpS>8Uc81RY0yoCJ-Y~w{CP$?=nbI&KL@0p08~CCgh$V#cU6nNg zI9o}3#s^9hsP;@pt0#x#7uz*SL@@o(Lo=wz9mb&wSWDzgyKo4vCSN!rS6sMM+TZIy zye*2)gN};%z{1u^jYZniH%ne3p?|Kujbx2vVFlVHavF$dhU=tU|4V7Q@^c_Bi3Dk+ z3Be3_@sMLgaHfB1MI^g8QfjMLPllnQCs1-ZW&L9H%ZoK8@^D8#xWJ?%r?|eb9Lk!0 z2rH9bBP8slbkogC2R&!n-@G*nINp@cB2~_rd{cz7YEy>(*i-R4plT5rlOS0fC`#z3 zN0@Q^#1VIo)LPT`0NKec9M>xPjf9q(7cWsMdMF+XAZ>K2GO^E zy2HuyhEbiBzE-5)_H3Y2aDC`;#(Zh{^SLh}I{BAFBFyo#U+Thui6PB?3vW~V(WS&^ zVB%Oh@8|FRR`}=_V?((4p}mM2^N+uuhq4Txg9UEBt*O|d8K#+te?#uX_xea5R zw-3`PPy>Fj4c9%=@n>F9nZ&RS)J9_-jqkVeT%XtNGU>I^fr9cDAiJfi4fQeOK3P#R z7yI`{!Z4d3^y^2+4RDbmT2Q`0I5e=%k-#r2P}Irz#8}&8fjiF@5!Gd?t*|we=c^$S zJnny-<(vhPcMaR3P7D?f-%9sV-SWv^d>VM^WW3cz*cbF1=lY45sOD@hWLP3=@@f2J z-tCecbmJH2<0Sfdwws~6;s)cN&xz|d7V=#YCgi69q&OO1H5#*yHTTKNA{Y8^_)q5o zwh}MVseQ_vpG6hS*b<$$M6T(oKA&ky+9~bg`>sFl`}I0{>?q6GlUo#)Ib6|In~&p~ zrP`3umpu6-Fmt%|Djyk+_;)i_b#cN!VxgU*MSYs$eBLKaATI+u|Y@7 zaTfE9XIi_2um^1MLhI$MFdKXPl_UJlfSR)LN zT;+&~{P|dca@R*4?^@!R7%ri)It@Wmpux2Tt$B>*{@=qO325t;(WLibf6JTnB_NNv znfb~OZxQR&1HVpk`OQoC0EN+R&BvX|82BUhN|p3K@P`S2?(*q51>t{7Y=Rgd+aDB* zsezgVUZBi(_xo~x6!2>8*NLd|6rdo8%-H(VYXBSv;5lSuV5H4#(pLGWeoMWBR08|NoE222>DFi(sx0Q@#B z3rGN-O>hCfR`r{>tJ4F8lQL~3UVz86D+ry@f5-+gL;x1iQo}O8;I9?{$4Ctr(Ye^| z5TM551yGK>Re1gZ=!%hjo@=%(&_?=TV{To<-|T}*W2|a-F84UeKO=hrjGda4R^k&Z zrcyVcD;sPw_I3`ayW*^lg?-s z8x&H|`~2VlQuTg(2RJHF4IK9sAx+H|{YUXar40a1=aS{#0|@Q;1NaKnPrL$I0}R*i zWZw(JNcj(B=?vSyT%VTt0{BErZNY+GCstQyvkrDsrKW=K29k-WRPjGQw|NIZ{$kht z1&ROH?v#o$s)A02q;6~j?>@N4l)7j+m}&tW-FS|cFwEC{JnOL%B^TsUV?WRLRiq&B z-&q1r1bA=YRKNo;b|72LM+b7u&|c8D6kXa4&x5jBBO?8UNoU=IuQM^l9y>`%8Rxi=m* z{-*=_s$X;mMXN8q(SEo496ezb==vC5Q75G12~2K4lx%1^FzkQrrMde=3y?93@K?eA zs)CQW4`W-D86|wmI1Q4`bZk~<2Bt~vHcG!@ges<3Oy|Y%{?rD8h5JfZlpU~1xOAe( zP?38(_umok2$9YS*ZHnnbyqic;!?N9R~2t_>g4+)CahjSt)|a4!3_H!!&fG<->atp zQ=W_TJG=JZ8We-@ld&~{ON``Iii`sbbPMh8FzX-_o@$A^BEi&>-an#f#U^}jQ0|65 z9GCi_o9sFTdce`;P%7ronMCmBguv?%xr zsQ5=p!5Ydw-^4ECk8BH|7+Pg-}d*q&8Dt?5YH(wFGQLM zqbm})p4_}Wp zR0WvUC!&CyWmSx%q^JUw6<3N?{X`fAGeTSt^6%KOq_w05xdes!HLtC%V)IJ4ZfVPb zE4l?rPIsn9XR7U}(+mF3evyonZ7M$pVT0b>0d(Ml;2*$WAfDl2bRgwv;H5OE{;K%aNHCZ5&cFYZoZ-a zW9{_;gDBcB_Hvx!7V$X_zz9EvVSIgnLQxelwQ;V$gD(G?2Y_G6($>K)tvOpd|8@Y1 zdDY`2+kg>^=|Bi5H|uZI>|o64JSul4i4>^$fK@d6uRi~X`~B0$pp*B98>)Y|;va-D ztml8cJeFq&0aSt6R6d?vT#$>bnDHPN9niw^;mGv=Mlgr5bnX+U;rsq1ZvMiTsUKX5 z02EJy$Mc-y{MqEYK|OO7a?YyD2L*HQ!(Lq1 zF`?`JQ9mv~{DjK?_q*EKe%szQi)xomzCzvXIGv*6+AMP(*F@Zo&wpHXPJW;MX<*w> zs8eFRNL`p{f4JvVrG^c{Sh7br03}WU2BEE?Q?-Y%z~g6;?>+xxRWZ>oGXLNRbfreN zacSD)_#)jwS8;=xc1BkWL#6NCavxEESLSM#-XnWOviZvbV_?npnD8r@CR5;IvRE~Pk&CdmMvTc zcqq)H@BO&m+riIv_KEDTjORDK)c@66Xqk`qpN(3oRh#(I+N6siKgFPN7#jg}Nc0L| zrPHo{l?rwoW&mq_=xaU!rmRSDJcAE_v_`CYI(dJ7Mfw)DE^y;@by;5`3mm@%p7ak` z(v|xNB;(;H8Zl#mziL-<03cHb3@`}Sm)e{p{&0+VUgAR4uK*nl;B+M_z(R7#{a`ov zle{-%00D)+ewzH#oU$}9(XoHJ0DxYa15m2nS=8gWz+8U_{P8KziH$DMAYyAz>vw+y z@Db1037`MHim`(KHiC)ZS7N(10*zE-+>nV3twz8i-ot=aN~*>TJ7D}Oin_HIs{q64 zRrF?36=N?MVll%yz5BlM&pv;|{V&?!_>Y_LFbw#1EYBvK0|PZeE|AwnhCXU zV`e7!9x!C^lggQ=e?cn?%-X`v6aevv{0A^Id>WNK190kLCeYAf%4Rr_@)}q_KxG+N zPy(;s-zL&g#4zYB0JlZE(hI-+nzhIyvJRW#W z)Vkn%70{xW-Nzc;gZPCj_Hg(X7+E_zkKi)vi7e6l%ZFVyFWW1PohXi;}e?+6;+h3z*&Vym$9*vGF zVE$iVKK|603{c;tVOt=Bj9~u&w&~}_mW3{VreRQfJfPNa*2Nh+5Nv` zMmKT(n=$~5;Qm0Pj~EItLLG^bDUJEBeF*_T<wlzaiTnS)Tg_ULUFajc&eY99#7|k!k!DTTW=p zqS;T`#oXMnW)ZT)4A+jkw)T$QMef{?^Zv@X&i_S|uij^OugQ_KN!gD()Zvyh)2@EC zOUjUd?yoc|-fVxeXWIAe5H{|u$J?5HM-lA0AGq=l8n0hYd|0#N?q6IF&N1djL|h8A zRVp{$^I8PtNWp?ERO-~Mfox(ekD&8HDP`%PPQew=4mVTlU82>#foPuM27ihE*yE+D z7KZ)W{>4|D-`~q1)h#a)9y6xfXR!l14oLM12$hO@eg?oXc>oa_X={pdk76Xvi!k4p zO6DW?vo%CtS&9~g!Ebi5BAJyf05K&dni!jd9_!%!DSQ5UL{IW#j2nczeQEf*iW|{* zpHHqL8T6TM5&2J7>S&4mUTrMu=9<+@>`Tl_dUZuA!)w~6edV;FXEOr#ubR)Q9sjOx zS2dY1{@Hn*t28#-w<3S^ondH^P+64V>*nwFIUo2V|1k6Fi7C@9F}9l>>3-AbRW+j9 zp2ELA(_i9izu$z6GCJHhv;9o)87=pS+>IZ!l3-o&9XO6qBzL7+WK^&E`u)1!(Y^Y* zgGmbR-ZJ1c>U4$=+HCe`_r+Hn_nJ?ff_lFL9*fkTU98LP4tFnB6``6ek)kc{$G_X( zzOIraY_!i-RKFKTo8QGho3QTQPd<^Yh~wvLpkHJ#F6X&O_{i=CvTA43b z`>SPXqDsYZyH-)rX6lQ5-XrIQDHFEYboWLpxlq*mB%=@J9?b^hea{NfyYAULy}44Q zrxS%XS38Z3QIDRt&Pw)p?aZ|jTu(;p=Bh;{t|LrJr__Wub*UxZWzBoHKdn|lp6OB;+ z%ZI+G-64JF-BnT~!ES+Zk@77|irvRu2d_+EmGbx$hMxtg4M)E{C@RO_$n?#4gUaw& zTpKieBV_DXK3@2_$+Fh!`EjrzdJZkRM@TL15ouShMCxa67&6qcn7;qn!N;OG@?zd? zr!LWTe*!U4WRjcLNxm(T&lVkjm`MCtl1 z6^QT<0g`XS@c-w1!7(ze@Wgx91f2;%qqs5)4C{*wR+V56g{oz;UF~4=H5Elh3XFHd zKQM?$I=7zcExH#ucMHyc4Nd<$7l7MXY`sC?>BQ5%9BV1d5%}iW^0Un8pI@72l-PEx z#dd$_%mK#q1U{Eps@9ikOsXnqVN^(uCN@ekotDL ziB(#izA-ekS8r$Y+$ho)-N{q``)u8|Le-}=Jfde%(B_>^!8NDJt6FPDKhKSuh05HF zi=PF$MI>AGL&meS8C;$=V?FUX!LO?)j1|C4@Jz4Eb_V9n8t^%DVal<6(pTA6YmTnp?c4w+fBe=xpCLHv*E2Daj z9h$GE)g*TbD89t+N+r>ovC%A!rrQ2|ljH4uHSe%Zc|QYixrY(3fzuPguqEulD`j*zScY35Xkz&SF}^+c^5l zE?nYb3y(<1{kgwV<{wHIA_dk*w8iFfk>#G+#$ss?OspUnz@fZv_%%Ma^Yil5i^5 z=h3gfY<5)lgH2kw|5i@a&0p-RyQsZJ$e@T}7yE-gPq>wbRpw)F5*uFht>Yq3oj*7` zH%2yGmUukl!KXp7^s%M$SZJuv$WYZH@&j`5So_kw9MuuML(x|sZpH%9MyV>O22Qj> zN9`A9t&;v5F`7@St3gTm6lu&&W1lCFE=TuQsDhs9_N|c3#FX%KDJ}>flA^xA*gdI$ zMYoof_*+tS2ar(%Pl1)P?j6(5Rqx5q;nnnaD`DiLu#*QXoTqxzz9kLHK4b1DjYvcEA$XB#+_dZT zIvq>SL|BDHmA{xO)K_*vTcWD~ryHDKpxAne9^0&tn7KM8N|zjG zZg$_9nLvoGzkzW%(Cw*0_6{~S)g@_ZK+8*9hJJJs!+Sozo;TlU)*sesy|x!Zh)r(y z{@7iQc>2zR1&x@mu3lKDCE-(bCf*xc>1p?x>ZG6}U#pGa@|@x~dQn5TSTDix zcUtQICm>yFFk&21uGW?@CX-+b1U#8`d>ZFeif=N9I0d|~G-)4aaQ z@!*uLAVZYztl;uICxf=euCcu2hoHB;uw{wb!f`jZ?@yTHSMC&(i>pW~=bhB;ORtVo zaj~j!|jq)+CuS&fpJ9i`jdfJ z4chB(B9ggrA?X*)14@ykQkv_oYxx)Gxu(N4X~?hEN!wYX(I-OU&m=!B_4-&dIkO$#+ow1MCOrGobO0_B2?2B7XY*c&Iqp#R%B#IiYwGOfw*_(cY{;*iS7I9w6E*yPsF?2y_+hG#O|Guk#yC;NvFqf%`kvfCfebkK3?`IiE>8IpqZ^E^Q?Vv5wJ#p=;;8zRC&O zn%OyK-pL0eA)?IjtS^$uFMX$=PFz|PhN#ObiMPJ-FPpn0jfuqNMb(-Cj-yFU1!|>vF_nAtd2m4K0^)0}ztWhHd^sjwlPZ6^&+aaQt?a)WN zQ)RAsimvL`11QQxxZIj?wz%EF&h&|Tddy`ycnT?X-kPm^%mlA}6Rt=~c>Nv(jk9<$ zamuS!`2n&%{_Z&Hw#~>@(<$QB+2%(^#zc?p3F?_!8RecebhAO0;g$^SX2pt;6NRt3 z1y8}NZj$e6T*!l!HUYs5rSs(nX=i%JDT-euuf6e(KGg0&N*;tu)yMCSL`0X;Np>j% zmuD4N`1i17qOIU#>$NO*j+*Egqds1bbnoV7KEOjg?|!^^K)iCh`*=u980=|$bvYZ$ z*q3G*YGr?Jzdocw>er?B@*|XPX|nNX#&V*Mf~oZ98jdU*H^<-HASR=P4G*eZ75E|x;d`8Uyj=gKHCg3 zN=m-Rc0=bsKAUyZG#Y|iRaY;}V9jQM;s)rquo#866+D(CVuQv3|(mg^lbzPx8zITVR?V zBi^PZSujdmF=q6o%i|1u9or7eU8t#9M9*+F1IL;Ub|0PxBTNSU!0D(Z#X#A6N71uY z)ddJx4+JDOjq98iQT@0J`YOwMUcQoQ7Rr#Ae+XGluOLo(TtlGL1Ts{i-1 zfT|(6l3>s4HEOl0Rykihv%HYp#PyV^@%4_72U~Y05(XPiyXpNxBrU%m&K+@7FL<}} z6en{hzoPOhX*>*8J#(%(ytut41-a*(f%-(}gYX7Rc%;`N^u+nbkME`6BX6Exb zf>&_9CMj=EA2<1ivhdneGAnbzbN%zd1(@A=?I-GNn?%yESDLT?vE;ExrdVZq!WAGd z$64~n589^u2U7{~HlGuZTmk6F3GjJoCo^>FK@7Ek<^Od z?}Tit5t#TkPu_@a-=N*kaui9AI(^uZyv5w6`>N;NDj2@*)vf0cDNW>QG%}D1&6LKb zZ^tH8ynZBpbx;YrmaHDbh z_)wY-hkxr11J&A~$p&y9I`{j0=S-cq$*)aF7?EPbZ!dF(;co}jLiXYNz4aMJn^%@@7;%We020iIuTHGNO3xZ5O~L2D?Rn_|W&K09eQ z@txr~xS?dH1(S8EiQjR5OmS+@Y?Oq~^L<9;vxN%hCpRdY5+}Ox*f68M0tojCR^gX3N_FAL!V)_V~Ke{$0(zx%6 zC&&zs_%<|EL;logmRU`SQDT6Zk@yu<&z$P$Drn{GemO2Hhvs<~1usMK8^tjmVt-r? zase8bmS`E02Trv&ak=jm?aMQtVU* zbq>K^XWG7lqXO~Ko=aJsj8zi%v!JtwO_VD)baf0+emKcyTG(3_rbf4-RIX}qCahqb%?lNdU@v1gg|E>pZl9i)k zT?NHeFWVj&w!Vyazbx1}v)6Cn#0jZDnN8t|&1se=03>ao@9w#tG{SC6TPJ(EIM3`q zorJWu?4gmlw9b-x<~hdq_5oFNr8)PKy42Nh_6O&-zFo}`c zP?%rF(A_4O06sO{#<3Sv*=`44RPtC-5|!Yy`^N86%s1PpgT;E2`w=o=AH*{D>bVNH z-#dVculw!u^U)&jYlt31RxThvK5Nr^e0prS@4cH}N?3in!Hz>#CQFMvLfgLi^yKBM zAKoX2Z^U*7#CB6}Xeh|%8RUt7-_&mLu4_LZumy_z@|c58^!NnjgE*Av^g;iAvm~>~b`^S+ zxn;d-IwX^N47pByPZ_d)|y9Y2(3m$Q`8tOZp$bEN|U{ z)H$O`Zp5uNb{Q)aXE_a~W+e%dE0XICMcO%Qri9@?7k#fd+cRcSM#-VI-Rp8eqObLY zTd?@Zxk`V1dvaVEk*)t#owUoERzs#7vUi9RpI?7}LKXbhT8}fS@25 zqtOT7I?X?U<(Ca?-11{a1E(QW0T?{ag}HNeq%(# zVs-mF8Qh!G$$-+5or9&7-5)DwrDjI##6{;HbEOnI(l+`0ab-t{{Em0?N;9`}DCn0o zzEb0)pwjTqCnX+mc;|69ED8P0?jSD5p|8}M3Z$;Z>}oNtxj6CtOa%n_ z5n~MRX<|dL?bl?3t&EwPb1xc|<|AyGa}FDkjgPP$UzN;G?1~=^b+@vZ-2Z4LvsVh+ z141#c;68rLj8SuvTTr9GpR6Q_S8Zu`{(yME(Oh({Jz2N2g09ZC={0F8Or8xdOI=WY zm10v%qYL`IwxAC0pcOf)VaT`MZEfA-6dZU0>jlw4xp|vZL678l2_HhZ8F;j&%#I zkkpD^CWV>OpD;J11w^~xT6gda;pyY?KsYqt-0HjSV_XqSN97f!c(k__JC{Q|BA&Zr z;y2xVvrhcGq7B^xKg-=0CQ28&plP)Uy`&i)%d{)M%dm7Q)^E7)A&G07k;K~65*W;J zyP0Mwc1KGVzT=dU(HJ7N2*hD~xSE%VlR~Ly@^g1~e+!(HiE(lW`}4279g+~ekQ|^6 z;ysM!2BmBU#BC$zEw2KILY*$6_ZMG0vh5ml%6J-ZvBbPjf2OHW96xgHyWWWf9eu4V zbSUY)z-*K0y%xw*O*|BZdIS=FOZ_zBSHty4cEA+s@^h@)wNlND1qD4-)^jGGRDE8^Jn~n{60q_gLcxdrW|%>cUrQ)e3DHZCJK?sIYpXzB`d;n* z8bW`PyqUNcI|vubMIoRGxUXnvELczG-mqoj_K3yYAnyocATo# zNZQ@Ld;h_)Kqhr0KGXh1r0GsPZQwq*r7mNw~$~>|EZ4!Ol>9ghE^M+81DObtqvR<)ro7 z<7!_-2!zr(vr+&({s5~ipTEA;lE?y%D}oLi*J90)bI1=dv6IF=Z=sH>zPNYHpTx!V z=#SJfNh#%AhVKuC$IMn(b|2)35`RWY92DT!DY?n)%ZUfrZ#!~jVauQk6`6#r%kA?B zv&dS5rNt*7-#1yMa0AJvYFC2i#5I!Hdch@-sQvki_=xW}UMx%Bb`%?!uwst)8@7WP zt8LzXUYBA zBUy_cyGj`gRc>X$0>m>QUgViicq}7mP@Xt;jQD9JHq%xd?#gfm`jWy@+3QsY?r<~3 z>+3f}wqRw=p7K|M!xQRt-f{!2$C0CFgdg&FiifvjV_20BNEVT9>wCL$?~ODQnJ?LX zBzuGct5GmoP{qD zI?W7gY}I;BZ`z2MTST4}(`@k%j-Hm+@a(>yaFL)V)Uhq*_VSp|q)v|ifGW75p+*ee zWCB4uChsMuQbm-Y!$MCEJQ(USLfm{hF}c)eY)SWP#WY(JZ!>Sf(#v2=Nis9dXTsm~ z7WU>|*hfXyh3z3BtlhV;9@aI(kIdO4@Qlwcg21mvI7uHgf8GB)I44)h_w*`d@`t-A&Tu8;X#@8+ z;oiqi*$UfUp8|&hHpFKv_^*^rHjz0C>sQwu$G(&E+`$8cJ*wtHo7o~E9uIeYG6;Mo zzBkKO^5dJJkyEp0UtsNuH||c*Gs*2VNLv8Z*^8EvJXrk1&mrgzjUs)mVN7#^+!){S za%Ym{LvpExqc&H%Si|-Tfs>k=1=Nh%=^0P6mcyE3IR}G-39_-3e*4Ov=%x{I{VG{2 z(`U&H_QOcFY$Ch4lFN=4uC)pN8nkDTw@iulzCzH&-0$mJ(u`(h^o_Cg;x+ zB=+n!oc;D=;^`_Dqe0_(38?i6t;C{_@-AgMDL#sacl07;u-g6FD_lc6;FW^ znFHifm*O`k74*R;=+Y4SJ3pHo#OK9Pss#=s?fmq7lYGW{G@yGPPhT4Ml{vsk-R9CP(_iQIGnoj3l}A z;@YiqB2%NOjFO!j!`Fb_7@#Ww>|p-arRD<_k5IkP@Xb2rA9ans2jDm zySu*Gs#NGRsMCF?S0@d3b8_K)B*Sa1oyaKCDx4rIJM4hDh?g(QszrRBB0UyKT6^(L zQD)I`REyC?e5?(XEi%4NEaU58h{ z7QMT!5r)go#35JP#IXDfc7g`N`?KxAv#yhAR&Xrt7vNE(Gm7fVE@+1NWv*Akjr-!w z!x;thwOvp-x#L3>@Zv>);z)H_A?iY=hnaH!K>ilkr2O_6(x;Hv0L~e5`|2HO${-d_ zkiIn&JiDMo4O~IFLZUwG6NEpv!LaO{G|zS4y0PS_5(#Hm`=YM2_(I`s)-u&3F#3-{ z^d^4o@zs;Y=@Lv66jIDA^R8TIw^kJ+oko*3;kN6 z6mF3#(#!u`P#o2?G@#}`CPLq8tx@)IwbCkrF8-@7~RfsF~W z-ew0sJdvkf>`sj&^Yd^E3Z-vg0D(Swj)_$?i!$Ol2k0{8-YMEo`rudhC|G@8ar zo1Q|AlVYO5f9``D0T#L0in_;*iJ?+}8+VR$(lmI&n4XZKE2aW$v#HZQcPabd4mDm} z0P&b?U6C`nh!lcBR3QH7u7k1)u##vQ&1}E+BL6{XM zi`2l){xN4@g)^_mcD631gdCeMVjqE^h*N=1P*@obtH~H?BBV!VKG62j>WBT}dJ}@T z;f;#1VzFso#J4C>jV!X4I21*=n?Bx|>gKfhu3>Q!8>NMTF$-g(+q$P#h-*b0^_4*& zU$)>P4?NjtSpE;FSUy>~2mYzmYPD4|wK&TaXB#?PjB&HMQ_1?~W z$OoB58*~yBrX_cINc{h?_ntvfHC^AY3P=tElH<&PC?ZjEh5-f<5Cj3qSx|D$8HPN7 zl7qrXR5B_^kRT3OKqQFdoMC_=^X|E>>kiL*>eTsqK0H+xHP!Y`y?d|jUj1Lcl_wjp zJ=H1={W?!&FKM&>DE)Ppe<>&E{!qmx3k0aPuxBF|~*$><&(oZD^1(JJ0T5R?PT-iYWna-s0Fidd8 z_J-wWLj>w}W9F?N{JucA;$;7m%G9kJcm3mfjhAmss$@9~&#Drh)m1Kl{%m^p2_J>` zx)!WOpSE-2OOU#VBTHri<#>2mz>e68Jeg4V?rX)#-)`&OCs<^VM3pt0*^`KaKiHPV z;lLmSi`gJO97ecSbG4v7`f87#otf9bVtT&8qGCYIkrDH&t3|n8LoA1hE@4-q>pbYs zD0jpq%D6)L60(`?_snP6oX+x=GQ9R$=+9M@I;FqSnPTFd?3*^29Cv}#-LsumElT&% zs=0+5N=J06oT=4T@132$-ndC;TKz#;LD4T{j7GFDaNGRtfShdhxr(*9&krcNaFA@< zY#jWToDl?27{5K7#Xp-YOH@Cv0$-sY4k)^k_Df+6 zoYJtU9IG{X3Q>hVhE0Q(qQ(KyREsLLz6oPwoHgqS#u;3;8?Dg#c{9^e-_+HZst>`+ z$uW;8(Tu<&1U2Dy?zp7^;)Kh$B~_#Jt=~7hANiRTcv7CG_bSYgrs+1rZl-p5@6Ask zW4%2Uvr6pfXpkxy7x^(l%0gh3G)Xa?N6-gu?&$=so^h&7Y)fn2*xhEm7i0T(T4}?> zWvVC47!)Qx@A;JzrT;+OxP0;qoDg9tr+YNcMO{^_x~-3RnJN|%=sdBLMx>xq0M(dy zL9a&hZu54elznDCmdJ3*ZLGpEkVS;}Y^}y8^o~)NDgVsb8Ko9IrT!7KDykmyvsF9G zyx`3QHv?#5<+6#$p6(gP8R%86%xl4miSZE$Oit73^jzso4 zAG{~la;hqKTluAW-hD|jsU)>Z58^s}kdi?_9epxAV#9^Xq*Oe3-)rn6@M-8fDqVI8 z+L&CmsU6t8bVc8#kSkf=eu4^6eH^7MCw~y$7`&26?Q{^B3ToeU4W6LABCW~1V+(mP z!JezEgm&&a^uK5&O-X4U?tTnneI+vSeJM2Bm==;%I;eEn#NxWjXAw$n1V*yuuP%R! zOOMd~$s23IZVACYd1tR{dzo)t!O@Q$X)%c6#UsM}wEDH_3+~Bl9-i0_+3RfSf5~1Y z+dfS{Qe`Ge7)P|d`+?&4(dWI>R6x`%+$`s7`{aoiKyVShdAR{(Ne!Mhc=New({nN7Px4JO=N7att5{o`lZ`USJ(rk#d#ehPthj&+kYOhCwGS=RzCYs zGuY6p=&);-!|g8NPDx5Hx-0QI@&@+Ll>_{fM%JY+xIc^;czM{~%BU}ZsfmxQZPMHj zE5l+7g!qNI#l-sJK8XEBuT-{vCzU3V1k~mQ1!I8dHU$udOA0R$Pb7v{s@qz644{mEr} zuH;AJ{Uo?9j0OAK{=1jL=bAx}yqx3SkzZ_}g1~Y>JJ#aE-AD<9*pKW&>WVe;mn^a2 z9P0x|7clP`N2x0}*81I!yUCp7+lb*EOsX3DtG)-M9MDB{mRIK$Syt^qFfi9ibRO6BdIoSr0MKZZ&^v z65Ow*kViG)*XuYqZo$`#xaPQe)?dTFPS2*NS;t2<;FjDd2~KD-51z~tDUU{|N7x)X z=moNG`2STcX78NACrr)Uyv%&;7{Y~Sp+1T*oVK7 z;fPv?fdpkTXa7l0$UVkdlteK*vX6#a0~7fAOXNlN#;0^w{D{VACTYlavaO}V3sJ&mU^rYoBbkvX&3um_5P8R zS!8o-Oo|=5ZNz~R+qd3vi#EJrs_XGnRy*rAWq+9uw_#OnrBxM~icqR60Xm$O(&s@I z(*`H)a>0fsJ=F>~$q=SnY!#gQg=Gk}=qW+nw38CMV(v4rGPiFfKT_v41 z?f>zX^H+)TRJt97cR4zWwc5#SEeSr)eR;DrK6mj zmHYG08MhBt7j_~Z(G{OakNx^2ID5sdaj3gH=8J!3mrq%HHSMZmu4*md&k1cQr3uSZ zR#OVl*3phUfLC@Th{>_iZ5q$s9We~(h#$l#Kf{>ih(XeuJJjqMgHg9(H`rQYo++&@Ehlc4hcBOfbeAB*>#x><;`z}fjlDT8$wKlXk zuR>ey6ByA5bhTo2r^bwbi}AX|Ku~fRG9rEB69agDBGPuRch&6nM01`+*n6gxyg>7e zRs-Y```8@D0y(H1aQSifJ+ZQ(2jEDMEI9lE_)$}E7Nqpk=u;5ULw%X&)BA$=b`m?TDR$7j4 z901jlQhKb(iop7ZolwhJfM#$ljSZy!aK1&WX~omvB_aEdeo2q#v|StQe4oa@GqV96 zoz6lsu_GCjYUG{eXKWK1i#(+spvcW{7n!~5Y%S5-c`{Owk(BTjdKtHj<`BvwSGPng zB`FyK6}0yHx&;eOb*#A}RnVG!z2WNDuo%0%CJ1V?$&njrEb6 zVQvrr_cvHGnK#vjgs)wD%Eh(sWMF~T?8H574g^-cwHnbGfS;V}C_iRbbS6o>zH z%v8&c_6~c%u@Zu4CvY1KR&3&pe6Y5dAH0`}Y|q>zgDnU-JB|d6{Lsb6P2s5vPE=1I zp_+VmwWMrjI1VgQ{W#1FpYI`yqq#>V4Y}c!k4UZ%Q(G;q*iSPT)^h$lSkV?$Ok^`9 z`Jl6d#Q8w28p#Vt#YB>yOnNr`*^PWJqk6Jpp#ihK=NI~B7ZBcO9R1=uGzqOm;kOQ6 zmdbY#AEnw&?Mop2ssNJn5zMl7JX|8-<&8~8nQ7=Y<$*+Iq?okW-cyk^BV1eeH=^gV5hK0j)O;}^V2j-o+~*H=dT}cJ-MzO3 zYb_{#f@%(!@}jgqjpIRehqSf)fO&qxMlu%r)`{hF1@N^8ppk-a`+sH*-p|Xfw&Fg^ zJCJ%NX7=;R2M4|E#W$PP+h^buN+c^(jL6eg~MKJtYuRW4jr-K+GI z=9QH^iD-VR;!u2Kcsav`!q5!O01;*>xG?RzG9SER<=t==sJL=r8gQuNg7DMnaC4Zp z62-sgFtPG)fb6?dm>tR#veGc#I8LHZD$h5Y^|^m{L4ouyB{~sQXYr;RXO7hU(X(fj z#f(8epRmq&+VKOtfx^)Pj}q9e8P^pIm?{2eqfDULOohqEeR$Q}T-@n7z}j-2@xk#s(BcITfK8IV+udmI2sy{U)4IW720 z@_P~Qb%%i2+Kz(8(^KIC3o`o@a~deS^=crX|KWBF+u@^50io*powi2Pa8E^R&J-d+ z*RHiQ0_}uXzRL|s#t#D4Yd%$wwspN_gVPS5nC|Gfm4A2^VU*gHy$YY~XelC+UE~>Z zVx9c7FNFQ%C=;7$l_Jdb?jV}4OzqE?3U!|XQ&7SIv8N^b?kKVSW#Ilh)dkRN)mvOk z4|Z>j8Oz!9ym#4>V6%z71MZ~g#)j+|sxO|Zut_AKZ1U&q`7A&E{^&_HIyBt_%*uCoC|UQ+wdUIx~2t$db=lnVDni~GV+V!UP^k#j( z4Cr_KYf;Cn==TI?jlA)Y-=x&T2V6rFFy|vz!&q3;ZkUpik?$6rnTyaLVX8%C)Y!8n zU(3EHvS;*_)DpQu^0D_&fvb&EIZo+jdvJt{^U}~ng0y0A*Q4NV6Tg&YmhMkq+^yx7 zYHkhlA~*^zxBX2iEa@9!khY*}gct&UrJ1#Tx7{SGj=V)wlI!SPe{lSNV(<6gtP3xor2;KbIL20XHAV!0RQ-)L=zyWqQ%6nig2Da_;rIK5% zx6E4t7d})zC9yy9RTUT3l3V!w_z1vjYD+(&z-WQLH>$c1jc>TyV5xmvGrJ z?FHG+(xV@}({@cpz~E*eMYtKTV^V=rNl(@~q!V$b13M;eXR=QB0jH@^Qkjemj==M% zs_gOK!EHB)Ug-jOy(o&SQKvoK3G_{!NBU@eSuG%rR9Wd_=NAL+hVEkfle+dycOpTpj2 z-!4@LefKm8gM@=BQ02EZ94g}I3sz0{FT7ek=ip`f!#3XT3i1!0sV6;v5$W(1?9(KP zLN5evgrPs0NK2*>{rZW=c+jq%?>D(H6UGAG;@_8&M9QE7Znq~AX`^&K>7&u79VP-* z-gnkA8o1p;y*Lu27FLPix+ z?AfmxXr$XIR1iKsj@#Nu0mTZps!w-@4@R!bMK#-cuT9Is9HYemJYRK;0eCX^=V+Yq zrl{kj07B*Tqc29~-Zuir+dTWUNk44Zt=6N7xD^BVllW}suGM(NtKNXflSop1#tD>F zQ?peg&%hHv}yr;cX#^bWxki4Hx3Zf)E9mcEqej$*{ z0jH@Y`=0`MQ`Tj8&39cN)(LNMhoz5E38JckHnu`dvBba1^irv4)fVq6zTPn8l)sSt zeBj)?7NuYcl?273Sc~`>?NC|l$A<`xdeO-$?QyJ>^^M(EhxC5W%;^-6qURd)Po$x! zm)x{xiF`;<9I&^clSy>MB+F-Lu8=!En610*e>BC1Qnq{4GH(?{w9=hw=hqeH83u=> zcxK3zZ*KLO?vzW7U-{P*+g={0Dp)97zq`#S<>{bLY4r*KvIYdaQ+Y7*ee-_*JgCcr zQ@~#CLVi)abZ)L@a5~ontx?mWbwo*>7&ORE&>V@qFO>3X_XHYN*f`_SD?B$LeqLqr ze&J(wqLPGai3NHN1tAW2~d-=YWBjy_$j90j5K-}>PDH!5rh~8_qqw%S{5(7jv zGZyF@#cig1mU)h(jhjD2iQKy;2Mf6;Dr6)hp1Tjnk1U7E$_a4)uuc5cBKM#@OR!6J zCteLEk$G3#Iii?(r8exF=~jRyu=KSvc+hEib5X>~=JOzZA%$c3^^N8G=-}`I4;wY@os=q;4EjUzShP%w8WZM0c9k*T5%qH(XQ| zpsdaLq3D*h`PTemF5lfpr>>%3sB7LyYJ@uRoVDbk4<1e@u1+6Z$A)*Ous9Ri019Lq z2nzY4ln|>L%ket>v|%dsLNVPh);!T6i2N*KSig>*O+a0yU8b z2KL_|Jq>ZadG?$oS}4G{J;&c&=6(D0=p|ENk9g$0z*POpchiZ|nm?oMLQiYG#YW>! z&EFOqsN_6xrjrAJBXQ>vMor@JC$XkC0}ZNmBEPoke0vBE6LK)KkYnUlr}JlSp7tF) z+JDU6MY<4rTEteD;5YK|hu0M&YhC80#UsIia(%l&$6$(ckvzxC{_Lwa0h2U&Gw03~ z$5Pr0eXIv+w;I&c;sV}lJ1;YI8D54TEsjR-tq%T*^@Y@%yi#IMZI_hByEm>g+GJ-H zGb8L=A^)i6M<@Y-3)(+VKhSo6EEK>=lG5>!ScUmxHs1>!HRTcMcTrvp9QVoP!gUYw=E@K9@np(dWj?R(mXV7~6pgYouzVFUTR(RGPd7pBBxqs@%7=feNa<(WeNO_?f zA*2Xk`>|5qr)qi|BeWuTR3c^-A#_X@DMql@ggMDQow&tQlXV3k5N;+;Qv;#I|6vxy z;4~I!rzD#~E|k^82M66oKs;NVUDES6!sbrAyjrA(#nPH5=nl_yI?8zLg-#4a<@}aM zRWyb|>Lue5H~(tjKg=j3Bk)-Z7qaUDwAj#n9MJEw&r=onU4skG{}`a>_b;}?6JSFE zIWRx)Wb`liMlY};vNMeSR?_G@6xhIKvaanLK}qLAm6^fx+TiP5oXNm3I`DAS(=>-TZsiU}O6>+JNA2oOb$ zV^@Se0$?Dy_A&*h0Q%t-J#g?o`Vgm=}USxA+&w&g4n=R5C0^A6ryk7Di4p`GFs~7jzaZhl^ zISiJV0>|P0A!UG;t1Yh7eF7YOKn;K(__baG^p2_{pkn2P>|^p_CE!M6So9wD0VUs? z!bhe50$}_PZ0pQj;u1)firf~p0S>W^&V|Hb(Z9oOm z|BEZrgT%dncDkB!;_F9K+b7c9V8I&q}PDZd8|TggaGrzlZ?fYXUEmz*ky`Zsrlg7ESXTfzCKQEx=?;VCe;`yih}7QJZ&dvwMM-;^ zila0fxI3n54f1#Ar3N}7-}MJ3{{}r);gB^wsil+>aJ%NjkEmb>KMR>gY z@|0Yi8@Q;)u&&|X7cGZYJs*0>EW2-SRP#J#wA5rq%cP}o-lUihvo@BnkO56-||y~SEi*+1NbQfj*%sPSTqSV1Au9?PYC~i z0fqtiAPEW5m%}@Fj@wf+(vpojJyNHCy$<9LTXpyJiTOx%$FYy>9&IieY=&{OnI~-W&bDzTAIETMj8ioH@X2X(yDA&*BHO77pk>>A~sO zCaU$i|9MtwgO-5I``wv4?cGXQw+=t^uv`FGny&$|RgoBX$ANtHfOqFQ<)55H%D(a%fu4*+@Yvbb^Bi$3#>CeVC;zhs0kt`UK4wA(kjapOQ= zP?A+SKx-N=cX%=hbnjx;Qj&jH1`fG%9jH$&Kf?9*69Ru@fMEUHjEbj9${d2YS3fdZ z?OYP!vH8V-{1J|E=J8mU@!yq!AMbD@!QU8we@y5A?#ZUUIAjxX;`l>CXEKQ&0R5j; zWtoOO(64g6P&@zx_3z5S-#7R`ef4V^>A=_a_diY?q{y=I898leC-7-#KGOf*@)j^U zJC-5>tU%=v1#O#uR|bB(0zhgW_QdOc|1<(ss5mefCA#mFIYN++fN!sR6D$7lnWAK3 zbD8KnTx(Azm&yODGR|23KfXXD18`W(nuCZgJ~hrx3!1Q=MLqlr;`P-7cTa@Mum1w5 z{nHeWp8@sXag}WRGmgmP&*NxM1I^_hW8{T!cBOV^VcY?DH%DcYue^ZD_Nrw!{#_Yp zjsIe0{j*zP3D_X+qVmzlAUGM&@SPr>o6J0af0iS-L5%g5-hbiw5c2lGWzy5$Q~)5m z|LqL_+Zq11GyJb*_{Wm`|Hm>+cwP*@Q{Ngh3$C}z^X)2nlvz`=uUG!G9)~G?_VK0t z*6&ZB?tdI_2jH!B`xoMuDXFPetyh;{E&zV<$F-vDXF%W(iQ{sCa@9{) z)TsmbOk25&gVg?9sWBWZ7eL7<4Ds={8^$*aT6K+o*=b?!nrtIve+e*|d3Jk%h^2|& z&aI9B*;Tk=0Y~`7;ij`h9UXo)%}>*(Wwv@qg*kFhufc7JdQ6$V3pdP4pXq&|4&?*} zK25is@8w&-jB{P9z9=3y(+3&Q-ur7+^4ClP@)!r_`_}&YkQ?fR4DgJH zakoEj3nKucMWkPhSH0b8#!i16(Uki3?5ICqZU)G7Lb@^2+REyN2LF1ep00S7?k;z> zDeS*hKNj|0*%(}yJlTW=-Yh|~=WHn9B(TrqxOVFqfP}6|l08NLG7Ap;?LH{;LAy{T z@>gx0^N+mZJUF%?0~*!|h$wYrFiJNI@}+7ZNHFP| z8PNjN4EH>CrvGS4ZPfvDz!Goc8ta$@76~EVRRgz~~*}aS&?@ApqXHgZCd#eMHEgKlDKAOMAix281=;jJ+GK>?fv`IXTpWyODS4d4 zaOW{VLPogM2q{>eSGHdIA>c9xKa}EVGoKmwllZf``T%6{-{aL*3I1C^i$>-?+Z;=d zBC_YaqtooYGaZ$~IV^o82;jl}=VQ2Eo*t}$nbOhjU3YBa+2v#pj5tLNuOSDX|33GO z*_Z)!3fOKwE!Fu3e2H>W`)KGDsD2>BXZ3A#`+S07t!<=W&~m070MD*Pn(xlGfqSy< zcrVk@8K5>0bUFdpKi(e)WzX(*MbwAOSCK%)}P^2?MV zNDrV*)!47^*|$b`1f1&JzpDfk*bwO}|9goAO!;o%fSAeJ-{w2v@EM?2ftje+;Ekpf z(*PtOr+Kf78C)+k{2XXevYq6bEZrHHK9m?_0Mk#MWcJml6CfO>vR7U=M$P9)xQ9*I zk5!l;zUBe0eE5q5b50xau#~!9)R)_bB7`?KH!52{0$p~3@5?52r~WJ1oEKE~KO+%N zi*#!r)rR6=v5U707?RadTbmQLN}WPC;&lg61-F&?!%lknTghyaFEc;>FzxB#PlbXt zZgH(e&HZ|#5dPTg^UyEu`~V@?L+tu!FO!%P%R2GBW8{tOpTCa+$_Nle8;mdUO3z1T6@yuIrx1U9lPnH` ziuoBeB>0_$W|DqA1g*q4L0UX3EDjt z=Ny)5v&-24d?}R&aILyi<-XEjjAtL7d?LD#;tntdSw8ECf;zPUUX|?fspF?V zqVa*B_q@Bv7eaJ@!2+LX<>BRlw+ZYf+uCZo&ZNsrw`LhdJ*&`%`qII*2E{Lfj|TAME6S!8Wl37#Sr1q0s zV>w#!i*Z~tnZJ312gOgCprVt|PXVsMf;$bWt4V~OKJf6VWTOEKvH)9xd<|Lo3up~s zRiN3=$RFWb;?TYyOOvL)a-pE)>(&2@PK#TRApgqe60>x4f`-Ca6q&#W z4TFJB&a@AL3pvbgC@9r)s(U}Vehye@-_W>gBs_Y_NkFjdt`2c#^bf`N)pa8N_uZWy zH^j0itwZWdQOd{yQ)-tRT_v8pIN5y6@lX+2~S(iec ztZ;E;C@@Hr&|8|F^yoJoSl)F>Q?dx%*(ii=O{%HtZ=laL_QFN zoEn(2R1-oMW#$v`8XijLM3*Qx4T5 zoW3u^3jP})!22pZVz2w&7GTFFOpl1hl+-M(+^cLFRyP?4C+N#y-pmXPqp3n@vzc;G zN)uh9pQPZt<5dP(bra0Ygj|{df_4`4IWuz1m zAVgo(kC|@lT+hJ&PNO9~r+;%5$WhVS+HJ#uS|fc+uGOVf5hFr1_MY==2RGVtTkRC( zxJ--5Ae2YbV6S6x{IApX-JOI4Ez{O+J5EngguNp|lHj^U3|V zYl^dbvMV}6F=&NLFf7?{lU@A_5yz3W3Pp9aaC=;MnN}LLN>BBmKnjCk%t1kH3Z^6n z_L5+<9ANS=ArIivY!A&Tv||#cl%~LXpl?7}-+`~{ zds846is>@=xQq?4nHBM%T0oAfxs&MLyw7&Sigd6WDb3|_5jERTcfj1-O&;$|_dc!x zCF%BPo@dK+FMY*t40WG>#tcXW+VEa{C2P^`5lZi-EXa0n-X@qt4VG87Os-@K3SyIU zr+}PoNtUSfKi)H2jF`tnl$1Yi>b&+Pu{sSAJU3UZh@ni2Pj3iWTw=3m5uoc*33geD zYfzl(`&LG2KxM>%YWO5hU)0%tZo}ugE70Q{gkk1yjd|^w!arcaCNKl~wQFAC%J2R) z*Of-jJ#LT;#kU7>NybdkpOYowmJV_Z?HLWK3^WT+LU@2Ie@1299xx|5!)CtF)#@M< z-K^K-1N9TxM~Jvb5NevMe-o+hNNXTdwOkfXz66a(ceYJ&-khAT-8osw$FhV;x5fF# z`>z8zim#enxK$+!aG4M$PexZ^9Em_bT*x?lo@l5jndLiLGK_QV^vjRt{Nt^{d7|WV z0V_O4Y&2kci)d};V%xi=kr718`!3!?`74J!NG#pduasUGA!|(@#v~C>rfdwcM*5@q zIN8F8L2C6-YGOlr^dlIZ;w?k9{8AEod_En@(g@hRl-?`d7zoQ+x);c#GiXSe-uG?9 zkD@GEiwKl5TF4Ziw&wo0(&>ILzZgtp?5Q`tVipFJ%1fI7Ti%hJeCxoVLiD*ZaO=gT zXD7rJ`kBF*V}q&|?vMJDX_vQ_30VjIM(}msuA$7-G}HYmBs;J25p2XLHu?b}50kDz z3Q|*sF=Y1E!yhj~szFklt2Cg2hQ;vnBR2?Ln<~pDxE~K60o#Wg>$Xt~Q(ogZn;Q(h z_O2!^@N)xO6kxeE*%$E)2S5kkq~-D1;c)1&;bpEURRv3@;#rd1<>&Mi>8X%T>jB6w zi6lXYg+z%)YYXR!gs-OKloz9>@1o#L#v9I zZSoEIdXpz2q`%xZtY=LX)X8U?aQ=|y9WoRY%hlCGRcu+&4EQ8gqIRT~TuE2Hd zjq?UdM9f)?G&G@`*im@Jf=L%X!iHtY*Xw-Px;v+kA+`OvV@7KV8{i~pmO0aw^TwpY z?sB)G&5jKd<{vLHhzEHuwD-X|uvgCdnm_9hz?f&4=nkg#CIv6epn62ewL1AQDVFvt`_xmA@qeqivL3YCX_!15`ZD<*Tzrvrm|!SO8ugH>J4{~r4w%aD2E*Ox zO+dO+G#5vr#7U(GwA&*2=uh2>n}m?$K#$UCWz%;+uHGP2V+!7h5|^zD6`qy+<`DmW z0uQ{*3)CJT^TMxz$J|=fAByoeiFn`$F;BL?P6}geh5n(M?F>V!ra)S$hI!2rzp9`h zEXkR?GKtTv8kT2gFM#008M9~xrHqzw- zDT5vH(CvJz^>S3d1)7x_$+z$(g|!H6x=lZzr3}X)2`w4H8X^zK483yvBO27-cejf$ zsPEygVy zdehYv(CaxCB74&n1rQsHIUgbQSpMv#0$EenxoQ@`Q(zPml0XhFrpy>dW$#Q;>Y52t zxB-$jk$E+`*+qPCf3tEhk^ST{hEzp5J~V#$EwkG|IJ@-c-NVY@W)-l;xwMDU%PPeT zOs2wBr)r)-UTy=LWf-YDn?tMT>U%AR_+Z&gZ{9E8$+cF0r z3CzFuf;jYmLrST8w=j6%i{CSsztlO)UX*&k@DteOrsG6l>=2sk5kHj4Ahs>1qm`%Y zUDgwX#Taig2vUA}Xk76nosS;3qOHADf>YE&_ zD+2KfcUXAi*g`|IPddcdshUsp7$u-rkGNYVycW0a*r{7aJB)bbqpk3eK!|WYG2dRQ zrD1e4E}eCJi1JPAYj?q?6Nd3+;vi zt7i-6`+T00S7f5-lfsAAWQIn#PRtkI#mYa=ZIJOM7IaRH4lha-@IW#vF((hKM^52)}Ry>uOIZ2dDihaIKT(&b8 zx)>?f#m@2#WKf*+Gl5)Ql7;i`9)4QsKNM2c-rXo?k>tLvM1KomdToVC3PRnJ%iB`^gnm^afs#(l zFkHg@Bkqs6a7@lAb)G8-kBJ z*iXII;xKEJY7Dw-5Le(F)oAMF&R$=%p{c5D&CEgQ5mKc9N|0QOR&`5=FKTDXga_z; zqhZG&7?NkDtwVX2~2LSZRxiAR`5*`e4z#v?-h|9FTxB> z|H)uFjWI!xK$7q05JCn-I`l@2|(oZvs>O?|e(itbicG`bl}{yVPsJ zcO1I6J*f4J{zo6gX`IN50TiO@OqPWd*NF|QYTm)It-HjwtL}I+D+tV(QPN8Hl zia#qn9?1&udoWJ7TVQn&zAfk-ke%++%X#|NUH?HyE6A}fZdGYsyFr6M%q@ll-pMVL z(DTrmp;BLFm5_CuLYP{ge@Rov=ywJt4wNtBP9iZap&@q_^e8)8G=s zM35LpaJ#?WNIoO7^l{^(G;!f`qpNO_1NXCp^Sg&j^w#{;O>yVcrxzw<;KpS7Y8~?P zGB5|WXGRnHd<8_e8=;S|34zB+IHPaICIsfsNm{fCa&xZYmBRu~6pL;dO%d#1@TEI{ zT&8Mh!18s1ZSQ45>5|zfa(6`2F2_x)Lb+u;3?xHe8m=&nzMIc4eNB-}Kw-1iS;Xo# zc8VSCw9M{KVc*}dh|kzh@6NVuoHTA{=nNCX+@=~1px8yW5o@}2P`3og3Kmn1cXpZn za+$NBWHXhw#DoByZvTDk_8>57_J2^h{SP0wPt|z}DCsR#`H7QQF<&do`fp9ge`aC8 z>OWi&0r5^2K#O*AwI`O@;?t{d=*T2&7V^+$c87jd0CsJVVhAu#OsS5{B2p>f9bXN( zee_F3PB7{un`ojxs0Z-?pQ(mqD8X7$HyD#WGi8*^L^M8YJgF+{F6*`dc!x1F$@OA0 z0kxGG@5(?!Q4C7!V9(?s^pnNgIvFylAVauG+DjE_km`Q2CYaoAkwu5>t!l79q;PKr zCDQ}6dcAz3u6fVXAJ3uZg|t4Ws@Dl_!O>`W>-}9DZTvFZBb6B z1eY9q8t?vuNxh;ZnvkU=rRe@5?|zdA{?4;`Gcn@%M~-BEWHuAIB34-L5?Y(E)w zpOSGm@+DVgpGl|a4rccTB$vm&Q+#1I^cqT7P{=v+Nfnq~`tjGCN{z?|SYkoGwXH(m45qv4Lj*{AXHcqp+pN{OCnTH z+e0yPJuE14w@A(v41r;Sxh?y1*>dqDO!r;)u%NlGGAc#^A0OYRpdWzp2Z)-u_XDX| zw;7jjSuLAdxBL*5;Iic@>LzGd5>9mOF!P5KdfObds>4;~zB9f3NAV`a_Gj-QTvhB7 zlOYpMHv}rm`nQq{P?wb8bVibez1^hANCZl_En zach3#N?~f~y8dL~oeWB{JzgfjS3IPNgA3$=w&;o^vx%{?4*0=srA$4{KKdp{Js2Uy zW5D?22m21#%W!~Y=sWeAE`nOPon@`3gBY#ed7t*jt}25N|7u(lv^BXE4lApRiIY%T z5~QTzz)Ox8W$mM}hD?X{+!D53zV41^3in#3r>)nWf@DY}NwiHB>SUaBg^n*t zqxg*(>3b!F)9vpWY-hV?MiV{$yeDi)e~Au)`TV#Y2o^T9&5{Q9&vo})C-PmU&+%Qo zuBIiz=bmzMGj)~-^#F^vP&mn`f_OGL@9$FCmfzgjO+&j|r+%5dr>jrsULnb-5geZ@ z?jt|TJaZgn_f`CP^b8|&@4*OLwVNzukqgIGw-_NN(in5?x_kWP=ao#c&c49*7Y7~Z zVAHZ!ph>v9Y;cBF-@RoL_q4N+Bj0iG^Eioz%u`PUqCkDgdqgi})n^ATx^fnUq2rag z(Ram<$vB)ldyQ>a+AelLov_V#!G=l>QOmcK6)P+Q8nQ{)loe1bVW7}<*~-m;uuJ$MyZIL|r$iN%L$M<=Enbh;ToiWVf3^Tqa|HvC3UGk_qQ8#ifeW z3t1h@0n~%JwWUvHGdaJqYXU-K&We`*EC=QB%WxBUR@&w?ryE3I9@EmBnsmc!+p1gt zlI;GYZJz|Z5NKQ?zn6CM7sa?8`bKzJE*z%<^zaiA|Ic1Lni1E5Qp<8EbQL9wM~Y|v zQmg+0?#wDTh};w(0whY5OtDW`dIOYXdXY>1y&xSq`R|z>IiS941ecWcm*E4BhKYW* zFPp8BUYq01XFE@2^jrVgrPAfPl-f^>I>C`d>nT}pQy^1uNJrMo$#*zTO)69zLt>p?B&2XND0O2MuS-k`S5 z0Mmse=RZPeq9|DMkPrl|WY2s_{?A8@p^r${Tw(bGSh2W(hRu}HYNt4ohaIk1TG?|` zS8qv=#zmNbT5oCoe%u#MBzt}jR%}cOak-c{mr=;PyIEh0D_OAq!DUCqzP3@q3F=Io zU|9qc+HY7h9q!!=z_L6~z0wm5rcE50H}W5i;1_T*g9+%-NNA7a`JgQC2b+Pu9&wWvDr)w8oJ znUBXct3c7eR9<@1`4I`#T_Z15Z)BC{c)5-{-{1)%f}|ZD*bXZ_*~;lec?~4VB{bNK zSuRT8`9Ljan^M_JFNK04oQoXmf0p6j>o)dV;DbBkneGz?2 zOon@~u&{O+(v}!f@Va>wl}0uP8J5Rtl!iWvM5p$^!-l_Vwv=h4-%@U6cBW5fBld6t zdlHivytY7Bc%u)ZZ>Tq;;K~rtLjlgA{8u+IA%ScRac@2@ENZz>QQ`=Q?N&xQ?Rqf_3e$UL6I#XZ5m5QSpqGAa<1y&kar1epnfL8&q<7a-^Cr9S;G^6qS|tL;O&1OjN+No7I#~tIzT%oxZAmb?z+f z{`##uEp~YFQ(P2(tuKo7X75*VzxSZMJ;aWAXkk0}2GY3exkQ0C!K5GP%Dw%stthlV zMj>NZSs^!bu6ddGQC#K;W0s91oVqQyjQcV|G~t!z6V;&M`W@m&IzFI<+VDt;v3>wC z*RD1XsDcki^bFL*7I3+#=^0O0Q}Tp3xkSU0OzmM)N(4ji*skSTE?rtnjn6FagUagH zgHf3|{8*%51EXTAS3%4G_5$jj%$K@z3^A^U50F}*I3>sRKSJ|(jfd&EJ<}X^a^UFb zs3IXJ~A4q>f*68GZG2d6c`vRCAg}3 zoQM^>*^0%$bUK9m>Ov9Ra}xjAjFOI|Oq()&W!BNIEdS0O(*y5 zTr8Bh&(WN{w&B{yLc|dLW~nNrxpy>{E@iYiw#0vX>ZkM@R8K0W+34dM9s5Vu8rYA- zsnS)84Yb7WS$gKjtd1ihIa{vB^X$w%s7q(%2u>E zXCyBV9QC0YcXLl*#d-?pi97(PF99&Zo$2)KddPe|sd#yx0=l93IrD)1kBFe&jvj*I z=4zEl#XMzWxio}{d51&)O<&x6*1O5a1{vp5K~cYymDP^rG%ZrEwCf*wXa#rNnsYl? zt^XKMF!d~`a5er&6?ub6fF@VSk7*M}A=F@-~bT5mh$ZqAEDF|uIeln%J~LG< zI#!={&tE*>7PuZ6ctdd8>_U^h!<{ALdqj_7TvKqkXK;ymcO90H(=S`g<_4;ClY=l( zB`|uEp8>k1ha@mzk%0EuHsTeh)nO(0MEdB>@lbHsa$TlJ%LIp%ba+$;4g+Km^h7N| z8yioXjGnJ={+{;arRZoB2t(Jxl~E0CuK>xM3>8NcM}x_8S#{GCIBaM;1H_rh5C6Ml z#1ABG%K+~3lfiC?sJQ)VUq8JBF)}cBmTdT$(@Gnb^Yq*!RWJX*t}`2>!PaFT^V`Z3 zY<|TqdyRTN8n_+?kY0S{ogCIl)FPg55HPn zk6|LK*blRLfqZx@@FDSzfY-oI1{!VZjsVsr=0j$*SKufi34dX9?`BWTCCZnO2T}4a zMeeUq!9qi;h{e7r9}aC z=mZmyT@j7}A57`Zu06NsK7t*P_Yo~m_q&V%WbD{+mCG%@0`Pzf4Z!wcrQpdC!~ieucM5DkU%A@bmNY-S*Mu@ z3t9=}p7KibFdTy+)F)Dj+(82?Kq3BK=MZ(kXWI%{F#K8t% z_6Af*x5)*jKQDy@>JKK^amUCOcpSeMI`{){Pg~O>hhonn3$S6EOt0{2B&MoqVTm>& zC1iJ4?k0ZdRiOAJmG0o1hXDp0GX|Lgx^rR=uXxtD{b6z&>oiRk4yL1P^h}H~5 z6=t~br&Boe4G$B%mtHodP1%}%Cgh<;Ua*R=a^8rsLhidU3nML9OINh)>R7Jj9u3uf zToPsiUbc=WSZC3P*%#?=jSP{1RKw-3rJP=Gsho0E2)Ztyf>} z{i{|9?>viX-v9layv&>WDl8=ub-g7*`7^gs&>?zE;rYa3R*G1*1dmz8phGg$Q2h0Q z|CRy3mBhIQAfV{OI6#8-+yen4WhVz;zv7vlc5Y>?V!ka2Fx&QbUu75$@2wX%UKc9| z71G@m6nYH3vVI7Y*MrxvT~{09fQX@2o@IYbhJt2^;XdWR)_~j|Y}R?R)ms&RMl4v5 zH}tTqP6M9THqdTd&TmyX%Q@C2eP|kD%L^wbtXFCSvjsG`;lzuKuEe{+4uu-?wdn@DW~n8k6}5W$a4D4}7Pzm+cnjujLkG?uOtdQhqFz3sH*X1spW=;XphAj%w+FPnTdT!#ERMD zCL00&MZD8gjQL5;1=xfw}pei4{cjz;hh`hzMyZP2E&Kmr^8@s z_6gZOX1(8Y22lr`n^{6i1ScE1g_31TBN+Jf%VQYyCc`r=huEcoN_+hLoj*oXbSsy9 zWFmb96(QSCP{Sib1$2(RPF}7XTB@;8Bb~o{Bv=yKlys_ozZtU-QnIQcn7{=udKP5^HVW=pV9xW_w znGWfS0Eg6bdpre&f!FlsWKm`SBPpp%3Hu3oQLAi%(|?ELVF4X)Vx+gc{%Eb>W6UZC zb>DnW>CgI{38GSM{73R3wvTl>Lq~P2hx9`v#%EFE{HQ%gLxvX;y>@M-Q*I z>!p4t<7T3&0m_LE^|R#K7#TzV3BSG$%)6g+iC<8RLcX4NFE* z;Hq1vQB~Tf_~NLk75h}OS~b;q;k%>VF;l?auEJu(vc{ooMae>(`O4wEYFMfBuAv^? zhWZkIshwh7+F9O{Y}v!fT0Pn^MI93FWfeUa^Yz20Kp0T*f@krhmm|@@KDqS<)wd5e zW}x{hht=QRiV2axAL>3UYzVpFPTUd4-3usUPby zzon9n2U2lc$rB>vZD9KKaU|a(AacLF0cvyznm$O#So|}60`PY)Q=io~1Ph9Yc=7Fx zTJJVd1?_i}*>pYC5T|?~DIsxe46ynIVKV%~hkI*@MW5Z4a?6%eBQ+k4?6>LjzZDS? zVNIzrZ{oFEE^uD0Xav-@)#x<2p0IpyN!Ls2vi_8Jxq$kWj^l+3f)}0(Kb5av23(x+ z!HtVuV=>jK)pq;_k#k?LQPz@9fE=XSao6f@}Vow_%of+fr6?UDq z2^k~xJL^TnQG1CDWzA*sLxEDY1kp##6!F{xi_g(}ploV9d%q$lbWVg-A9nmsztV$< z@Lbb*hh5_Kix`)Wt4m1`pcX9qII{aN9i3Rx9-w)#A;zzHRariI@lFWy;|-Zoy% zHuaX-qVv|yW9Clj8tVxxEJil|l`>t<`R*2?#{QS)+jrvi8&8UxSm?%Ix@M>Yz1fBg zj(}WA6bUdm!&7-0*8X5G22#J6`p4i1Lk5SvkVvru7vxjwaRf}#5g-nD(|njr4EJMJg1#7JhdEhikNv3aNc*>dF4r9Xb&aZiUYrO70&x|4F6M44Zs zkXDUryg7L7HsiXBjKGNv8HU1;yaue{abb>XSw~}iQ7;ILia-&yzNjET&OD+n4p~!^ zxx59^PA69VCx<&*twz1$bzaw8kv=m|KU`4(SwmN{S}Uad=U%QS5iFW!mG*19+L3o2 zlezhOC?`73-DR2czJB+o2w#7jI^1TXN@d(-yvorzQfA(^Izt+#fg{fE( z@9Ht8PG-Vn+(3QzSb_b?OYZ!vR?J1wtQOc9g%BoeJ~kCD7I@Eaef}vr`c9sDrO9xS z?(J<1^Sso64>89;9tt#0phFX@Y@PEe_6HN$e1>4eD~+a?<1J>WQc z<5Hn2R5fa6I?RQh6)JG@4mt33ErA~OQ!0G71EIS+x3(v~s0dJkcLglBR?~ZJOsFzPSGxGcf0mmO9084#?L<00SMOglL}yW` z6d#-v4CLQvz}F~s+xVopt6aU-7=k%Tejz#mmo;IxiP$EKtJmdaUO=N&-oE zoep>$*5B}+?oT6*s{ku@MPJ}3+8n>Oc_I@NbR;}kJDu-z+l38O+M7R9ldBC7)@4}~ zBz2!<(A*FJjMFiV7gV1^N->qu>BGmxNF7rs>cSdt`3I~u&Ce&gkB>XA@v$fad%K7f zenC}qw7at8K2dI&9NC7se1n8%=qhd88*fsl3`>5Dn=y+z4wg(W?%<%sXKi&SiyiUP zNX6)|)EpNPE{N+ju)HVbw{Y6{PKemn#W9Z}ukt)deIuQ!ttf8fE)IA>qr^zeZ#=*_u?I+c$IdgpLm=rh{dV#z+K)25 zb|L|d5pvPZdX4^u+nCnw?@vL#<)uDar`l`nPnsP$!5!B8WsTjAb_2;ro;J+`60wJ| zk7#2B=wo8pxrpr?t4U5)_>QD#TiWLYRP>P{gg|Kfb{`OyNYZqqnVd@IJRygpIlR!^9zgFl5XMo z+K9LSXs+WjK>((x8q9s${p?6nliFo>Sl>BX@-j#M$!26tF+>;8kf-80;3X(Lf?!T( zE&%C&SD^);=0$Z`kIh(c?p?V&i1wL7q<3gW@9cB@`O~TA#?KV zYzf%Jocq=X2P4M$J5|Bo-A}g?UC96~H|rI(loxC00pJ#G{fy$wT%P0k`GMfYU5uRJ zrMpjMR57hPu!kU0aN~!E`pv7LW&MFSnqFJf)b!$L1+4MgzCkRO0sS=Ig8wHB%%O>x z*Vg=O+=}43I5QB1`X`y?)iKoSp3CHc_*7MRV(Riui;#oE! z;b(_~HC4+eb%fQEx=cSmW1#>u+v!z6AKy|A%;h_45~m}MVMLxD-TK+_yZ{}j+sd)I z3pk0J8?U}fs`~Up0G2Y}0+9mQ68{W0z_~fL8f_W{JnGyL|I0!#EqYlV;8JgiAsG+w zl~2nFyCAMl{{1vGhn>ZKJHY%sG;6E<_uucWzx z6ziF=YGu-pc3-tlggv{#-SEjwnW|ES)MfIUhg+rE3o#$ra6Uw~I9I+HA>dFxK8z|_XASF`0Zj-bz$9C(iQO|x4=R8ZC-QBbo zczvK2AFQ#dUBPEBQlap91@VMRz#mRIA*!aL)6O%an<8KfywG4$U@%cr8Hz>Fb?6cI zOLT6iGXzFx3hsI0Lzw&uSjxA-I@qjzAVGW*_-+FH$-8_TDB z09SnLyEys9D3ab-n46#c+aYW|6j>WVs2BTx_-(Shr+4uxeh%(tHZiE{(5g2OH9{_Fa`pfitP;PBjV ze1A)0<|?|-A*hlOc%5onapWfQ73Vk z1)}0X#9SR~SEVW$2|7HwPNvDu7KQ;KLgFp`r;sjjHFQ=CcYCVTVf(`de3|Y3-Z;7V zVA1WHm-+{upbHA9d8deyQu#uFHU|o+Ge)HAlo#P))qcmQK*npmphe&pb}IQ%rBs{( z{{NooLz+zqgSM2JHCpaU5hrL&DSPSBK35Iw;0JkVJIp*DJ zGGayu{L6A6e1IT=|Ih=9~YMgem)m=$B2@WS?%KvX9 z`SS%iXes*qg$SFZB5)%T7;7OQpAx-$NT>X9kv^M3ue`V%f!fZS=lT&LdMx_8q$24NWc>t8OcSd%Aa zVv32wy!Qa>!S?LJ#s1l*X(;1gRp8Af>$KRH=~iJ8fy{d@&L)uYUhlaTI=7>4kO`@@ zpb^!#gJ>+ntEicrC4IaMUXPMB`JsK{7L&12c-gB#hS)OJqqb*9St ziu#u8M=PxLS^QOsVvQDlaeas0Ts8H4&~wu=z@M3(z6g*3o3Hf)F3^xt&7p!O-wWzB z@MGEn2hB3agN2QxOZi%khP$kK&y9o~m@!cyRAPs^MOqwhzFnxX=Tzts*Z%SB`{PYQ z!`7$_=IVpFSVVD}QEY0FN)hqbc3Gs)6sS8ex;1GVRbK_!a}*!QlDIx(-6Ckb?4@^!e>yAW ztRP>4h)%sKvq!m(_mu{UA^BSDvLmkEQHv+y0Qo5PNI2C}gCh%G!^+1jabdj!U*uErgm=%kc zBHvlW!g|C;Re;wCDwiP4BdL?QBi#~QcU8_r!Y%SJ!4D0a$IMpX?a9Z$Ot|{HhaIR$6A!N2ZG7k-_S@PLXxkJ#I}4(a;*Oh}AMWkDSHvF{Zz$>+rmfMtt*~0<~?n z=V9C25V4j3DK7@oe@xIDsb=L%pYqJ!p5coc&H6|{>h5^`RR*Sx;|DRN?7VXrmpNyW zl1}V201#l@IcJpStg5ahPPlX1vc>c==Xx9^!;pJa^bN@qkOuC14+P9aj`|!2lBV(a zhO)uKP%?bwdWQR7h5ua%k<>@f?rI;v^800}3Dfo0EOYpir%5=0Vlj4r5HSKJVD{Ii z+$MDB($!u2Cr;*}&`WRf zUbWP@{s?6Z8(^yVIS(?$ukS7MbLH7+AJzpCPXPSK?#P~m>Daw8cZ6ySZ?6~wA(F0) zP^Ii`v6_9_aJB%R_hd%tS09veWX{NA7rCsjHqEgMK^W!iW2vmlE zy_t;^*3UHaUnp9)zms?Ei91t2(m(P*P=h<@ zUV$)|=@XCzJJq^4^EfHSH7^=t`8jl00|LR!BDh7y%Xq-%e3*1ol@nxX?bb-%_f66o z<@q&*tvfJ4dtzd1zTdpT69>V0UKTvmLGI~wm6z8oX$7g7(Fi^K#Bc0+e!S*8Z zKFjXlr>mR(upT;7s|Z!1iW3p5|Cd?&8>hR%%GS(vFi;PoIw@ukFMIn_aavu>-a_I; zMPSy%8ulDid$Uy@xgAYT7Y~0=rqE!uzOSN~mIN+i~&&D>|{Gy}zsAxHJRYL@gw{}>w& z1Ms_nc5WQ-QHpO9KKGh_WQj?wUCyUX)EwKXN^~&;ytI64Qt*Ei>@_xx<2qlB9XO8< zpE+ajq^H>#JMnQx0Ak-7%UsqPhAGD2V8e&K>;z&pd>5Hjd-r*oM5U6knLSxUDxarN z2bV?ZH#^%{#AmsTOi1;;0ye8zR2d;aNsYNT%6r&|I%MPHiF1KD*x)NT4?|^GnKl=> z(lOV)Q#@^?Q(x5nliaxv@0z6>~CyXI$l(C5T?tFYDCzZq7@Mey4D zS+ToKgKYLx19WZYA4;0ot9e^VfD3-t> z@mJKCyx@ll^u;&M?*nx{2`06f)Zs{)oB{~cwOWmy;h(tM$X*4ppz6Xdo*NMXH=+Rc zV1^R>qFP&wb{fH79YW9gZGqzlc z@{}?Y#zHQ$tO5cS0%Z}yS|!TjT~Fu#AUy)a5+GE zT-23!Su}rRWI=RU=J<11Vz0T3}Dw>wa5C>b=7q1Xvv`H&WWV|dBEUQbiN6wI zLIGs(eIYGRh+$s7mAvp*OytbyvVe)T5E^*_0QYmUs%-1mWCb5g!S(^}GZeo}I zqX-^%@WgNTNW~Jqo;?)ZZ8?)4n$zw6_^rBI%)O@T1}V*5l9d<6Hvb>$F(|%zC2Q{Q zH-RMp2xuW9Jat9IIgxFswqVO=I!-_#X>DzVE#*~qNI#zPQPM$B z31x>l_2hFb60S!9-s9llIrlQkB#@yq0@;ab#OdMEE=bHl0MFclt`qMTepl$KrW8~s z^fWc_`(4EP*Ju`{zVJ|}_dS@HJ5FvJuj+q}!rob>l*hjH7=v%l`!eV8X41>=sSwnz z2g2jHGWN^bfwj<&ta0kZgZ5JB1Fv&jI5`>~?aQ!W&g^18KP-R`i)B(S_y%1HY2qQY z>aR?@w{9xDeEEjYX}iEUA2ARJk|91}J?rP<{3-s0h64KpX zRX%g^?fA{ql96^>Wx4_aZTHPg{}Tl&`6 zi^KSp4&$(tmyJc6<9fXWN@_K{WwL+tFk!9K*9=*|oUwN6b&ZT+^y+9!LK1;T9}rA> z#|tG-$ap^9N&@Arz*u#zzIyzRw#xx+hdU@m&vMb1Di}|cUCoy+C>wWbUAwEUre@Mi z$s-t^m}m~wvJ8{vX})s(4sKP>+CRU47wyTX!K~q0I}2}(fxKs}L01j0_qM% zSNc3Z&=t}>CN@7DGQn8fkvz%*Wfmx*4A~}KVEY9ivM?j;Vtz_n$Elp)tjj zm4GrGy62ZqlwZ?@Tu^=i+b}Aq(O2&K_p{eX7 zhfWD4%!Qi$4_<;q9sfo4;}OV^kkH0c|Gnm;>?%Ot#X{{+mm2G5t}u_i*&=K&Fzihm z23JRj&&+gmtPSjE#GD6jnpZ(p$6-)z%W$mHUdB!GA83x?eN1-4(NP}T<=JYdL1l{g zCtbtt_L2@0idwuXb-XEJ396P=h0YNclNFAfn=zmrukOUn847F_EpW=EK&V(Et*p!( z2oFN!U@$R5B{?78U> z9XSsAo4ms(ck#wDd{tr-^y>5J3q0m;>2i_pfQtLU1Ykp|)aFSOLyZP52`YqjLl`MU zoRRR~#R~oeSsws4RYe9$jV5%j3M8$L8iLw~#s8JZ1eMV%N}YC$p#58z&rZ+-F6v;} zdGHp|Akz3xzfoQPy{Gbql`CKONTJ(6X9*U~>d{uzFiihw%?HJ-4j&3v(lC7c!++Sh+U+0cP6lp9Q1FdA zZSYQClrw|L;1yWWP1t77Wct-A0YE+l{G-B$lg z&!BupP9ntfj&;jiw{&;KGdEG8LQI-4T}hhi%QdWatTBmEsgWp-HJyPi9p8m_HPyh3 zEd!@0HyRgO%~#DSKf1pF=@8$_C;AI`0p1<8hrFjvmkwpfdaE6aYH8a*uBtwCyALXk zqMI+B8#Hj+^ihz1RrdXz15dv@WEy7fyIPsCE_a*y9LIH z*fROX?X_yJ@NDgCvO8FWUqxZlz9w2jyc=eHnL>T&Hu}fQY^py;DTKj1!Oi#-JT7DH z1d=d+wgaWem#3aKH@^Z@O`LZN<14e$(|AwQxcRnXUV41#musV22$!a1g(Jm)x2n%J-< z_6|h|X7U;Y5qTW+@pr6%@F`@1>#jjDxW&xVSAVmmf}@aA<$A^7_*^HBsDha&5H(TT zpmzZnEWp^>xGtbZ9s*l-Lyq&7qyhL1Z%z)Z7r*2~&V)`M;68`~+KMUQA)M4>xAve+ zYDqGuIHhjH&cMW!my>n(J_G~DbwhK^naTq36cFo|S}menc9^aZXGGU(zscb0-Ycf)RQj7;kP4^ySchQ+$~JIvzlHP zo9S$JQ%FVC-Sp5wlNPl%5a=S}Fp56Ta{KLIi2p(7f#3fMWg-07ANa5Xzgqf|Fb5t4 z_U-O06a~x%ax_bt0^Qb|v79G%t(^>I?~mUT$Hb-FTlHj!)e4SvNjkDX@% zX+VeSqLsP$BjUoIk*;o?9pPGOa?s(&5_7IDM3OUSDZbDppy~!M!P~L@lmZ~QE`-Fr z{Uy8g3fLNBz``hSN{h@~kX11Ua3*_2r0S|e#JJs8EwU415k=n^ zUB>Sj%Qc>_rqjs%OTE|?BM-?aU_x>ZRc=wI>@_}LgCa0N9w3VJ4@o1CI{m>wovYvw z6az_Rar{Eh`#|kXl+)Bd{9fE9T=1XQJrud18BKz>7y~>grZ9y4>U%^qu>rK4Ymdkg z3yfUuU8>ygkiiOy-8xcVT>R~C%|P$CClMh8_Tj(5)fXs;qZiyZ?ttVr+()h`c$|ArJ!4odn0>rZ50+^mRGc{HQRFiKBQ#$fH zlq0U%%>9Mq6C4G9-N-ael>b|uXuxLD4=p`}+9N^HZh7a008R8H$OCrb4p{O5@aq`I z0A6Sl(oOaJ*W-g5^7a~Urdj+aD2S#aohk{%`u~!n_92jU5JmSjZYVh|hM!)*26_3g zs{YvDAJ>CE9#IC7;J}jlKrM+JW>u3R0W*W=3FvsnvK?AX~Bs6c4VkZ&L^)g9+KDhjdt((vW04r3kRa<4 z)>yC#k_^KHQSSdUI3Fm%;V`e6Oz80dtZksS;xsqS@90GOf0jk?|59%!+>9LdY@4&l z#Y21q|flmiX0Awp0jsRuxg^s*Jri#c;+RfASB1|=i_^a+{8L2P=ot3FU- zjRD|kx)Rr^Q{?JW!=Tmrq5-}7cP}1Ks7VlJSW@sJkQiKg$mZ4mC`ZHp=*_*WFYgAt zbX(a`**zqNtrW}Ql;H=FnH?Npv+T6raEp`Y;JUS&|U}D&sRBkG^ zoTk*|8z_;)0PMN!ql$2X+cS+gCRkLvXR7tSp*u@uJZ@eCh0lmV-2DoRY5AIt<(Qg?z{n*-BH$dvTWk zomzLdwuhtCpxH>E27|1p_jTps@W;pe%B2H#EA)lnTQGp*+-K%A8(E#3r9>`QliBuB z{LoJi+{S;vz)*H@O>t;q^(=@((v?~ z%0)l6lX;3(`@uPI=3`UG|7u@^0td`*T!=9F6QC6JVb?@t|FHJn0{?=C#&_T$q%-7c z=!^6z_G`=~^JhnCV-8yrIe<|%P+{#XQ&2$OiKRY!hZ2=Rg;OXeLoypF68<^Q@jb=f zMC_4=l!IwnSaCttgX}9c?0ZD;)aBsJ9>YF))mJum4=n zMQtG(Di-SGO!|B-GEbnwW=ni2)aTn0U=6EBNA9@|SDP5B4-JW}3|Lr%d;3pMN1lEJ zpNNo3*vunYS-qCU2D2pp0hUVd%weC}uB)We5LPOt#j8RozKhDk*^h)?9fXixrYE`+Epl@1RH@kbXrl!+)kFQ+Ab>ZjY)#V`- z6PD`Zh%wtenBBsphTSv{OJRgrLjT+(MT9QHz%bd`eq>1g8DjSd??FmPNmgE(D_~W> z9N_+S@cxq?tNTNu+<~}M0&Z{~8n9w-Lk+M2FI^B_TjC42n)WM9PfXAefFJO)D0UpS z8OY#Pz}-G%3&)oXm6{<9^%J=V_$_~gXcYgrwQaF+ zE3IaoDp9n1M_CI?dEA2^ucP8O6t3?d@3#z^l_ZIJ+0}C~7d#uQzc`8!mR@aaKd}`@ z*duU!O2{V5RAsDG*lv@k)H|WEKp%-5DQvs}`+#E<_6Rwmww@e&s<&2M)>rLxkbaC1 z_F8FCAdY(wZJ*y@_X|zIG_;bXC}#nXSj`1_}!GYvMehQ~}5lL5B>0zxe~RZ2+CP zGz3^F36O2Q`ZBT+V&y*B%y|U`cYJl*R@~&VWLkswPPfsy6Mt@=|-zanfXMIQh@!+NUcQN zy;PpV8Ww37p+?+lp1E#%f>k+*<-Xw3T7$fCqc^o%WWMrR^?+k3<9xeSFXKw?buTGd<_@h$S9i*(puG@q+C!Zj?%j^kN%MHAk?5}%Q z%zhXwFRu{0u{bnPGg18fEth*KociP7O1ywSfoS}g6|!x9(gJ0FV1HmSpZ6Nkt@Pen z#t17(}nxk(_$m-_rAB9sx z6FF6!;33ZC7k4E|*7hbeQJTCBOwQ`-Q{z>YB$b!1DLq!qR#QM>B8wco-7mbA@v^Bt zI=*9^EV^5E@dQ4sZJ!7#{)%bZ_a9TQCQwH%54N7j%vyDkO{cwgk5yfDt5ALK7_Pcn z+2`xN|B#l)-V6}$R~*;hFD@Nii#S?b|1gTE=PUVsRdh}SCsJlr3RDBt4&<^*a*4?v zpxNsu0ST>Qk4x~QPGb7@Xw`yLk~tBEJ#LS_Rb+a$rW?3HW_COD2UqHeiJJ%9voo*k zjxFo`XKRt=y6Y(8k|Y1aKH5OLiV3Rv=J`O9%9GJ~x3rdOb!5aqE9>L^FQxpVKV&A> zcuVEu_bjc0kJ-HU)fVRXm!k50dQX~_R(JYWNp(7`YPy-NKh0*U{H*a+y-ZbJ<4~?$ z60147w=E^$VzzCs%3f^R+oOaXS*|;!4=1?0-)25NcNQ35IXXWtea0=d%-A~KV7s%1tDJE7cG5z9XHER-#APb7*hpCnQ~fPcYiVHU}e{Yjae*>}dLv z@u+=`)ZTGvmeh#5(LHcb4+peSTU@35-J%p5@-el_vlKv_xC{kgq|Q5W8c=99n>j!U zIp;~f{RP0Pfj>_?4zW;)XPXqfXRt;jPPKElMpBdiu=Q=EX^rb>t7mrplinL-+}|V> zgm+?l=Nwr*kBt_014YnC?3cAT?b>izlJqKF-N?@7vrq4(+|=fnV4`!W%2rE>*+T5$ zmYX{odbA0qk>^PB>3$~RwaXwh?jUoB_8g7c=nyJ%U%Sl$iskXe;8FS{*2iz>X3E}i z^r`|K1rhO9o8l~vLzkkealNVH1)bZQU+=n(E$dv7)fwulw(Ie&M_i!L5FQ7P-Ov)g zzB4K2&HFBFTyqztQ{omQOhq5a#2n}Goh<9Hq-OAw&ML=S#7$5A=o$5`K$)`?L^jr} zyuI+?$cC!wF-~Ux_huy8puk(5s(g5A4PNMshc%u)n|}4${Z&O4ZRML!ri8n%?~UwV zWvglvvSa;tTlx*{(8vgVA%%CLVC+s*AoJkMb3k^}}e-3t>R)BE>ZpRVN# z#pvcXBav*konHAYQ>C{xPXD-JO=;>AR_5q-?0(!EreUV;KBj--GX7I%a_#JKhd_fx z?E&pRbs=pPPjAAVy%=ZH63yFA#j2dH+pHhPK45%UE~KRy3OjSF=Re6zHjT&Emd6Q0 zPLH~zPxzX**|nyz3^Ck|7Ko1v<{$X}lu<C*<3*x_t$<^nS_^M>q(T;h|Ft0zyZO|$lJt=fT z`&+?iiN+Y*Q|=#Qsostud~VU6)xdY~&I&H#NUnEXJWAbK^D2D%@z8y3)OyW2P)n|I zc8=x9Ihx8Cvg=R3gkig<;4WWJvN$4m`^oy` zHI2}Kd)*W2gYBPU4b2j#Yd<(08ku_Hqb&-syx0o;8XZP0zVIH6)>K`W>3vK~4Vmki z_R?a?>zB>ZPaL$9ZU(Lqmbbj2U#5=>j+)-35XGfXgqJV!p)<+qMG&uz*v5|DoPB%U z@CWG#rqcb+hUYNXR7!#jpBuZuB6I#EybT?EN6IXAnpSmd2WKyK!aL=2A94QhuR2V} zcLWtT$rJI!zjOW7)+^yXi8UwPP0&W}0}=$Exv?;`{0HeG17wQhuW^M?{m^W|gQjA zX+MXknz#sl4B4i>>|~japPN8y_*_fi=s2BoWUz0mQ;i_B`VxYS6*b|svx_rLKW}WF zRFj__bXCj0z;s^WGX25G)0;g4QL;Z9kFH#%$0EnWi#S?U9SBQtf2~P~5btVXo<=!- z@=u)6HgR`fDN#x!nnMfuVS98yBqS_%`CZDx%}5)*rTCKPM1;+!S+uqXjIYKn)JpPH zq)3*vAyS^x?vbrqi?8<%I+BsGWxiFW#AK-~HXRzRo%6~YtGSArd+TzkF<>yUnlAoH zXX?gMLYI3dm&5h_#Z0MK#srrvN#(K?^^w7BRlfTN!w=UNjS*FvYoMG@j)r*pX7tlL zTld}{l*V=zArQr!{THryceXc?M;%lZ)OtCewsNr)&>%rK1kT`KyYw>_>R6mzDJG7S z%J-Y2m`cKYdz;TADJbYVcxVYEW$b6ngvDXcJ(f12pUmgHt;@I4mHgO_X2LnS;d)|S zmd>VEJ!J4yD4}Oso+E0#@r83Y7kx0hdH*8jgpHL?r`C6Jt_pq5#j2x$+^Nc7dG7aT zmk7(8c~r{@tyW#^Lx1KfWEaH`zz9xJ2rN%l^gGgjwXQohg!^pmjow1E&7-r0P&U`-K=lT79e?PzL^2eERF3xqI z`<(lIzuvD!3OQg+B6O#q*k=#sSy?=-#?ej(ys{$z2#&Q?(?nXM>l6eR)%_;-4cCq zlrBY^b*^!?t<0q>8wE$!y96$j$ie+8e1wj2c1np^`K#(L&*4uQ9szIaNcp^Oi)QKx zl0jBTU~~j=pAqj*2h{!x3vV}Z03hBDdi3{hyXvcpO+cqSfW*Ce-kpvkvtBc=`>(Ze z|G94@Q6wqUSv>D=hfDKj{M~`$Y-IOLsMcJm1*zOhXZS=uye>sVd|V|&z+2UQywflp<~?@1XRy^OM^gqi$Y;s; z&^YI1Ww$UheEoL;RPn*_hOM!;Ye^>Xxsc}Wf;xfg= z&jV={%6AAAdig(W!u+4B{dA7VBlS&Sw$r`B1wZRsn7lt&s7+{9gYBft*=6bH3itJC zl-q&72!DYG6gpklckt87Zc`QhK)f?gZeAwY^d(1F7=lH<@cXRD0wMApY5jOL z1pByivfvrO@iW~j#N6Vg+(}vfkBC`wLOR7>uJr`mWKr(c;63gaA0Dl3)a6`C#Ufxz zY?Wjk!dT+WBFbDtB$#G)s47Qb{ACW>T(P@9M``>v5t)9AX{6LvEcL^lcEdt=bE%@; zQYJ*5OL1!F8F<@zkw^ameoBMt)1(#f{J7|QNhsF?sZaA_5T)z|!Tr@cDv2qeTPcgq zCiNYr!+MI}c@*Lw?9fDxg9Hom0*)#LFO4y7FHHn%?FeK-y0QotMaeTlXurcHeIdTU z=>{pasjSNpUcR`9undh(!@@M#XgS`D!Fa7KmaE_pj#Xa9xiD17D6f`mj+gw%%QOa_ z>)^|2!+LI>#tVDh~)=RHps`G?6kqIf3Xy;Vw%4$ z{VO;&6!djw>!-HBXhwx;%Mx>HPmphlaTLjyrnWcJDsVPGaG7uUYIf9}uQ#`*Dbx+J z6NEWWrVQiD#p9Hrmr4l2$hF7A+77kZEN#UD02e3P=$;~Sj_1^qh+erzGS6EX3fd3* zbl&dr8Q!2O;MO^mR&dk^*Tm=H47*py7TT6LhXbr|L2Wsnf`r2m?)A0BXIx9AVoPrS zH}9Xih-&7rz|GK+v`<6YS(oDx+!6ySum3IxhC{sF^&qw;;YaO30f}Y4N#q zJ@%dd5xmX9*5xDOnj8&oqii&a+m*t0zTBzw&{Gabkjt1UUW$dP+#x`L(hDJs#+2;fH`R!SP zdNuYA7H2IHN9In1<_T%yOaA4~-bB76G~HRk3z@=r<%h=bd4GDF9KLvV_43MBG_YL2lj6{)$;Fm!NV)g zZxNk!h4|Q$RWZ-_<`*|+yO-l-7p0Em4Dr5ssap;CNAjhIyH_;?oOY>fl;{$MsisK* zg`s}_nc)c>V?jfC|Bl z2W9#4)>YX?n~^$W&J$!^#U6Q%BW0MiG+4nfc=iL|XtKv2e6NBUmy-1p4KYO3=g;kQ zDC<98ne%43fSZsY0f6Y2`2ww!0_iPhX-KY=F4LBP`A6yP;|$WsYiY@hS9V>ODqHTE zwuD}MKVUKZ=0D1J8++IkJ2pl;wJJTmKwg$XD+)XO`$%I&QKiv1`FpzQBEeL&cR{~O z&0kSGU8kT;5`CTYzN1h_vNF0&C|09Q2!9vrKRY?g+pU%9&;=GzxZZ7uw@MwYK`Kh< zTZ=Lwlki+!O8a{wf|u|3u{l0A*oG5gRSeWj;ap>B+cAue24D@!Mg0{IO-3wcA1euG zLB7^FTq)avMqKjPQipV=(ol1iX zt7CLx(@!q_2AVotrCrJ1pgfqC7DLPg-AVZv2P^fOrTLEXKKTC3pK=i1q>8Wi7E0L4 zTG-V$$y(cWNX?J;oNF8Nc^Eyvv8mFBF#(%i4$KG4E2xYhvcO;x&#&IR6x$AmF7e%E znChFXRSC0U#?;hsQPJQSjWs2C;$&gZoop8HtyEt0@E{uRnXTTS5h(3qpeORUoD_nw z0MaEJ#Pc?@+S0!I20-?*P}f9? z=Qo(}{CUByuFXE$^@?TfVG+7dO-q37kDocH{>oK28H zO{i~pSg-8yD`>61O)k_4LQCt7dn=-xG30BJ3gQaH_vi7#A2GcGoDO6pk?3B|QcO-? zunp`+I~;)Q1{oKNl}4ZMWHMVRsNAww0O=@zBe;$zY&yyXNdGBBXH~Ozc%AST;ak`A zlQ11MyY{gMIu;RT&^4embcjfhQ@yMN4o&-8sCQLwgpkM2 zbxvH24*76QyzGa4?^=|R63qJ0a`dK~e$lX|7MdJ@`C;?L&4!S>@iLaThuOpLPdr-9 zF(iW-zduWv|EMy}DB*?@ztEj>O2{ZH>-K48g$SKQbJ|z|_GEC$SaVD8;7E2CJHvrP z2HI3u;uS(^gBfg5#U7KoMI4@<77{|LX$3&(cy=Y-(`~=vZzgcOL#MbM$*^7hy$P`2 zrh}uDwR!2Rp>X|SsefB_yqu$aLQ@lw#3?A5t74?9yIq&H?bJzM4K8j`&NQUFjO@lY znuxZ+r6#>OmV8Zr3v#@$F8jS>CcJvS^G!8<5g=Sr3)UML<0i5 zVfh0xzsRSQDl4m-!k@4DttN3)bF-y-)-=bvaK*mMj(E9nn_bB0Dz`+$f@b`^ z2>BOHyV2Z{L|!f|;Y?WIqMdm3BPp%MZ*f`+T)~EN0*E9DD^}(!wwJL8Aqm)hg9{Z= z>-p=x6>9Gz($_Jdn5%*2&p7fttr*d}n`Zf^cRqmH@MC;RVEFV>?9%`Ty$E?EEah>> zrmWrj=;@&x-$u*gy6zXjj zd?tZ}U@Q${(=I#Yrr$J|eyA@aCk=hDj9V6y!Vs ztaY_G;bvi}a&W#)#f#r1f-HG~`O#Ce1(Vs0$^0{FRT{o7-&Oe_8g?dayy?sE)odu# zS17@`d2Dd2rrAMWD~m>eS&d&4&B5>XRooWhqiMW#h2rOs=qBY;8muOR7hjwo)V=h8Q)wgLv8+k@bTCfGM2VO`>FU?bzQ99T>Fd_5p~ezFzp(U?7I1tm;BTL z#h<5v%Ekxw>ZVw*V`;wU0OnB?!LrS-Tsnji*WO;IdNaKw>DKdBR-V@x(j}e|MrZm` z_b|)HI*`h$;uy5t%;~@z9G07*)i1F=K@v$&r=*(8Rr%Ieq7Y8#`&W3ktf?(A{ts`sW-h`gkU z>V9z;Kf0N=)#?;w@`Hvu&~}`9aMD{vD+`@A(r8&we&bq1grK8CnJ-5rKLthQ|1+zl?g0_XI2Iya>7lUJB^;2c~%uwjy{N1@UCt zg44w0a=mCvY$qkOG8zBesDd( zSm^+T0+pdwFG3s@NDaI|xFe!Unkb7AjS~^8m7pN|${|B1hgq|4fWa?UT~YbLD}jB_ zI)kI zkYD@qJrrJbW30DEf+uv~H)Nb;B=<7MALn&_YrVDR94bMGz4y;Q>TAx}F+QPQ5<4|t z@j#cwR=x8zO0S-kM;%aFTvU(l7$qI4yjS1mYep*u&lmsmGwMX&ufh|e9>r>Lf&Ns$ zLx)Q6F9`x4ihCF2r5-ydVcDJV$a@a$J>7#uKm(uq*T8heGNE1 zqHCW*d%|@qC;(#Vo0s2rfdM#}f1c_cM<+*JXg}>^2G-cuSr)V;cu3ULghzlDQ*rM8 z5vuv5Yr#bl8%9bqFeL9TBcx53xAsHwwa$Yk@h@mkbI<4ByWnl#E{Wb)EIKCX=Jk*4 z@=AvVN0AKgoihP7`N`;*@IbW9m=>R=+(3xx^QX;-{Z6>p9kia9T=-Xh`QB2$VJ5a* z(O+N!Niv4G2`i!Y)Vn3E3aeFXHNjUCuN($~yAqT+VWx@hFJ}z?a z#70NHi530XGtl=i9Yv}w{!7k>WMkZ?TT@Wa*f>UQ)wB}ZH$6V)@Q=3>~#ZP!{H+_?Z(qwIR+<04U7C7ZEe?*M2;C-IBaw= zwgKM;EqG!fSumEfyK1>ddy41-`-sC~EaiZImPh`2gAtQZae<#Yvj%!d5dK{ffk zv+i4SIl|*Ue?u6EJ-{(714SO^Dt#xOLD;{jszqLNZI9?ZpRS@iT*3WTiTb-+Q{*S! zy;&bjiArY8g%fYr^?}=Wf|EZs4ul+a+O4sQA|!H+{2hn6o$@Lwit|5pYnI6T7(02Q zFQ-2n&OZY@?T)9mqG1N1ONTDd&t%LNU(4B33dy1e4bLO{k8BPILK4O%ut!1HVH;P> zqaP&+=1(5BHYqaURS5nQx&Z_y1Czn-JHOivWtCpCId&~#w)m%t^87=uQ$vrDT+fW8 z&5R0|x@tn#^8#-$SF7&#_iJ#^qQ7ZfW$GsNDAF1ntmNOAw3lpTgZ9ls%PFKAc><`= zS9*8nvbP7dvv#(eS8ZONk?oFE!;yYcCN5%2%hjQFvx!Z(%D_!!4QJ7Y zogH95D8OS7N2wks(Z+;R&g0g~Ri-T1A5lmuZn>_b884_oyNo;!Uya=D@^=DuE1B#X z##=WytfO9Y6URYjwT}+^zE~@EZkS|~R&h6ac}1pmhqeRP%XtnE){Kf2bhm5lvsfR(u#F9Qa? zIV=9S?mr**AF+2`fPixbJ9~WV`|IjhJLnr}2_ya2CcTL86a)NXw1^s_?&cWMK7pjX zS2nC4pkQ03sv*^WRoq1+Bqd zLYwf=B?DO6B?U2(Dh0mEk)hFWS2z;PZH4{Xn?2-RL40$a-8ge23bbs-NwQ2j6K}|Zhy6<5s4?mixZ2mYMH)P2L?y= z^=O=yqwO$HW%k}>ynnAl80BaR9_GOSzp}&GvOpY@>@jd(o_-N=qFjp)c5W130v7!=&^5k^ zvBjHeZR}qXc!pTT3L7p9r|b-*>`Xe-Mjr|pS^Fyp_PZXPg4ContJCVW!+CX`J=Yf( ze>ssY2M2R6N{@WGdE3be+1=$nU&Jl(#$mtIplB%o}Z)EoYHt?%MW0CB_gF; z{`PV$$3c9klll&i0x!rmKLN9aYURhfXot9<6m<{FyMq#PgRl>6kj@aWDX>v8 zqEzwAW834y<&}8u3TH=r4f$1=vk5hSn;_~OG`rin7kxmUSD7zZE@%4A{nQ$OUP>1o zX}QEQv#0~__3Ev|qIH#|(0QJa1JGPkI9lA`Fe+Qg^D>odT)NDDSHo0P$|I~=M55Ug$#wJOMfd3E zeWTh}QyTmR&OyLQHT>|u+P6}#0PV?h4OGY8Qu8Whp{Y1g0CnZKP;6*&(e(ikwDEwI zGU=IE@x|)82}(&a_eYaf7JQ(CBj9#g$UWPeq|{o8&Q8#|xU<{tWW3S$GT7vjy3MUu z9V@q>Cdqn!WXfM3BdyrQO=tjbtg(iZ?R_JzwDdm(5Rh1eK1R4E9C1kITAM>wacjJb zUsXnvX)}#6$RsAsGr}_~d0>`_RZKsfCpz;mB z0j7M{ZA+MfK;uzC^VTy+bLyw_F9w%C911gR`R=U&6C=!}ALybkV#2R*;N$XM{ z0j#R(OL zfNkM5iP>pFH#@3AP>Cp0SnB^oD@*2q{gv8uxZdZ2!z>mh579#qZy~sPrv!w!_Sory$UHy`5qf?0WP#z7n95$xFuibYHHXKx!DAyuG ztf{Zmjyw%tr(>?ZLpO*Q;s>CpAc-bwEirXU^x4?aRzuM{{d>|R)MgKZgo%0}_%~Q9 z3nQCtdfnGZI2Ylqmq$oHsjqSqs9uwwZYw7OJIXY_zwp#5k&eN9P}dP z3+ghpu|1+GnJU8yYM(`LmsnW8v!^yQ`Xl6|POS{|Dd*dICtRiYIl2;BH?v<%lQ0kE zaQC%d@R`%X%#5B7-V-7i8A}}Ng0OPTj(u_y{vvG>V-PzA1=x@LNLk9GRKa|V(qSo~ zB-y@fr14em3eWAQ4$iUw*YN}F8SaWg@h!|Fi?54JZ%`ta{fk3}Z81<>AWsw?4{}j;<)4^Tc`G z{mn!ktSV!^1iGN$l{3F_1x(mgQ=ib7pg++@C8AqMVl1f+aAv%1R>v&1I99q-5c&i^ zLR;=RwAp1ObuGv959l?;+q3*Qe2Y;DE!xVRn3icFO# zOV9H=2C%h04bS|Pb$$SMo0>23ZKs=B+{t`3Rrs%jNg~YZ5|()W-gttq|9$lMICRs? zg5l&j2_s=v89iyJ0ef28J!9#oKiWzHil22+L2Q+8%1BR)tEr@Kuf(j*-eV0oQSN3V zJ7oH&YUzkCVE$Uu!uOTpe(F(8zIYW3yLh)bg`B(8;*<~51)`+0GWfs8+_N>-3DW5k zIMlC9d$djVE`}QWg%Xl1@2Ez8{hTgU@l%(D?HpB`S_gl1B+hs>!j=Vs`slUYKL2f` zltqivKVIiP7<^tU{jc36F2yreLATC!X__u^sUuD{uwkQ#W%rJR?XGYZTO(w&>^oCG z%zBG5;78)xw6cCiHH1l?3=Gv^8_}f+R_U9*e6iGLab;96Guf)cu*+SJwd>PhsEV*9 z7>zaa&M%6{-#mHe_lzfUcc8PH2sl%2wtX#tVc^_EX=vRyxSdp@yHfu z`>-<*L@=v)@to5<3Gq`x$nuvRsMulnEa`4mc3>RBOB*2R){r@OL~qV$vG@* zH)t;M_(*P{?xK$RVu}7ckY&BunmX5~?PX#xh>zkxw7z!HLk7JC~U&gatbH0#IlH)mf z=KwI?Nva6@XTV@CV~<6EW;sET;o2s7K3EF=n3wkV4(|3OXSu#ZNKzxAO0SX8GisPvDhuEA>BoQf}2jE-=N4T%I@;mQ^Q zx9v7WsV(b{RyKUDH@iK$;v`Cy(@+%kTWc(}S64bX+Etp9dsZjOAC6kg;$(<9h`Umj^($h@s7s-tbZL)qQ0ZnH!d>NyC)X{(J8AL zAK?)rjs0`7J(_=I6?F_JJz?lkxiO6ugjOY*UkZ}cLQDG2{6%L|Cee6RPZu%sZ7*0)4Kl>6@Hwd zKlM3`O7{g`wb|OI)clS-IzcmDRC5G9J5c+~a2Rtz^YU(>Nlb@J(2#y!261@A#t*kl$U%qG=t8c03DEBLUmN;8yc}l7=Ac- z-^)_RB(mM=nJvHP!t|9>J2BxL$dql}Y0UhjqVoZ_O)F&7IRK3gBguX;I#0zMCrDF6 zM4W|3=4y`SP$I~8gJX!OHTU2)j-&dJdRN$5%J#h_(O`ILOLK$_#jkag#wWMDlvNB$ zsjUOmpP%ok=l5e9S#aN!D`g9{sgKg=Q;sW*X0+H0ci$cFs2FRegvX-T-@5;L8$MzW zm7I+|f6Tc2JcuSa51glO9QpMHG%fe>pIsRmWB68phP2sIO-INy^EXjzi%Fi5=ec&O z4BE5a*)nr#ePUEge0*!b%@ zTx1&a>rYBYy^{29XNFuE1lqnP@j-yQy-?=oNYYj&v2)qGG^``fAC$vYNaIZsSBeI% zRgJ>jkVllE)jjc(%5yk~Zoq7Xz~g$npU;-o3v0pJtCWS$A9M!0kfFPzLvg{lLk=CN6tXU z+vodciR&P*_2|G!p_gIA^K4LvaQSjoi~k+j5J&{Wk-((D3koNsD(!U9&6nMp)YI#hPe_^K;!t?M`?4{INGy~;|iI9u5?M;$hbo1eSyFi2m9Vmz(WB1 z$QVEO1+2@y4E#@6Y1@SpsS}TqKS`aCcx{lP*G8*#@$4P&DzhS`eiZc3f699jC!s^OCdeRRPzxVNK0|zf($$I~f!;}TE+D@O0 zHXieDWl0}%A-+b#iSIdp|?71PMS0ibvPKc4`}H{C(N^7r>R z0D*5)qA&2)|1<{EuK=(gy;JNSUeVOe2u2M;F-r z>s;`7vN7YokN@w>TcF$Pss1jH12p^#bVo4Wwa#tj ze*9b7&@)O#b2qE26Kb6gZ)9tPR!BiBTL70XCw+bWTD<|SCuNor6W{JLNk0AYR!lVG z4cMsaaQE_9=@@gVNddAn=nz}$vZ2f)=Tjnf?b@>`Ws12_=o@2R9>uKhdrmS>Xvl9~ zc#e;$In{a!}9uZh?(FS^FfFl*SA`UVnY&T;XUU zI*>uSGEUm_exD<9Y84YTP$F3iU!*OwdAowbV=sC9vf(Bt<{ym20= z%bayrPLt|Gf=d9SG1bX=4{OdfMZ`FN;Kf>56sU{RDD|{sWc@PXe(2lVn3^Z0mK&ZK zwqk~xHl5~{4w9}Tt-{G7^f`O_oAJMPCFb<8Zc6kRaBWBMB{y87jA! z%2F(Ms$rWPdEc;Zfegsq+oXgCWA~g?s)FTIij71p>fJJ}ynC5JcFd!a(oi1J{b8Nw zOKXIlJjH{j+_)HlP_~^4?{6Zdf8oD~=M|ED-& zI-fEZ!Mf&kLh#nWTQ}-8Bi0HJJCavEvf$2CKBxU|9M*Ces9FE2Q;q^DuYW>(Rwazq zTXvJWm%iB^syM5S8!6Q$gB+u%1YTrYlDy2Y(`pO_#<=+U?`zXyckQ zaUUt;mYi)KH6@E18JAhs`^mRk0y#(ZQ}B03A-M`8x(RSwF@trR-mKw@x!-ZN0Uv1B z|DWX-cyPAq_7bRNYhUS;6?DMtvcqk4g1(lr`m&WTG7T7JUyckY;HE^!(;ovLzr1er zdG!Mkp|9*qA!Z9o>nHFBJ$U@B88a;udDJc-_olYUIZ3toqm|#UZOtvA$R^Uk@U%Zc za?Nda+h>Wp*Li#Hl27-Wa*ME&68nESVPim0M#GTpDl3b#q_mcBBA=pE%=3r^q;IY( z<9ejTrz1{?EpgY9>7Q0p#vp&wi$uH1Q*Zsl<(=i|0f z@+U9Q3yHh&=;q5BCER!I-wUBuSpEpcg>< z%Xgrg544n__RmNS7WCm|&YS)h%oI+>(3g>2rt!#Gsb|fTWFnspa18~QK$bs2=<4sc zi3qm=;mGq!38mN0s0JMnd`u>Eh3qU4U`-0KilD%RubNP-6P5N?b;sT`+?K^rHq3sR zn4~Hu*e4h+e1Kl|@6D>2%{ikMY1xLc{@WcU!mT|%WIDpkB~`=mJMOB)*lnlbu_zWt zP<>kK+BvG^doHPG>{viU#K&u3f?E*w*N|Sb9AA7{Y3m+msFbw+z^$FBQWrfsZv?x_Ya*3SU7{WMYHivqp3`V=+?(Z9h4yeRa~F_qKpagyvP2uvziHbX*mN~% zXsO$EQ{*HLZ9|RPQvXxchxz^Vy-HDfIwBcMYsY9Fy7jS{b`^*R;N4RRq9bEBe~duI zoC!#SfD%9C!|^PqAO3HZ!dS#AGR>B9cZO2J8)nIpR?}%&4n|w5<@0+zfe}in8GrAT zTM!6BA9|FZ8%yLOMTYv#UFpqH7GBkH7xd!IrtKxOjSWSY?P^ao>%21}tvgPod$$k1 z2mkeV18-V;4oN)u)7|A+>S2sy<8zQkV+XTte{&kK3NC^9NTcw`qbQ?G=@tSz8&@a* zBm2p);sdY76`gOZovUg{FGW@1HMgOz+hHn%dAXMH0@XlW%|1_VwxyTAUa?QI_uILP z6%@{#%mo{7R%x$lwmLtJ>ws1R_f5nipR+b#4m*q?+-T?ONX|jCmtrS zo%7h;g==r@DF#kdJMO+C-qTW0X-u4QUsDnq%Kec1MekPeYS^jJS^yb6FZ<&i3F#6% zmjW;2bMjo4noLhFv?aaZiUlCC=TwFxXLLdy|AO7#>WB4%kI~};&|z-&iSHAN`+XGa z$X#q}V?8O^Wqw)YUP!WdpjqkDMf?Pj0^e$nzmVj&v%9{|ab%mDXRMq>N*wyg6IbRx z34L)+ggw^t8+^%oErDlvKV%_N@%y)b02bTRq%Xm$X4aHd4t_^3SqHwI+Z7AG8MT{t5}{ z`)q;C6Eid$pNE8SoR+(EnpLIRK6xyDHc&e5c-2X5k#O zyxIL_;^D`c54d94{>_Ci>wvC@d2z;HS~h^3w_9pPnB7n4Ci>I3C9F~Ld1&3yix0=X zow1#K@H5cs|GKhN3X#EPgroW290yiGlE0ckLn=4c7K`KrM3syDm=gZ&j;ypjtFU8)JqymCzQhSDya9OJvoQmidi<#CWy z#B%NgmbLV;7{XS6gT|vZ<;BdnEno#g107C)A z-*!LWR*^JbGcf|1j6Q7OP^DV_Q9u-qFLZjg+)?(q^UK(2L>>_z%BRxHAAB_LRxVzv zJjv>fk12)h*^=~f8KN#Ky~x;=8?Kly41DbqsYZ4aN0Y8a5vh~q+GB1Z=%j9o)2hKq zJcrbBtGYfY1;+)#>P1J~I>{-a{JbBd;JYad7NRz zvcUaa25GM&*~k-Nx4(@VDdw<8sAAGabq&f%3yKU9lnzSEDH>bq3ebM3K7rD=>7RM{ zq>J9^a{~Td*+|+RBBe7iM48Iw=iI;4> z7WSr~PLAbqXpaL>sqBtLyrNsT%Frvu!Xh(8@ssZKN(WS=cFpw}-~?3kSnFZaejc2E*O zx1o=N6e9FEIBLp+vi4*wa{V4?E4ha85l1T_pfSUCQ-sZD$7}h7(BcGbok6={OT|^A z9n2}>!#*Ss(COCaju-nLJ}Fj_5Q7lir-G_eRuEcphI%dw5U!Z!;|W6OUi#iIpFfVh zTG)@3LsM38;UWA9K6Wg^SS3{UPRHz^=mw zbZihnmHS>BxBU(Z;wdH%h=(8X?{CZYe}A{N$QxS!6uHz0d#AHLLXnZ4w-jW=HxYux ziH0cbU?s!Q^az+&++W|_;8T_P^PX~3WYFH&@MJf{Gikp4*l}d)pc2*#y0R%yp|7za z5OPJJ>#4}3w0oF!mz~`cEpmmpO0>xw5G$8cRI_HG5784rXl%*vpIi3GguQX~`1?!f z-qGZ4-q|Ram+C;E%*eTdpDBaoNLnNY$LmDETN^Y$_8NkwOo`4OpN@b!@I&|o{*9B~ z85p5#whYsV{ozFYG=~XOj8{#bu2FTEwK~4imu+pB>eRG0?YogrQI0^!FQS!Jg4H)L zhoE@0*R*!)wQx?zofgG2ycZ&9wPmf8VC7~#vH@k2;;xAh$t-Uu$?aZ}wekFU7xowM zH}W5S8`e?2^e*JfF&jR~YxxLfja2~8lnzhzG2%}`hmVY{Pid=~)5wyFr`<8j&PNB_ z@P3+49|1QUj2q86gs!0q2tXq!`m3-b8m1LUo4bW$! z^0E=#4Lat3;{bq1_)mKJoNI0ZJQf7hF9Wx&ufE}@)BZ%Z8vk`k1Hb`#6XH@&gAaSe z>m&@SZW?;+V7)3U`malc+BsJenOL?lEn>CgQ@`am@l1=%BK@6;GVGH?p5Ebx%4VUO z5QQlp)zpvsB5@AT&y=?QCa&$E*?UP7cChM-Zt7n8+!F5Fg{pdiSWNB1l$_-&|)>*kqlmGvfAX-V9cG?}$7kPtco+Bz*4{IxrvGABZs zn$do&J~bWmt=uSE9Rm+ueJ|+M0O|UG^ICHf^6#OV8t15E&;gmd$H*aZ;zd+Tfo$wr zX#{Z|gfRSY!=-LI=*fk(bS1sX&~@RE_^N_7d9elw0(IwG-UNH}P-UD-4XfH$Zp#u^ zt96H`;&35~e-v*u zvnyP0K5D6fmq3UMdw@Cd>SdJ{y8|^}xNEvZ5^s8dcqa9WI4=79;qO2G{(A+WH{TAO zl9$sX9MXOc8$7LIMGGkO5dxDRd$9+H8%|fkx2zYFs@OlF#Ro9H+(wSRsU5tYs+qK6 z*FRTi^M2@d5iO?u(gi}_IXr{frRk}_7dZE|2A@B8qt-vk{iMmUl&z>mH)(-HQCzDz z>R@tcR_2cmgs2bwHB;)zzattPjJx30C{7{GN$~xj+L}H|p8@mnp^Ep_dSH^$9b8?{ z#PcUA)4x=-yXpp|&r0Ui#((=@F?U_)b5;u5;K|qZghY%WI)I`fdmLCIcb`F-9e;1) zIs616sI}WV^kv{h$sBkyZA2GXlf3p`6S58cS0-H5R7CStpht+Qxm3U%74ni*=N5$BuzjO__Eh!lODMOI76$G zeu9V$w|46B!l#A(mNVU2THH+cKj&<_a$wEia|K@{qt&~J3!BSoRT3jslblGVSp4P7 zOzOww_n@GlhTt)ZyUL`Y3uzlW5AboQ<_-#Mj<3sL55bs>Ll~?Xr5vBMTo@>OPz&(; zwa8%<(D}t0f9f5G5}Jmd7V3;^#*LURnlm|e-4l84y6-WN{(SjUkw@JoE-C~^7bIsX zes@AdSbGQ|o$)2fHI_4EiAR7xi`Ch{#da zq(FN~Xm@hjq6WiG z4XgJ6qf?VN{W?vdS>&54%j++1nq+Y+9rSokCBO#}UObcrA9@*zHYEAv-Ed0-1d5X$1fcH4LqymlMXW|JUXyv z!iPo@A3>xw7F$S38un3?k_W#yF>vCPS3MKtKDg2c*kc%gB1M?+-;kE1OowW>*j&(@ zA{RC^TE|(Gk2ivt>l)xlSOA23A((6?N3`w*Ec|C5prhIis&gw>oa$FceC3{)^pDe$ zSQSu>3``Y|OLBSEj#|~go(V?xXE#8nsNwNA+Yi*MUQX(xzwxsmXFRU=EQ857aTPA} zG6W2-+Ww>&e$}UjBwn@9wR zcG-IX&5gsR@jg5rXg{^_kF=&S#62LwLET3e3k__j%Pt3>pUtV26)MexR|~Zc{o)H&9puSO#qkz9Ix2METc)yw%q$jiodL|I4ecX{ z=@On=4Gsau4j`MpjJV5tJA>29ndxqT5ak7_*r9Q(Co{Atu1)0iv-dcheRN#w92^Bo z&RJ*Lvk?+9>LkcvUcp@>yqF1Q)V(@%RNKL}6x$xrCr&W;n5DtBF;^?{TmXLM9ZFwF zCjF^()t|J5xR2!WMa{1vYwz~r)HOzLo7FNS6H>}EN4R8>b)J4J14)*=FxH*hUsMa_ zeWgQbKc7*?tw1m*f%@|APY;vCCzek?>|J_`B;9CmykBZZw$LE!IAkyHZcoaYjh(oC zBT~jCAm#X)laSR7(eHVo#nB0QTMpnd(uxqWXzeDX?NCe#rbAyl@?uKfJ%crTvdBG96`7g}>#kS5wX&2nV6P3nJ{FW<2<(VSEJ#3xL-}CXZaS_|8wXPT_1<6K-Vfy22{w1? zlFa*GoV{gORPPf%tcU_CQX(MT(vnMqfUvaE-LTT#C5qDB>;ftX(%mIUr+~1qupkY> zf;3A$XTN^qcRkPZfAja+7v~&~_qk(c?wPq~=CjT~^767VDp1L59Yl}(b^1+0L~<}Y zpeZWl_xLhs0SIu`YPO62fNQGsQB$oozaW%A*o>CvdD}F`NAKTI;=F-X8@j;HfDT)1 zpC!e_ZU2P&^&bh*laBPfkH#U+iMe5VNaF-ILXO0`-^||o;Bdk}>Qzq*c&@ztX*W}Q z1%CVLp|-qUZ1^Il2L0>zVu){Fa}BC$_(hi|0JaDmB*xSj-!@*fV>r)enl?Yhv>~EC z(|U3^zFeUHF49_NVGEc__QO=Ci6--Ojwx;&`(ue+{@CA=C)<`NAky(vqG0e>w57@N zR+KOGmhJgHiN(35$pn+OR`AasGg4%<=Yoa;#gKa6Mn5@E9#b3#!bQ(yKgjT&3Gu}R z8t@Sku$_{bTnK=7dTASffa3Dfav<)v+4g||Fa6~noOizLMqi|R7B@~_VuAr8S(Igg z+Rfp97GEuvN&tS@AUytlu3BfRNqk0t1ckjTf+8;6n<1a zp5$np=BQE3Q|L<&LM>mynmrC>@BC8>!1J0VFAqxP8P2N05t{v7>Qa16SuU0-Nh076NqqmgN~B?hDzv_ zybBZadbRp_`Q$h8)VFO}o-E@J(i$6CDx3RxD{?$M?L%#}q9Z}aXvbiA{^sp*p-qV) z{_G#YaRM~Uq*(LEi95mmif5X$f_M@|o9!1-WLVkeQEN$3583CurHE>=zr4fz+si@>j zYKo&`2J%#LeLUU%9Ak@P3b*%?#LK2#Lyi!17XJRWs}V^yVJkaLM_a}NWiGb$Be%^( z#D=Y@Ey`3jiR=7^4bFeO6R_Csycb(tji|@%U(_6J0EKUnk=HycV}@24mceU_duGhuFAs>W&C&0J3(tsXYyK!3p)IXja%J zD-cj!`0?cTQFiQeucRL8rOt}_d*3Oz$CDD1Iz`y{jpxq^8M7B(%xO+i(FXJN`5m8i z=v-AJ9@x9Q&hk?t;n-z{g#{caZ=jX?UlCX2xf7v(=k7kma~Lqv1X9v)76?9noXyED zw5m^w4w_B+#@}*ra&OdxbS=c5L2$QWi;LrD#Lx4cHaey*Hvh|6=ZWnj&^b1RADY?G z(KKz{xH%BDS{D2}d6$=dOl(ebe$;nnT`3#;L149Uk9)kv&it~Ny5#lF(kWQ1`<+J> zYs03!$~d)e&h}-FBK?FW3@wuXyfxk?A9QG;KF-g|^mPXN1}O1IaiHVNvkMFLDcwDd z-F`*IMZbjL_)j~)p|St!QMSD8wgT<1he8kJve#L!gCxF@eAP9%lxdI*>>-diyaAQ4 zf2LbaDU4H!5a|cb(Y!yr$Wt~zjHm$jte7itgc$-BnbM>+q$G3db^un`$)B0|pWM~m>vY9?o0S(BCra>0lsq6&2{F>u(%r;Umw|8;xLo!JwYNEAszPhR}JQ97zoJ50B^RXzo(+WPIMiC-OdircG4^u#&2~PKIjP_JUc21 z8y{kB+2ytHL^d5|6KDOxTgA(UmD=K8_zt{i-|V*-AkLXDvpwyX7TJBpvl{J^y|vmQ zvXK$>LT-cfNbBH^x)NgyTUy{Y?@?*UiEnH&l}VF>HepwuC#7Hs^>|Ns*X?X28kC}y zMjo>Sm-6PyK+5rmMi;%rCYkD|OyYSa=;rxsUVq24``mgJL(i?U;$iZS-G*JW?-yVn z8SV09{k)cyr(MIURLi;);uuqzaUyO59D(>%d#}_x6MuY$odThLJ{g-*4jrAJpGl@2 zxCcMskIj1bYyD25|gmuJ6 z(G~867dd2o@bwN^MH0*C-a+hvNT#!W;0{~wFpOW_-?z|SPOx{Wn`67+CCM#N(5OLS zmAbzDY~7*`Gn+fF!>RK#ACUNx^twymBRsp2Vb6rEdq&fB$Bp?~KAFn1pGWTOi7m!u zm^|=TBph>L=~s(zRdR)JPY$CQ6!cEq$$T>X5>*e0S5u5Llh)R$1_PWFo2wr*I9X`C zL20^{e@&E}$~ccw7@Z%v7DSQe1IzPP4of1`Q00=FWudSrix zI#~j@uHxt>Pe6?@!hl6=^?5!6uBkAR`P*yHGb2o9q5T)nkFS6y)Wg*Um49?s2Tat{ zKXuZ8#-=@imH;5TUCfziNERUHTdTVc{ebHW4ERj@XnapS#wzkoPBtNfW4Ole%<}-l zB!rkyEz6)t&$oYA#uszUO0c*!4&1t8#y0dWFO`39gSF-&t| z+4CHKoazf0CH#b9{1g+9B#r$E1Cbywn%x7~V1$mqtGSLn0wzFzP=MWrNuHqP!aTIj z7Z?%8>`Dcvp00m(rGLf_bRIL72F$?W6Xj4K)3VPR7-i#qqci|^qwk-o?86{@G-4a1 zMK}Q$V-mrSTmOot`dWu^utMXq|6pwph9CjhfL5`?L!cMHgoywzi}fm(0}Io4jqPRt zcAhq?Gym2zEX~Bqs^_+EL$FD}P=Qh1yeU7b5fT6w%jT(`aevKOJLb-N#}k8x3jF>z zij;v6_{`sNaFsH2&7mH4MKh74l&Bo-&3y`@)}YpzmPT74`>8bGVX4 zXKDox!4-K-)e^_x3ar}}@5*)kA2zvwzoIk00?9VmhlpCr%e0wsW=h8qn810FdJ+CLi?Jk6M*W!1 z5aOzotlUDU%HfT6k)4iTIkx>g-`HaTaMhdJBqe&T{hKI~9~=z87Z{liHL>e}^j1Gg zm%~3usM0@xc(&LxwjcPIa5f-N4MWgqA2$I3VCB*=C;IN1MU=!L4XhRXK(=3Nz>K`% zTKgkTaP>lO!OV|-%2Lxb0Yf2)^A|MJd>utP>J_Q1Oa{XSiaL2;27ir5D5*hcm(s

H${VyJe<1B3~nyCdET6yyP@n{ELU#do5acN0^3b^)q;b9K8)Fas#7Rlves(Rez?u3MVF)hJe_XuF zharxbfXF*k5`XLm!XsevbA#@B-ukoN=yZU!B(tgTRe`Ro0iWxgOaAp&B)nhHv`hffb&?)hxi&WF*7pySJJ6`QA*`s*NT~ zfx)P{W@&G=E!qO6kN>HoAJ6N+m`$g^DRF#U|7K)$FTgVnou19jK=hFxykXP$&v3?` z(J|zm6jsEg@E9_S-YNYHdI0#abTT1WS-Er{R zbylsHtqrdOXL!aW{kfN~8HcW4E76)wot4Om9UWSUeXvPnW?jGLwGaJ2XNrEUTIF|` zYd9&@8~X&MnQ#V3ai8_(RrR-?nwZqgCf*AbB{e{TIP#9>RDXUM@pTP5mD|)RjB339 zm{Wf^=ethg@aBd(X42y&0E(&(%N+sY+T(+9>GIZxjU1(7jGSp((=3*8p6^~?iybCo zH?Qshh;~eDS;0DbJ27%Hq9=M=N-r_Bi6dFnWigrW0B>=JOxi!1g^4iMor|_&m}3|3 z_wMH{_~#iZ4k7aEj@mw&ew{o$rFjAsM$G#UZq_9+>2=>#&|B>M+__tSa7W?~9&N=v zj1;?>Igja7IbMlTwq2lqSslT=5cJSkqm5=O_I_;Jc>O#hTPtIU1xgUGX@qi{a;Pw1 zFpPSh8h>pUfAtC20GXsk&vH^I9roVT);Xybp&E6cU2FFdKdhTmO!Nb=rv4)AaA{7! zK#J|wpOlD@z980X_R2llt)Hi9v3<)0r4hR>;9>Z@^+R<((sWO(ea~y1czjQ2xoH8Q zTl!Yz=|dpf|IgQIE(8Cs7;hT82T(|!DznBIuFx5?^hTio2wZr_iYNnX|0G=_{0Ia;% zd+DOVjhDGX)0za%6}*A3E{UNEmr2Ci{bYCbR@ozp&Pbt}Ei=Z7VCVO;!Gs|t7|}WW zJnoOg`ZN9&3{=(JYH9JGiebRR|BW{>Q^qPR&HipBDu?y<|eb{vyc+!w=gUrM2;tYw| z$+^DZA9iZBF*fSk=#w+qlS?#qm%XX17$N>C=kK^r?UQ5_hFGZ!)&45;`bTCk{4cTm znIJ+C@Y=FXk!LOgVG{OK$;_*hxylhg$(%Zc5USLJS4GHd+VXH${eEj(5D8o zbsbauICXyq$kQ^jsplBk{?D%t(BS;UULV%{ODjg0_qR5I+St-sBw%+OiGb-lTi-nb zwHA8I9?-BM17AEVHqw{()1_EDIZ^zh3+-bD9KehJIP{-p0NH@?VmFv#Vg0+X75IQm zoqe5KfZ=GtklO56$!4Sh<%#z8Nz6P#&gj_Z6VgZd+2_3aJ5L5^)8b?I@qYYv$2dB7 zT&A@D?J{st2Sh>m%?2F)IYGt<(Ev=ZchPWUlynX82k*m*kCfY=gjE$3)*MGKhfS`Y zbU%<{5ZR9p>cN1-k!PwPl}0ezsz{w^^?!X1{~8OlGw-V7_xYcP(ia#9e7gvoI!c<8 zP;XbeY4lZfPY*%(f`^9{4S^(mhuWIyLsTaXOL zDS{Oawr#f?G4ZVM7h5uaQ^#L3I}1P|w&Dx>DgCpkzy=9)uR`Rc)r7L_P z^NR7YgnqFK>o-S_Up(1YxQxaiCiC(oG{wL$dTDilr`P|oB{e1!z!G-I{?EgZQzn4V za}LUyABDVP`Taf69`zPy;uHFjo7MI%foi3EOiJPiQG>6C2H8*m=ILT*Hs-7hWr1sb8PQCL zy5*=K(C5bY24ujd{I5)!z5^_%l{y}l7HtwnUY1I3>zZ1hur2--3i zWgL-fd@s^c9QtJ|@#r1ENx3fL0xNSEljMBJ6DU&uZ^I#6z$`lV%fg#XgWJ_gS;`y>1v@Wd95%u=~ zzj6bc#Qbv?KLGkqx{QRJ@6}u5DL!Xlc(c7Fi+gxedA^C%9xk6ynj&LL$>}q|Ri#;~Yl z7CHWZv}g*f$OzfQhi4d}ej@}xV65DfT4`I6=t~+S5KpiO`=N*s7+?nUX@=`spO={_ zGaO?@)`VZdo7p*~^`LCU+S~2Ue#&JREFBVujovJXK!QRC@3I@Ci&4NzJT=Rb6v7CI z9`Rq?|B3)PIs`yx3g`Fj{zGsT!FYjKH-F6m6g{K(L4MqBHhu8sX7ZBF`dovr>6)$P zM9D1cmgCUqJda++!dt~IM) z7DpV0Ac%a7g_?j11$cn%-`*n(;}8}D%wXwh<7xUY8_i%U{D?jIMFl)*d`8C;>XDIY z17ApTfMh3CZ9b9;aL$r&*DWf|Y~G|Vo)_rY@p&?nDR7iIb4_!Ctet9VPfp!x%~RGn zkQ~>XR1oDO7`xE?zvg4YbaA#x1Gquj7T#tgKJj)PPEyHa#HNg2W!h%YeuC%JG64UC z0RNn&Rj->EIaN23I{zW+KRW1De#PNU#Of=27B>mV4rK{Q84GbC9y01EiNeqXOUQ2ftXWoOX?;wi;mz5*seHvcJRJkNO6?(7 z-2SYWHbRcmYqw@j!0KQrm;+ZV8Yq_nkwMHVoX{A4ErOqxuOB%r!DkP`0n(!hfm`Qd z@Ebjb)8zk$E-Nu$KROVdlRrigur%@17{%c2rx5^zH+}+pKFBgl!qwNV?B3?kNs7vE z;W3AAMZ-BFfM`derK_mNeoN5@ZpGN6qI4%XJyC1r!<$mfq)+|*UqlKz?JwxLon-

MJYu5aIh{P7!*oT*BOVh6qm-j_@{d@l_CtLl?ON4_yoQEGiCM=R zog%G5y8Db(PcMQeR|nsMjVdjkr^2~je0ZJ0V>+*t{Df#_Zz1>^07xqx+^-c6f5C0i z(vZTTI}-Vbt7#Ix*HvXbxD7=8)d4RdA4nX2{~cAic6>7|_zK<2qMB(%%As@L0>(R( zBejq!meY6X>}(XSZxWaOyyAd^X9wcHJhZb8FEgfG+Y6%&s`&OmYzROzwkmz@&9BEZ>+P!VovM}@r#R{{7OcJ1VFRuepk!p-d>`~bgvt>AS6u4-R&GwLMwuIEap!q)N-?hz z)%2(IxK=B!a$tCoHju4z;c`t7dLG&vZ`^))3_U{4!t+(3kFee3bQJDHzZShZT}HhI z5Qj{I(A{n4JI!>7=<7xp)MO0Izh~8eFpVV(o6wF4j zW|Q}%l6>MAjDq+OKF};stL>!?oNesi5sR(`eF8$#4cg1kvES+=)O2UtfY0_ji!Z zVQ5JJOT9Gc^31$iJ}8q>(hxXZbsxGDb_dXSRfz-I@>Mb{-r^8E$l;%|oh;IJ57@w6 zym{-+G!Q)fP$&lG(uoJvvsv$Md;pa>mHcAd>~)&0q^9O;sk5yaHL+hXyXxdbLC5+dfKBEYO1J*w?$@{ufYdpx+t?5x3U|WF zyGP`53+F)%kflPw5N5?ALs8i6o=1>i2!<=Au)m|E;k5|$+?f+$Dk2bBA>`00nYN(= zL*$u`SNfCQdN6&C2*~1xs1eSzwZ?{F>a=x}2z?`qFMvT^XiFzDMF_B3_C?~X>-8Ap@1f}(CKU`x#o*IsH!-#Xah zIz`t6uP|WBXd++rn@yx+HfLJSO7%0*cF1V<;<`R0%No~H$e(W7|8RpS)TP-A6|Kr5 z5=a+`hV2`>b`dF%Lmzx;h)3cO)67T)oc^wO_O3>P%~q(4uIu{ZV6`TH}&?f5|oULiQLpyTpL!cF38byHf;l#EDdtm1`E=X5iP)5 zpGPz2xyRL(J?zG4pg#Ko9{(wx;q(~2Tp*)~l&DYcwd4>O%F}kr0N$7?HN@$N`u^+* zeO$BW)}x?oKn~I0jt0x~d2Ws~_gQt3T?X^h=N7X+Q zPjV@H@ll4bu_g7yq1Z@J#(yZC_jonU^p5L1z>UB8murc-^PEMVEDoZd7)GBy7v8_F z^`#Q&SqA$Kyyllo>`&M_@aq{=pMNV5cCQ_5wO$i%Bkr<%7M&vCyTV&Wz|+$!eClrH zP%-KQWO7;3H0bWUJzu|UiF5Ca@?Uu@{(wyHThs~vI*|zs>PfQLeKg(jwZq?+)^d$1 z!PR{@TEU93Ymld%ig+)teb)rR0w3faetDyZc6u4OD%tKgkRkgy^kIf0Kx;>cO( zhg%`A+>$B$^^pdrp980QAgZ}r_Mz~-nRmSH>w+z*y97#O-zwZz2Noq-vi(PX{ha3u zy3=?PZD|$_gPK+>`Bg(kACQuqs@VZjA)Rs{kzc4RuEK^9A9X|62X^vY(oj5gl1kp> z)_PxUU2Pdq!OER`E%Bhji*FxtKjAH}+in8yKBOmp&p)b{VGD=*!lF#rZ1kr6Jjsj} z5zS%nZ^`Us32_4No}T3rwzA>r1{QmcsyYgO%O%#)y(IX)`1)diD4=WZgF-HJs?J}p z;dy8YUyMa=^? zSQmq<`^;O8W2VJiBFuj$)9(l8RikA@v;NzX0TJT>qyirb{oG(93U|ZmGfx}=-|6DR zvtF@WkrtwREp>UQS!~kUL|>9H+Lu#i-28sQdwZG}yxQkqcSM3GlbDb=8@@52E)|#* zJ~wsFFgh0ZC_|ONmUx=Wpk`X8?mH+o`H3a#;$yaEAlEfGbjz*0m&!dlVOxHVE_~i+ zIfm|)sK*8&0PK+KBLV-&30jwNn=I61H6rWpwRdBuSCyeoP;kqv+Q6aqc=5zvr6`@R z3;gNwc$SCBbQ3@N1EaZ0gv*MloB_iDq1PPF$*th*FzR)=EBZ9WDxf4Z$caix+g(zL z?%?!#rkOx^xajO^8G;b<(`S49tiw#X>%GNuRV|h1$Nmwox@i2Pu2er&azwOB6F(=h zWZ-3~i~m9-sPix;^6|Ylx1X79I%LeuTnFaNRNr6T#{3&P7z*GiH}}e3pLY*hKM*_F z**<7&cbC9P51ka+Td9t$Zv#+!Wu*2K;!2Dpe}@ogee_(WTxj6FF00Besk+|`ktO+{ zS~0-9XYH_-V)W&{uJx|xV6WjCa(u$-)B5#N*}nFwPtwQZTB>Rhm4<;_p)NX|fG&=O zo{tt&0hQ4$dox-O4Ao3%i{5K1kc_Wqd7EU-x|R7sUkB~_FBrZPP%Nb#ed^74E5QlR z`2vbt5;OW+>V9`I{yK3;bQ&bVl7--m4sR629)Nr*QzZ1P%+}#)*T7X?E>vzse;&od zqHH}_D&#QYdhj(UZ)w;$=s=Vf78g_67=r?2vbJT-HKNwuo@ND$=ls|D;e>j*h;W(V zquEA?%G#9ij$2x$?BLjz=Jtr`0h#5pBUGw>PwKcbuCy`9)cyNhEmJ+O@UBr<4Nu%! zJ}KVeqBvdFsJS+C9)U7Y-2W&TXTdK3IFqTUSnH5!c-Kt6?-?jo&jnY12u^ zge}JvG0+YV4eEbhvd!d_xLaRh+ll$oO3B zr!B9xUs;y4tUE5Rk}c@X(Spajgy{hRVriJV=^BwVEgotrC3>SbCNtvyvUEO~b7EJBw zd1Y7$nk=EZd4gP1*wusflZs*VZ2eT@@l-u;eCYdesV0}skkm4nDiaF@l1GJ2hafhq zk`=N&rKI;Bkk$?&>$$&*HShM@(sI^I)M zW-vC?wT}m{a7iO5oKNKFzS;S&TeKQuF*r*s>HSLRu{tOrr)sJ5(k^m0$UEgVLEwh$ z7L5MT(ez@8Z0mv*?!r3Pr=eWdY~HaKN;TERs=ux`ge%5LC94EPPVJ zN9*nw70iX3J!pE+AkwXOv@4H`dNtuWK*di()fJn7wvH7waT>B+Pl1vKh`>vJ|75{( zH)o-DZ2NT%@Tq&siQ6l+46&6O*X3nF%ZIs?L0v5J>%|BC-k=b|?R|@@rjLCwL}dg^ zKklG+47NnWSFg{5ugeFVTZSn?*djXIvq$d(dS8}|i0w6v3=~hh5S6#{7*QUs!VcP? z4_Ev}#O*!|&jb*J1Tp_ckH)01Qh^XzTTvh^zOxY42dM>;mU-vr&KBMHWAS6Vep|25 z8|S@)lkJ?=0Tz4l&+mDBF?3ksXgAV6p7AytvjF!V$kNI91qtV;Fsps#2_YI+7VoDp z`5$Ju2{3~sSVQK1hzKDay6-+#)OUuj2DeKh&BnXim1pIf;`vq{(yLCzGgv(*(RVaG zkN42D-UH5;-D0g6ptu4Sc1=cm0=CaaZ~U25}0yggt6$u-`%!lj5%-$BE94Vt4b z3fgC1R_zq&oF3m zkO_b2mKM)AtR}jd_ZX@KG3|QjJJ|(y&pv?pSxOI*vK{w;+A8nrChA+WzjV6aqspF` zzLw^*x-rB*%1IFP`)#pwQgD@4t%NNH+1iJ>nY3^+D3807kPM=sU+dC;z6yGy%Z$^f zWtn>S3k+k<8?gi}kWTcbJN}AYh<0fC7hitEI|ZC16w@EQT{oLfURs zJU3YCJCC4?jj(kc5b0MI_A?QZkK1wr)00LRIHu3;|I8-vDij%%DK1kV_ir;4yk0oK;rSSrARP-&Ta$wMVkCI=?L~=R8U})FXJ6V~m>^AmZm(IZm>4*fRh8$^gPY z6BXW<#pR^HT6tjp?1GR4n`BHOHl8AQk1W_Vi(P*F*==55aOdSWsSDZCSK9jE>DrhN z;w{DF{vG#BUYMS^&w4!vlQ6L#^l73<-lG~TN-vL*d?QPY-P#JoGF_3@K6u;=8?ITe zHIWJ%@#Q_rLWy5OsTx09j5oxDfEgS6omv7=U~rPklFre_`3gS&r??e*R>dc8R0HHb z4}h1dxzadn%IgREd!?@Sv~40)yK5S>{EK~<;=^l>9b6JKw}C<@J--NO_o1&D*=v=- z6l9g5Z}+IZrp>i~B^azEDVZ;wGV}Nf?r*-Ktva}(V@hf8koA=o-k%8Ep znE1K?aiaA*_!{W~OeU+cRL;TYv&DxFpJv;H+*KWdg2tjuw7OwXi7pTtsBV*~>@*dB z>l3o&)&3M!iqz<&WW8ZNv;x$=>Z(9GzR$r8Vy~fm)TbhY5dRhznoP3Hl)cBGJ?zN` zPrU3=R5#ler~o(^F2ZSW)N*ND4#O$q zm?tSdm3Y(9ptWkhfdBBcaj|EZsjK;NC49)Mr7=1Ly*0-Q=dGe@cQ5b$vfw~Zh}Ek4 zGm@h&c@|aw(SgDgCJdi%NnXD|yZCN=Q>eTB!uoJlj3Ur&x9^qi{I^)@Cpi}ukk8de z5&*%sshi)aAjD?KBYWd^h8sfo?{At2_$xKhz&ZW*9BkZs7H>jdQY$?rRKMa<(jn1a ziHgb7oJ2!{k0IJ##N)9?kI{*MKFWPaQVV6&7evbM6BhJ5 zYY-ACLg<#{-G3%qr!NmbXCkPSJ&Vum`5DDjW&X^KNNZ(5GkZUo`mXI8{aS8cYuouc zTg`>gLZ5KM!L7)+Q%2uD>B;O+qI^{_$&2}VBO%)jiG7t6_QGN%?az7a@|THifDsdr z5`LCuiiO~tJ=5G&;Y^h2sTO?Y!d&Feklm5`KCo8qc;fI!}Ps z!G|clJYbchn5q6@HU1V$*AZ7-k91_BF@k9u0VC$gfV832z{SzMFBbALczk)egO5c& zDs+hiK|*VUD_+Sob(@>`l-0s{ol?H5rcy$ok1I4Cw^(p2vsyBuQ2DoZBlJDF6G}eK zooek7zbP^wR@fbV4u;Yel|$o&oNJU3O?#bdkALRh9-JVV9Ki!Q5hkN-Ztpibu9Q)d zgYzFS%c zC4MZ*F|HmWfj_(?S>VUB<-itJFp`CNJI%dXuY=wUH(9Pb6nx-h^;E|K7VSw>TUz?{ zXFj><5_)c3(zNZUePOffP|(`t)dwif+tm+m35v$yA}bex@aB1K=e5eE*Hl#VNIgac zC-JAwHL~)>OLcs251Ji)(r3#YN1mZwxoX;lqHW#E`hpH7?Fh~^wUJIku9sfbG4AR) z*zM53IhXNNUhjF~0;KqoAn7=QerUC`0XbdKYVQ&ywg5Pithx>kheajkZa<9HHX!90SxmF3g-X}tKz0aAgvUO}A0?piS0rT(61G%xC|ltp?n z19`tr%Df!WjKU5fH#={?w(?}6co8n^$+No@&=c?;wKkY!fQgt_S+q_Sx4bw$9al(z;u!J<1b|9^Bg6kNNB??5oM^9N@M|mFPV_8gmoKH&O?a zlsl29tJ9z~&j zinSZeZ?{X(JC?mtPH7?6dH}6n%Nq7I3nDz%i@$DLnF%AcW65ju}kKJN(L9;Ac5@($K2Yq`ke6X1KHv&%bP zTN|7eCf7WdxW!aOMOj}rY`6}iBpo6PKoTwsg1S`ZU5E}`k#>&|0;9OLlT#y>@VUB( z1^mY&lEo7buBO8di_EQ=fx@suL!P(%tH|wno@d?eHxAa#Ri_kEukU@=SwMbMw$S zC6c*WeCheyRUT9R%BtQL@Ax}p$$$y^W=RclsYEB!WXhk`@Skd8W=jObh8duTUdfp8 z-5gw~vuk0M+>6leA!HSj`6h4orH_$a>$$;Mh6#)b+cd|^n8*BPE+ z&*MTB8yK4kT@ux$hO!iDvlR=oyy#cNf-y0Uf|dA`%J2l-W~-BD_lJ%(8`~u4x$ekh zQaQ;yzQ-^=Opxtf!tj{VO~38w(*iK!5znSdKw?txK5MYX477PAdpbgJ=^?)eJzswn zOCFx5GBMN{mC=r<%VCCTcQ;kaQ1WYo0o}Pd<12Y!t^1b;dFQm|uja#{RDz&6pAY-V zKUwVXq?CCrt%4HM3Se$Zt5#|TGRS;Cy^)xXhJ5ZBiCUS=hOPhwnM|W8ZhEB`gTc)# z;myZb=i)u7iiKiOr)*N@-0(^F2nYi}ww;>(b6-|Ip6LgQY2@Oix$S00{r zBa1(tO$$OWawEkXWKGywv}O42&>>XdW!uh@^5E@t(|OWVhcC)ryY*hy^;RbXelZS~ zjIe(DgXxPGS=)ZEXb890cxO=WDL?_?zQ0&()=MRg!+>oAj(jm8L=^#9cKa6kD*%4O z(nB^T2l;Th=f-+HrOi{<*7T-Eo6LHrV?tVbN7KFMVD--_IkF#4@Gb^%6b7ScgOHT@ zUfw^7a&rzK-&W1zT6P9R&T7;9@>OTaR%p-r^n3@4L1|GV^H-7w)YoS9!Xt)~qDDLJ z7v;TT3xS_ok?Md^c*3tnp#1u^DUBw5D>iWk{l5;9Q0W|!@c5krY?cec^pG2h1q`Da zEh|Zo@Wg1LYZhiDtx=+sF6K(b_ke@M<%`kGq@wfDa{EQ~6%fx?90n z<&i>Xu?Z??Ih5K}JhJ9$yQ}Y%& zjJZ)hAj#F~&Z{{*1LX>m-qdZDiq&vBlJ-D6(MrNttJ=y0k9|O2*|FjjQF}bA`@D`B zHk;V%1BI;NFXrD(4zJd)@&~fSg&on^nFlP=!&1cGVb#gL#dVUv*+>*~39kmds$|Zr zc17DNmvf;=?{iOn6F||AvSUaX>@z+!9j@-)p>$(8Snkn!l3W8B-z_Moo#wYB^?=f>FF^KmzGNi-L~WcAGjyg(Ri<4ZS$;<+xWSpC*UG`?YTFXW2( zcjIU*#+A|Z;a0;rEq*en4LQt30+QHKSqI4VmG5PaGk5#N!qyc{Ex+UTcH7&mFv+cP zZKS8$`Z98+t?GJ*^(lzHwa`#5XhOgfeGBQv>_6uL)OeziF$=*vUEM9>==sG{Bm3=b zHxj6YNZ{Qb%Hu+}$^D->C}XBiLYD_Jnh5;v*Wbg}WZSY`eH~dfdQ-p6L0>)ceo#Ll zoos~ko5Uv!k`eOzZ#eg8&?;XO!`MX}*~PUH337SFzJk7tFZ)a;Q&a_fbHEPDdx?DP zsfN&`xSTV{{tM~D zf2G0pX*NIcB?)-6eD3VmyVeOl%%wHXIal&ZsAdn0pb`fgpXF@%rA_~j@aqUd3aA+ zhHj0UUMY&9JEFo*N*o)RoFm5Sn8aKmGw!_haSc_AazBfN>#6qeSYa=$GhO?mgu0mG zjvYmg+ZuC&KP7swtDt>zUCYFKeT>Gb7j0wOLYbyK8s% z8eFj;OR#`|eq|Gl+v0d%G7Y+$gtKzah@%>JjrgUa$;d>0y!SN=ZtQ*gr5DkrBT}(B zK}9dOikLQ_9MJ^bApE%oJ$N=ZBGUQj7PQDRAi|ThP0oH6!S{Pazqet&@ADpcZltq_ z>-=;;{imDqK9=@0eY`sR9CtwPUa4C*z_VD_l3g2hL?FCwYVil;_PwrM{3EC7ptH^? zBhskARoE9#k~{Ki3FHWy9irv3Kqn)5uil=zWDXwW53ZTk!XU5u>m!}i#e@ijyX3|8 zX#-B6UE%eolXd7aJA{u>?p*ZiLhbuIfC)Jj>3ErmbLN@#ZFrc(&B}z*yIKEB_jKDJ z#E`2~+-bB=i0AjCx9&ZX`)_mX`MB58?IV4yocdbHVf?7E8)Y#wfIs6bO8TT&-FGP$ zl<+koO0tU!;t(WULz5C`#(*Tn5>^(Ro+1E0=m1VIcFJZ_NtU zhDVdq68hn;&19w+!r}sEGuAsnl{&_}eZLdtwN~4IqDd=uZrEQb|V|mQz_|U$pFfn?mK2F>Z+2*E__qe<+ z0vz4{qGj&Y2fL{NkTdKaqNkf>s(&jh z{}MTGUq*YnK?^~N&QrPbzd3j>egfh1ssmg#AR$o`=ec6iasT^iwP7Cc7*Y}$L=4Yb z1|=D;=du9JdfOI$eyG3hN>pqKy-_|L&JYZLk9P#Ds-p z%!&DD+7j+2GEz7OI7s?ejTw3a=-`}m)@g(rmRMGJo4Ie|Di}|3A9seAXuVXDBzh8> zaoPV^yN>+<>pf=j?PWdUxGuVCguF|<0{gz!X+m`AKs|~d=}jCar@^ayhs0Cp&4hoO z)>FIk2bz4?fW^wF|60`cvyJYAhW}ja`WqdsIX>-%>rQhKE1r(>O9K zey`IXLvT~5vB>Sys_C^9{qxKO<*qM9<`*l{l3mg=77>CU*8)*d{qo~ko>ThTRz)wI zKm>iodRh*}xR0v${1=3^3e`t)0u|YyP`vPGyClAF=-RD2Sg5m^>EDcSTrfIG*FE{`qqi4Jp%OQDAi+JOXfwvGe(`12 zTId(2<;2y zZ4MAZzB_1rXi;`8V>|onm|3bM-AlumXHGCyr~BV?4kpE2++Xt+N~Z>2rk}X2wLHD9 zWU7gYNv>-wOV4%k;Kix2HEHlNGpA9_F4hrnX(314y#+W`0@G;`9@)i+sj{HxLSyLf zcv%gEUi5?rCu`5b{`Lj$Be(|X`u^rcdH`wyGQ09!ggtKLWy)e{=Yph(_s9kSDWqtU zG^UgFbp)0~;y!iswP96pr0N}Tj!7Fbn$4@D*3#R_Ig2#z9C+bP0RKtFL$++34uzk$ zT9^w*ofL2Bcm^+c1ozc3;mUz|A_Qy*o1w2wWf=3kL8~>iSb$&f?_UKY7SXsEL-L92 zhikmk6IOE>mD3#vaVQ-bo*_tgqQk+#6?s&cg?>Vu3(pqWjBgj^9%-bRQ(CC!(4E7$Xa#hQk@}MqT@uYJXaSHj<+Dbd! zb`xkB^3m+d?y)ya$UrP6McCo27CqxrvoJ06U}>y?XV({L-?P}9(>mY7n-aMEnf9{w zlv?4?Hz(bpe73w59%~zYS)yLm5);)Di18B_i)%kt_vV+0GIwh^wS(u(RwDKuw=H$#uXg$KJE9sM#kEoD2G+7` zJJwVp;I2t0j=T}}`)!B{!8<`tjm{!=D8KTUYMLLH&V0AdYb8-|VPE7lwG`5KMFK^h zwp`(K@a2df-F%7wie7mQCU_l|8ZQg7Ivh{N32)E30j{~`O2>1%Z*4(6xzrOqYZB)^ z3wtpcSBDc8F0cl`GNFbeJX*Y{;nONk3;v}9z0+OHu~Rv4gIKC936yHR?JaMVh0S&0 zIYJ?)?PBJIjugH=mNM};Fq0o ziUlKu{nIpp)U*p<;G7(NwB$-O-kP4$^}`)-Ci`y_`KEDMcwrPZCfd$&Xud2lzi6n3#Xv&98u znph_iKlsG}2Snx8Ond+C387#2nF#4y#SgMy{<~ES#RB`pwyx#zH6{n%75!FIaUa9DZLeY9}q7Xt56TdU_gQ>y< z$Rz%M*n7{YCbREtcoas#p$Lpp6_KV$6)BOXG(iLu2}Mc}1jGP=(4+)JP)?`JvIrl#MoOA8HuWKKS)|iIy zug8}7&;k#cp0r&!`A$v%cnK@@FGi-Ex#}NK1{14ln{@IVp8k2tl*`|x6+0R7Bg$VBI&!`I&yb~IqS$TS z@C4iAWX0G69uyu$R$zISNin0eBSPxi0#rze2-L9i1FK?#IdHt0VlvM9(|GgfdWzx>2kGP z?EmhBz$3-|fYB~SSwA^<;uc;Mw=ma{%sg)tO1<~i-+wtHwvIA|$V3tD>k(gh<=DxC ziG{+vyjl_y?2mZ?>uM}`({$ef5+G+}J#YN`+CbINqM2eJwiVaE|NWEwL6ivT)Nr9An8LokDJxrD_`=JzJWkigr@ZdxQ!DE_(v}`3vZnpcep6$iu=kn* zqGC_)5)ppMFmM~*#OEzGNA_#rf|$mz4R#Jr>MSl73>o{Zr?Dl!yYK zO8))*LtVr83Mg+@qPcq>_oKk=ZBxPv8q*-aW!#(=f_{~&X#CXxrw1B04LO`x2Lc#k zJ?s|$_wz<0)H-r&)8jNkBa3(t?+PNO*=fL2xDRI0}b(-v$@_U|ZT{7`Q(=tZVFt%$ZZGzkb5WmY@ zLRcFj$2DCUUimV_%sBR%2h9StQ+Wla{1(T3Z7`$fw7C(JB_g z7ws9NwnHI*Hx>h_mJ_pLbu6}UBG%+#D{B>^RGsCg)rvk1c8*?nNf*NW*&$EA7InkX zPBClWyUX0bwGSqp-T*Nie4iVj*kglvBZY39VGxCoIxk~ej=yB4ZVmhEJRlAR+pu;y z8D2n?)iTC;)O)C*rgq?2{i~lu3hRMoXrL&Wj8O#^mW;o4*)O}DKP{*Bfp$4e%oO5# zGz3Wy^TEbqyJ0@=wcIwV`txI;Uu!Vo5C2WTfg&8P0|}tZ9PGkWn*&-`^4XPXgfE>o zH21VNu5!eLQxWLwwA{I!=XpERHhhSL2^qP{)mq|RYab^y&uQu@7weam=+$p1D3W`BWfvHjr#LjGUq zc!-&gBMMG_W35GmRG!%OywN(fFh|+!$^d)^oKm|O!w{!HG<)>+?Ny}&Qr-7Gl@EzD zfMZTy%h>O>&8`2O6nvS3Lnw#~u7LtfKHafY8_IT zQ%HqH{avLe1JX(ZzR~M*YGXZ3*8M&2=}x}R1IWOXarFkTcjA}DyE*ctzPDZ6^3SVRQHyTv zrB3g%^UMLvhsl4hX{w+G)RFQA-&y<`lf@V_rN_YMzNVAflFePfMi-;MXwd{VWis!5 zzo)3D1H#6^TR5jmCO3SEH>yxQ4lmx6^Ve#we4elmbd|%|DqRxGt8*#$A+(r%+qTXL zFPuiey`HOGr)tS5SV_Q{mu=kH$DCz|6I5`^=JFy#xK+Z$rW0iV6JgVi!+jHgC1gu0 zR11VYCn#Xm0NB22FTgl}s@i{82}>@(H;DA6KS%|7BX;5E8^{KapZ+<>zja`v9@2`K{jV8jOuB8*xQbF$@c z{|UTCgT~|6bpF=b7V~Wp*7o)V1?Kf$>P(m`J!%?NRtQLyqt<>KS|(AKjK&d$`y8)l zWno-C%h+E}k#T$N)zX@tB9kze?*N>5p9!9LkK$q@sfP@;n%D15yO&JXkZO7yf;t;W zYRWP;`wdpW0OV}q6qG-xY5+mpZzkJ54UEM6yRzlUfS16)57#HZZ@mBjAH&nNLfLt{ z-kWMBoqfL2=03z#yNNff_Sacc{npZh%p2n>&eF%>r!7jjUd{l`uV$YHU?hupKNRQ0 zDXj?uk51!HASeF9@+V&81%O}Iz8t<&C-b)rv?N)+d|zD|z}`u$r-4fHBLAmb%%@$h z066{ZbI`MWO8L?k)E9i>cFG@E0mBn54VWLFI6*Px1do5f7YTU4K5)J(K=_7wEdj)1 zzDk#U+yFcb!)kXw`eZfnlq^t|{QlpzuTH+JrJyv{8EilBjC9H-5o@RU@PEhgzxMbq zSp8rB_}}$%5^4Unf0WEnOT(s2i)vPo@GyCp^YioAmHcASBawQq zot2w6Z|Y3|cQrjmZ4YXN5s4U&=`Vmf>87}Ni56mQ$wGo{8qkHA8x$BlBJCg=WXM4L z`Y}8*G69grjx>b#^ck8ut07=f3cJ_5*D4IzIXIFx)`zC9GDmwa4jk;@p?^b13f`l+ zpws)ysW*dCGvp+L+S=M)*yFOcoNXh`R0~|zZ!3HCF2O13k0{_kUms}YD@dcn_e0;| zO>n-M#N!*HmqZdxs~hN|=m4~14yG_-$St0r!S6}Gw%{w&7Xdo#w&gqBMxGK^+USbu zL!3;PVFMvvD0IVTQ7%z#YBSQ>$;nA4V0U9Nf>S1;*pG~_s87MH+E^cxiN$MXl-PDF zLm=ve1PlhQ5dM+-Q(rz6k~y zI=_ETlLXoO%GwFkZ;ppSu6UDauRL7zD1b9JhFyBN_{u$q5m&aPc2VUlJPNEYKmtG_ zA(3+4z}=ZAdVynRiv7u$$NwJ;DSyZVKmbwyHuD3TZG}_EBm5y0nL+|Z=mOTmkk>uL zqI?#37ft!ij>(f?>P8Y~LzHig`>>fijuKFIiho@X;6Ah{yy)8>a9Q8cIn2a9KYhwf zykkQQv8;uCoN=JPA2Gcb0SA7wcyi{9OcHTj|6Ydg!7_HWtWT6J<}K2AQ(-<_vXeqB zho?+T=1%Sud5DmJf2|{CoMDZ6CG^sTG?a1Vnzj|?^&_hj5dAEQTv;4wJnU+WqwuwM z)FZv8NmJkMpDDw%?rt0(ZMdnurckS~2k6G5RG930hm0^31eo_h-D%+5tPKEsVEsd~ zG%MwUk0Cc7y!(g0Klyb=GD;XLu#jm^6>JKDXz> zJ2zw4F|M+J=-Nf=txG}{RTM(BEJ-iGlMdWk9I^Gg{InHz4*(Il@BToPuYMw4aphB1 zD1UrJj!3Cbn!me}tj>k9(ian>;nRs3JNagi-OZZ&ON@SdEm)K30|OMgejS|Ot*N<@ z<}u}ooeL8yy8084lING=%Sy|lth;xhrVUl46$lQqtR&_O?S`ZsN=n; zaoqf6Vzt*$0O%Q{RL(%Ydg-sKT`82(hRnstvSR7fEZcNXoLk_wE9xfq#N>~4DYWTh zLz=xjzk|Hn8);E84Vw`+SV%9dR`!PpYvj+SoGjB3v=GvSp_*s<{go#h# zT4lz3#B^UJ?Z5E^#-E>e!yApqs2N8UHb-veMM zIjN$xZif2sbqaqiE0_1}|05fr41lzA(T8k6zEF!=-f%y>$cq>TIkYUiEU?mh8(#p= zAWh~S9s$lP&HgEN!|#}cg+fSAK->K)&>dKQe>qo)l?DXdtlE2g*mwLR6nYaUw}97bqw{HEY?AUD0QW5!@oM=kWOuqOFuh1i%? zh!c2vDdjw6rrG?~*|>C12guT%0~yn-&E$l@Hb)zd<52e6<8(4P?oL#KwXzKLwTc zHOc!;RE)w2vNDQ@Xu~!!1Bt^C7}-Ff&AGK`Z`+^Uxw5_|$rlLuew;JeWbzD5vi^oW zbq~?Oih8l^+@%t`w6}84v@M^z)Q?y@UAWb}cZrw}AtR^gUZGGQGA5>vcBOQ+Yi6N# zFSovFpR1~0bI4C+N!eGMZW;(%-n0$ZO?L#+So(^{)eU%J?cWy$9qWEJaEdH^ zb+)YJs+XP^oHRJ=WS*n~w+o+R;jB#8UaO~MOBHR+gmG_BFEkNk-KvnCNteFD{L@KP z<2ThOHru%&MIQC|;jKy8I!DFeKD;GM5T}ZLHVTotSR^tUtoiNT{eP0DQ0Fn4Ajj>LYyP5j0*CnbPq$r?D-_;w#pl(Z?b_CE?;x z@$o^iP*^Z1Gud7MUVgVX=BD;5r0A|K>2t5Z2m5Ee6nTh{#HER6*GkoGm>~Ku5ZG!$aA3;KL_%kXTpB@{g( zIN_;!W(b({j0mXdriETsc&G~!B`Q==i!@>HQori_DMI@k1iKLPEIITEVW4lE_Ytim ziD{9KRpPB!hi+y_Y(dL|so=tPd7K2;iP>t%K~+fcnK;w^%glk}C4pNTN9!8~pYIiU zwpATgym&@_R}x98pC;AcwsAfJywk&zBA=bOx*IGtFYsr`?HCsCwb<{Yc3a#>v)rAO zt*<6dj$O2pGUE8!273|oGr4^s^Gt%+F+nWp;AQA(1uOr3z?LTN^iq}8nq zTFouPiPqv2rEc$HcHYtm2YkyW?$l=yMR}hwZY!6eR7o-Ht54tBzRcp3Iws)AP;_-# ztYsOfv0Ha@2C1}lM^pr(o2*;)p2bo4B?fP9xW#*K^n7oxgwN#9**bAim&e>VhGl%+ zCYR>}=a$j^yi3lO*tS3N>1DYix++3US@T?)UP?$LnsIi|Q=l2fXQI~Bee*4Rx61Ef zgAdNOOV{rx;7iVff;%(gSI)9ctvPz+Z<#}Y%4=n5oF9nD5gCO?PDOOEeSZ$nP2Z`^ zR~Eap`XuTWhje-3eF&0g2%%~FfZ)BZ)?cN8Qkf2HdO*q5WX2K?LV%!O$@)gAD95Qr zS)fqJaYU(5{esf*z`y4z1Ha+Jbmgsvp4KTAaioT(=+`6*UW?$Q${uwMmPgOHLdFwT z4N4!p{%mQl2MY-%%rVqJP|%Ns>w%+HsNDcw`5`bsLdv) z0|q(UcDLR_;a`$spFc}E3Q-*_p|xWU{~IU{3?Z+$3-^w<)7#z*FSt6l4T!eV`9^>i z7>1r~Wk(v#taUSg#>)*zyKQ-%F^2(}S-kcis{FWvtBT+sHO+T?ovxC*&sz5RT3(PV z{p7Vr(M6>Rw$1?EQuJ=LN*GoMDJ_(xuq^1LFnW)+Ab;@Pu0H}c%e-@UzdWvUG>!I% z&k?ee@Q9^i$R=vn-C@BAN>W&1a?uGKfh2ocL7jUvOysYESyg|^gecQ{m z&aI}*VV(kSl@79$kS?t#JeRYA_(r!9_?u&OQ@8f%wtNK{_UGJGivhbBr#ZK+`11gk zOG$(rZf6ogbPwRdg;TZ=0QO_a zfevpnP-v*h_!4i#3KV&_Ge7FK|MK7Sr(*%+ulxF)5|HUzWj-|*(aO^td_^x@m1mfS zGd`tN_>^r*M6>{R2iMh&;-i(~7v4yZ5Z;)G?1P!JN=D!4XSIZ55`=6kj)5Sgc=xl{ z;4adz9(f-^i1~5#MTj;yBbyVn{gt)BDdorQ{e{>r0Pf5Q1%h=$F-hO+0A{jm#eP+T z7(6tbuT6g`kP8^(fAKaR~bHHSgZNM@Zn20pd z)90oxwe|<#J~QfBvFvxLVx~d9gbeJP?Qi}+y~ub7O9P=)rQuaRNnwGP*oDoN$B8UDvL8cDPrI+Ygr3J7Cr7)- zeho9<&J=ptL(2(@>agM_jdtpD9<-WgP>vORbxFUVorvza-EGi==c~1JIamhiV(t)fArLeqambm^vKqP zCwk6Ju_K?@!y8^F=n;qlvrh(Ixu}fpVQ-7Ds&#IXYW9hhyfCaPYVMd>()mZ}6rdA1 zwYqI+$WuL`&^b1}@0$koUa!cNUm0L59-KnmaJ<}|eHZ$}0kCWLb z`@e3%$4(k=wlin{PY*T$B3xS`0Eu*;J$2mX5FZ!#H?8V@7VCt^0!XkaFm<{GH$y*- z19!iyr@0Pl0{6x|<5|wVSslVnM#}R|d>4QR?L7jKqJ!kKMR|3&#%N%}%?Wo6N}*#f zZbqw?sY-UJDUP`Vk`MuSv?+hAFt|u4cD4N7^Ji=Wi&~~aS|VE77Vpr3KkWftzYm7` ziuvpJK7!{Q2(PJ7x##{qYh_STa6cg!2=#3s%yH3z#1KgP_u+*e-#}dLGY#qL=&84^qI?-A_UJ*>d?GUDBT_#kS&n#k8p{OI&;MhK}t5oURMf~da66xAr+bZ zNytt{Gzo^Z?9hY{GY@D#UkPd*7TjNIqmhVdp)TV5TmMfM+{A>yU(4t^oYX}1SVndN z)$q-=x$0D`%aHgL_Q53#ACBU2HD3 z!*lc@PxkRH?6|TamvAw|V8=mt?y6~r-eRzI-M5b-!{~-8)Uqi*2z$RMCAtlrgf*M6 z9!%qeLKhqql{P&4@&~7S&i4At)XmcGAW&DLcI+TBWzp!~$7qgjO!ZFyTM^?+ zw~Pzgt_5k=$w4r!Jbk^O`R6HHRC0?+oT{d<{{aF7{*Msg{FRUTv`6zwM^=S3d=WJF zhu>w7pfH4QLgpP~0&Td*8u)4W*Jtb<_XyF3fG*t6>`(4l)tGnV9yLR0$e+A<$sc$t zzF*gS63%z2S!=0&D{Z6TbzTSZePFq7hs^1uAH4W-wP@zrIljK&JHwxmoFPKfwCV*K za<5%0l>r6xAUImFh$Tu$qhd@Nj7o607_g%KI_!@!z7lNyCBWpVr+F>4Ia@!bY6D_K zeiLwfY)Pw?T>72Ir6P<%@|%L19a9~z$LfA!rL-bzjs2b4GWx+46Ud;Q#kMn>o$n5r z@kTLm<4wkjw5H(VK>3fh-O^Uj0*t){!`}Po5yrbBZ3**U{c*?Iz!?q^iNFMY0V&@C zJjuatxCR%e2(FApJEmSCnfT4|rehw=DnM}UuFA>fZ5VmUdkgLI2`ny=vI0vL8*k5% zy2@Ufi1s{H9xn_2rq(vDp&d_5kc7EtI7ZMzWa7@(4bj@QI~B% zt`}wk%MX)Hk}9C|IAqffkqZ0J<1? zJ$|k16jr1bxb@(@yo_JCR$E9)Juh9qF1rgz1GnYFs zs4BWJ2t}LMu2!S=QWxd(aF5@7k+r#zy(4H2au)qO>8|kQiT}%;V&rtsRb)fYDXl!+ zqG(5n+T9rR<3+Hy5=9fN`~mO}M?OORG$nECeTL=uHITS9Ki|E~_ltU=Y(XK=dHit= z25|FMqyGTeu^V3v)!<1J5M$3L#M0?GYfwKKOz;tah}^~Z@x>$6EZ-LJn`?YBC@dH^ zaFe9H?=HPLna-mC$eh*^8xOG+$^B(EV8s}ZIYC>nN9^77`TL(X!lR`{+nEW0pF$xB zHj~(?JE3To!f$x?38Vq|(OmA=_a%IWw07Ve*-zX0#`n2&h;(*@N%-_Q_|*M96GCG4 zV+XtCrw;hAavAeXha%-CiXm=q&989N2G!#)RNN#FcTiIdZ9CT>E_ zHoUA7$)AKK|kBQZ;VUC+j_ z`S;u~-wf?kmXdNFBLtoe3B9ga%rVO4>hgxawuj%UlCC-`VBi8!7jMfVK{Kh0Ru${OE+o!^^FC&Pf~D z#V>oL_C0(%LMChWTU}y9hEagBH(^xRBx2qfV+t2d>Uvg!T1tguc#_RvPO*MUDH)O9 zdipHI73;d$zf8%$h@a@aH~gJoy}#$p4b>W^*ov^b%sjs=cv&t=$Vpj-QyTqyr$Q*j&1+a{D< zqnkn}61eSIoIy$DKdxlPXHu%qx3-sMfA3Q9#p4q0rJYG4`U@ zNx~lHO!G-rlL@PB#2=4!3!Paik-0t2a5Q{pVI4?D)Cx8BXuANxD*G&M#x$^eYZ`>S zYOdG=y1^A)o?SCpb3IU_eJE8BlP0qZWuAhMwcYK{&vxHZPRZyMLtjbp6tLMcNResW zhsC@2?hT1@ADj1*#u&RKJgO0fv%V=DVVfXsvntc#ZWjQMVQkBuRc!&WmTu7^{dy5g zFOwBq(qFzRp8n^BVjJF+Q9DH2#=V%hk|6`!o9r9{LO)u#VkG?Rt(5uwph^%$Z zm|?=VHA+bNX1Ehih=%cCxG=8~ja>WZhVn)t?L)n=JwW1ljYTgT1Bil8sZBhvH2@Y!DW^29w3c(h(HsIkLNr}!$P_RJ_MV>!#?q4 zM@$pCv){k`t`(m;KB&$zsG8N&kp8HE{wlp-CW|dRx=w%(!&P!a`ANavyUYYOfxTcE zP=8fJxc?}h1r{?|qMO3X$K|Y%&H^2ud>7r;^75y+&e~Hk+wm_QIh<7ARbvbooW%1c zSMSKiWWv|TZwi2T?zMAlYb&zud!utOBNc&(aT9d5+XI4&09i9s+<)fjTKB@p<@;!e z7pU@?%x4E~a5FBfr|u!Y2qWCqoT(F;z1ftIB;ZkTL;A3_K(9(|S5=NCpzVnOuAzW$tjk%d+I$YiQP1@BV_oDbO~*4a&nTTFd3yg+VDS zCBxf9N6Ce~imf^b1#(@GoEy!e7f&_HFR~AYsVR|92tvRXbPE715vr6Hb=~oQIIG8; zzqW9VN&TGmlm-j)n}=7$L#}5Ai$5OAF~6istF?+ z>A?s#L+e5gBdj<`7EJR_EzpT2LdY1b5*DO?(*_UbMKy>DTmZnwz`q=cb460PM zSv)*nxEZ<@ckc0CW~$)gx?x10JSxJx5X)I2C^7BI+G4>L$z{mumez!bGijk3-Joo2m4@ac%mxpz9!!Gg{hK zFOHsf`Jfq!2*SF1u~Vv|yN;Pobs!js2sGMIBCu-7TnN^z!$msJ1XXSI<8eF#4y%?w zlledOI5>p1jHZfdo67m+Ia;!0aq8;-QR{3$aBDR(r3#;zWNGwySGg;5#(A{cd8@;; zdBSMix0ijfw$xjv{4f~9HP8sc^;t?moW!g@QIfKRuncq4UeZ2eS6}aOBYfF9@rO_7 zz~s%KC+poJVC*T}Z*KiPT-C@C))b@Grws39q&Jhb=5}mTMxELX&3gn9Y*G8x zD7QszeE#LQW<(irf{ub*j+`2*z&hY_tBBj}-^fEVx_%FyW9Nc%Ar?Mg%vL05yf~zxj^|x zau^$>Ij~Zp1Bt_mvrM+trp~f-jFl6?9$WgHs;jb?4E!i5luAnpn(_h8n$O z+uHWP556pLio}^XpEprn$mmn@vy5#!M|4(v0)9k04fjr7o)Rh4|+lRiOI_) z-6O6%F?j*lZu32phA?fDh#L&jAl{*R+k#jZc~t$b?ON!&RlYxVCUAlKVxn7+RcR71 zp1LXO+Lr>09SyQ_y^11=Bq{fUiYO4D&ivOq3=X(LG*=U?6qF= zbD%SCxoqXknbqUFW_rH(0xgZ5%-v7rf*BPK=E1tD`^-XN14RO2xO~4POzp$b7tiJAsD-aP)-Rs{)V`m{FJ6oQnY|!*5cYde z1*eEwxXRKc{wr!}A_(*cmJgp6e&=UerGKzn2~e6LXxc-Cw_W2ZHP*nzSRNOG*Dj@? z|AFTJlJ|y80g%=A=1HWnJK&g!W}T8V|D|sNq{JmnU>{U?pFj=J5&u&tDB%RK{Dyk9 z-E9EgFH&&5Pbl+@Fz}&|S>N4cit-GPBguo`o^b(qMtw|3DC{$|N3XjLSgRc;}NF^jAZv=A?MdaY5f1Bh%08k z4?X?YBu!UYeiq<%Cq4S$j(vOSq6IX|%byl1fZy>2h&7nLF|E~DV3@kO@05a?+<}*d zoqb^byDY-!Au!OtLgmtau_D=lKdh)_^pzeEP4EDpFJ0|qKmeuh8eQgian?j&fzAZT))Y&05){Eu5{SkngP(0K5#iN zSd4j0`@`pX&v<*E4{@xb&|5@|hL)~U!X@gZC6Uj5!oCFR zHb6Ko7Gr1Y!8BU_IZn*?X+i34l$CYMTRq?Hw2<^Rx#POh*ul!po}BQajF$+fPjT;t zbLi+3zgQ068S_5Yb95v5!}lW2bUu=~BizV2D4-y^z)wS9B8MDo0#$~A#n&bZgPIkoMKNWm%xDH)wAmo zy>9`d+h4QJu%>h~8PoOu(^j-pj%sjwY=Y@#03Rzi7;iQ97(7kTPm zt`2P-0-l);Nw;$dp-^cuLwZVn&GUyonr^TLY^n}r3bb{%#?-i31HJz9AqeU1z!RAb zAc~-@Sryf>r>AIqa##ig8yyN#cg94lRSanrrkTBRdFTp-t#|x$CJ(Cp2|sKZ5+}G> zBotVReP4F{9to*$kMv!Kv)IS z(2d$f?dkP&Dy&`KE7djv4oHDW^vAMz;Ga{9QszfV7=tSkPQj9+XcfS4B0 z1VnvIh~=C_112)iM77KZpgf2yrn=}Dm)U509t>reulo{f#nktfC4Yr=?iBaJgvvy~ zf|}k#E&V2rU%3{%ogYx}08QgInvizIy$U3!wV5 zy|&qtKyeUF>qcve=NjiJ1)T8F0SDnJ;pI_~maZ(kdO%?p?e}^#JkGfVTJsp^1h`yS z_P&?u05kg8E&qQ_N^@c+8u$A67>d2=%)^f|a+wY-@7 zaONynCqH4AwA$bQ5H(8=GkUX)S$D6p)(}%U*`sB7NDw_ z@;;uuS#7DZ-=XWP*Fau_p%+#CfTH~kLo+w9-PIcUx6u^c5acpxv^~Kp5|mq?`rEEo z@{Hy@aJtldHg(&7Zd_sWY1OYD44hp~9pPeB%a=}z`HUpPN0x7NErIJGR{^sOKKH%(}^|J{kr zxB#PuwJ6m8j@C^Ro1XC?dcd4r7tp2;8;-NeIw_f;gVZHx5h^!4DheICguiUud55?> z1n@!49K9zdMsjNN8Zv%!*$>mS_EU8^_NI-fa7Qk&mK$ffRupPdh;vyag+hf3$9;a4 zl|IrGho1zsqyjn-&` zwxc=KG{oq3x4)zSyZDAciJkkeUSR*agYpLmtv$0-`t432q2gESvl1Sape2f` zE-ky}}!SzgQPltTc#{Qp4!`UOy@m6zI2iW?XdjhPmi`aLa-KB9Dc z?o~QItTC05DAe;JNXyHc-pJzK{%|(lWQvdwJKg!)1XyUEf5?N_xsZkJ?2-n$6TR(h zzz`~V)8cwBp02$=vkHrfGgKl*f7#3g*N*E)T~ac4JdjIFRPtTP!M5EC-!ZbM4T?6e zf6=F>P82qgE)I_FjRSg`08E~=2I|I#z{+6_bv*zC4ksr@QV8HT^>!_|1OLFq;6g}a z!{K(GQej{85zx5L0MM$WK9Q>_5+h^m_Izn+qU2VktBM(C(;}?TWz02~G&S17T+4 z#OR6EK2t$NZm&rF(_jf`RADXPEw&`bHC*^`yJad2+Hm#u?$eyQ1#4c6WKL~GUD?jx zr=qS@FD2r;h7BXt0NSbzb9XOrxJ(&aj`{{$P{p%G@H=)cmUr;I2)pcIw7 z90IqQJ67iy=0gPSuVoxBI$qz42;*#DUng&haSQ8ujfbu?Da9T+m)6Q@ljQhHLZTHj zqAy28Pw^D4_IFWsG>}|Kp)CcOJP=~mI5~u9grTR)mR}|MWn=@&-n7c-k+6NE zAQ|uE*%Y9Dv2tiznin`E*f$q?6e+0rUdR1UVF2OPYjZSj@#Jy92PiGjgRqJhpkA*? z=Jd&J)Dd#T5T6g1?kNc|`pi)AW^;a^v;h2%I~eIvwpRVytZw2MavCQ~lNsE8#D|ZrGS*j9l-!c`v-!N;(eWTV_(`{oYZq0bY{27k2^sii#k={4Jfb z%cl8nD?xx)TMT3r)q>MHeNzHMB>}i0XVm)=hyh`}ztlSUnu_hNM z%*@z;__RD4H#gKfB|N?lV#-u2C)~rLryQOS{X9*P2U*N47byWKf@nL%?Dor*w(0$g z_LRwLg-WAO0{aWg&8qx0)oABas^WGGqvHRocN8TRni=oPIe`^Q)?_fwk0DScyoGHf z%fbjC>#rU+qDPqs_{@1jCv+b}CU(nY@*+KJ&>TVUEuWJf3}pyZ?V!TQQVbREKRfiC zSHU+jz*d}h)Q(9zvL=306K$?Hg3=;BR!E`e1={=D%0zOF+ZxuY$CHk=C2`B z+d7MnT}pRsVGdz#D~f-)nsynkIliEiYy~}DmBWlYIJ60UnmcbZCxf1^k

AZ{|PM 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ΠYv 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%0AS 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 agXv17^M(vJ!4D1i+*f{}^hLoe^gjS2=P~>M literal 0 HcmV?d00001 diff --git a/docs/configuration.mdx b/docs/configuration.mdx index 22225a004..698638592 100644 --- a/docs/configuration.mdx +++ b/docs/configuration.mdx @@ -123,6 +123,49 @@ mcp-agent uses two configuration files: +## OAuth Configuration + +MCP Agent exposes two complementary OAuth configuration blocks: + +- `authorization` describes how the MCP Agent server validates inbound bearer tokens and publishes protected resource metadata. +- `oauth` configures delegated authorization when the agent connects to downstream MCP servers. + +```yaml +authorization: + enabled: true + issuer_url: https://auth.example.com + resource_server_url: https://agent.example.com/mcp + required_scopes: ["mcp.read", "mcp.write"] + introspection_endpoint: https://auth.example.com/oauth/introspect + introspection_client_id: ${INTROSPECTION_CLIENT_ID} + introspection_client_secret: ${INTROSPECTION_CLIENT_SECRET} + +oauth: + callback_base_url: https://agent.example.com + flow_timeout_seconds: 180 + token_store: + backend: memory # use "redis" for multi-instance deployments + refresh_leeway_seconds: 90 + +mcp: + servers: + github: + transport: streamable_http + url: https://github.mcp.example.com/mcp + auth: + oauth: + enabled: true + scopes: ["repo", "user:email"] + client_id: ${GITHUB_MCP_CLIENT_ID} + client_secret: ${GITHUB_MCP_CLIENT_SECRET} + redirect_uri_options: + - https://agent.example.com/internal/oauth/callback +``` + +- When `authorization.enabled` is true the MCP server advertises `/.well-known/oauth-protected-resource` and enforces bearer tokens using the provided introspection or JWKS configuration. +- `oauth` enables delegated authorization flows; the default in-memory token store is ideal for local development while Redis is recommended for production clusters. +- Downstream servers opt into OAuth via `mcp.servers..auth.oauth`. Supplying a `client_id`/`client_secret` allows immediate usage; support for dynamic client registration is planned as a follow-up. + ## Configuration Reference ### Execution Engine diff --git a/docs/oauth_support_design.md b/docs/oauth_support_design.md new file mode 100644 index 000000000..5aea9b1f2 --- /dev/null +++ b/docs/oauth_support_design.md @@ -0,0 +1,108 @@ +# MCP Agent OAuth Support + +## Goals +- Protect MCP Agent Cloud servers using OAuth 2.1 so MCP clients obtain tokens via standard flows. +- Enable MCP Agent runtimes to authenticate to downstream MCP servers that require OAuth access tokens. +- Provide pluggable token storage for both local development (in-memory) and multi-instance deployments (Redis planned). +- Maintain compatibility with MCP Authorization spec (RFC 8414, RFC 9728, OAuth 2.1 + PKCE, Resource Indicators) and the proposed delegated authorization SEP. + +## Architecture Overview + +### Components +1. **Auth Server Integration** – Configure the FastMCP instance with `AuthSettings` and a custom `TokenVerifier` that calls MCP Agent Cloud auth services. +2. **Protected Resource Metadata** – Serve `/.well-known/oauth-protected-resource` using FastMCP hooks so clients can discover the auth server. +3. **Access Token Validation** – Enforce bearer tokens on every inbound MCP request via `RequireAuthMiddleware`, populating the request context with the authenticated user. +4. **OAuth Token Service** – New `mcp_agent.oauth` package with: + - `TokenStore`/`TokenRecord` abstractions + - `InMemoryTokenStore` and Redis-backed implementation (second pass) + - `TokenManager` orchestration (acquire, refresh, revoke) + - `OAuthHttpxAuth` for attaching tokens to downstream HTTP transports + - `AuthorizationFlowCoordinator` that interacts with the user via MCP `auth/request` +5. **Delegated Authorization UI Flow** – Extend the gateway/session relay so servers can send `auth/request` messages to MCP clients, capturing authorization codes via either: + - Client-returned callback URL (preferred, works with SEP-capable clients) + - MCP Agent hosted callback endpoint (`/internal/oauth/callback/{flow_id}`) as a fallback / native-app style loopback. +6. **Configuration Surface** – Extend `Settings` and per-server `MCPServerAuthSettings` to describe OAuth behaviour (scopes, preferred auth server, redirect URIs, etc.) and global token-store configuration. + +### Key Data Flow +1. **Inbound Requests** + - Client presents bearer token ⇒ `BearerAuthBackend` + `MCPAgentTokenVerifier` introspect token. + - Verified token populates context with `OAuthUserIdentity` (provider + subject + email). + - Context is propagated into workflows/sessions so downstream OAuth flows know the acting user. + +2. **Outbound HTTP (downstream MCP server)** + - `ServerRegistry` detects `auth.oauth` configuration. + - Wraps HTTP transport with `OAuthHttpxAuth` which requests an access token from `TokenManager`. + - `TokenManager` checks store; if missing/expired ⇒ `AuthorizationFlowCoordinator` performs RFC 9728 discovery, PKCE, delegated browser flow through MCP client, exchanges code for tokens, caches result. + - Requests automatically retry after token refresh when a response returns 401/invalid token. + +3. **Token Storage** + - Tokens stored per `(user_identity, resource, authorization_server)` tuple with metadata (scopes, expiry, refresh token, provider claims). + - Store implements optimistic locking to avoid concurrent refresh storms. + - Pluggable backend (`InMemoryTokenStore` initial, Redis follow-up). + +## Module Plan + +``` +src/mcp_agent/oauth/ + __init__.py + identity.py # OAuthUserIdentity, helpers to extract from auth context + records.py # TokenRecord dataclass/pydantic model + store/base.py # TokenStore protocol + store/in_memory.py # Default store + manager.py # TokenManager (get/refresh/invalidate) + flow.py # AuthorizationFlowCoordinator + http/auth.py # OAuthHttpxAuth (httpx.Auth implementation) + metadata.py # RFC 8414 + RFC 9728 discovery helpers + pkce.py # PKCE + state utilities + errors.py # Custom exception hierarchy +``` + +Integration touchpoints: +- `mcp_agent/config.py` – add OAuth settings models. +- `mcp_agent/core/context.py` – add `current_user`, `token_manager`, `token_store`, `oauth_config` fields. +- `mcp_agent/app.py` – initialize token store/manager based on settings. +- `mcp_agent/server/app_server.py` – configure FastMCP auth settings, register callback route, surface user identity, extend relay to handle `auth/request`. +- `mcp_agent/mcp/mcp_server_registry.py` & `mcp_agent/mcp/mcp_connection_manager.py` – wire `OAuthHttpxAuth` into HTTP transports and expose helper for manual token teardown. +- `mcp_agent/mcp/client_proxy.py` – add proxy helpers for `auth/request`. +- `SessionProxy` – add direct request helper for `auth/request` and ensure Temporal flow support. +- `examples/mcp_agent_server/*` – demonstrate configuration changes. +- Tests – new suite exercising token store, metadata discovery, flow orchestration (with mocked HTTP + client responses). + +## OAuth Flow Details +1. **Discovery** + - If downstream server responds 401 with `WWW-Authenticate`, parse for `resource_metadata` ⇒ GET metadata ⇒ determine auth server URL(s). + - Fetch authorization server metadata (RFC 8414). + - Perform optional dynamic client registration when configured and supported. + +2. **Authorization Request** + - Generate PKCE challenge/verifier, secure `state`, choose `redirect_uri`. + - Build authorization URL including `resource` parameter (RFC 8707) + requested scopes. + - Invoke `auth/request` via SessionProxy → MCP client opens browser. + +3. **Callback Handling** + - Preferred: MCP client returns callback URL payload via request result. + - Fallback: Authorization server redirects to `/internal/oauth/callback/{flow_id}`. + - Coordinator validates `state`, extracts `code` (and errors). + +4. **Token Exchange / Storage** + - POST token endpoint with code + PKCE verifier + resource. + - Store access token, refresh token, expiry, scope, provider metadata. + - Associate tokens with user identity for reuse. + +5. **Refresh / Revocation** + - Manager refreshes when expiry within configurable grace window. + - Invalidate token on refresh failure or when server responses indicate revocation. + - Provide method to revoke tokens via authorization server when supported. + +## Open Questions / Follow-ups +- Redis-backed `TokenStore` (requires deployment secrets) – planned second phase. +- How LastMile auth server exposes token introspection + JWKS; need concrete endpoint specs to finalize `MCPAgentTokenVerifier`. +- MCP client adoption of `auth/request` SEP – need capability detection; until widely supported we rely on hosted callback fallback & manual instructions. +- Access control DSL (include/exclude by email/domain) – to be evaluated once token identity payload finalized. + +## Testing Strategy +- Unit tests for token store concurrency + expiry handling. +- Metadata discovery + PKCE generation (pure python tests). +- Integration-style test for delegated flow using mocked HTTP server + fake MCP client (ensures `auth/request` plumbing works end-to-end). +- Tests around server 401 enforcement + WWW-Authenticate header. + diff --git a/src/mcp_agent/app.py b/src/mcp_agent/app.py index fa8946cff..558691071 100644 --- a/src/mcp_agent/app.py +++ b/src/mcp_agent/app.py @@ -3,7 +3,7 @@ import sys import functools -from types import MethodType +from types import MethodType, FunctionType from typing import ( Any, Dict, @@ -40,6 +40,8 @@ from mcp_agent.tracing.telemetry import get_tracer from mcp_agent.utils.common import unwrap from mcp_agent.workflows.llm.llm_selector import ModelSelector +from mcp_agent.oauth.manager import TokenManager +from mcp_agent.oauth.store import InMemoryTokenStore from mcp_agent.workflows.factory import load_agent_specs_from_dir @@ -249,6 +251,23 @@ async def initialize(self): # Store a reference to this app instance in the context for easier access self._context.app = self + # Initialize OAuth token management helpers if configured + oauth_settings = None + try: + if self._context.config: + oauth_settings = self._context.config.oauth + except Exception: + oauth_settings = None + + if oauth_settings: + token_store = InMemoryTokenStore() + token_manager = TokenManager( + token_store=token_store, + settings=oauth_settings, + ) + self._context.token_store = token_store + self._context.token_manager = token_manager + # Provide a safe default bound context for loggers created after init without explicit context try: set_default_bound_context(self._context) @@ -557,6 +576,25 @@ async def wrapper(*args, **kwargs): # Fall back to the original function return await fn(*args, **kwargs) + # Ensure the wrapper shares the original function's globals so that + # string annotations (from __future__ import annotations) continue to + # resolve against the workflow module rather than mcp_agent.app. + original_globals = getattr(fn, "__globals__", None) + if original_globals is not None and wrapper.__globals__ is not original_globals: + rebuilt_wrapper = FunctionType( + wrapper.__code__, + original_globals, + name=wrapper.__name__, + argdefs=wrapper.__defaults__, + closure=wrapper.__closure__, + ) + rebuilt_wrapper.__kwdefaults__ = wrapper.__kwdefaults__ + rebuilt_wrapper.__annotations__ = wrapper.__annotations__ + rebuilt_wrapper.__dict__.update(wrapper.__dict__) + rebuilt_wrapper = functools.update_wrapper(rebuilt_wrapper, fn) + rebuilt_wrapper.__wrapped__ = fn + wrapper = rebuilt_wrapper + return wrapper def _create_workflow_from_function( diff --git a/src/mcp_agent/config.py b/src/mcp_agent/config.py index 638698b4b..d72f972ec 100644 --- a/src/mcp_agent/config.py +++ b/src/mcp_agent/config.py @@ -11,7 +11,15 @@ import warnings from httpx import URL -from pydantic import AliasChoices, BaseModel, ConfigDict, Field, field_validator +from pydantic import ( + AliasChoices, + AnyHttpUrl, + BaseModel, + ConfigDict, + Field, + field_validator, + model_validator, +) from pydantic_settings import BaseSettings, SettingsConfigDict @@ -22,6 +30,79 @@ class MCPServerAuthSettings(BaseModel): """Represents authentication configuration for a server.""" api_key: str | None = None + oauth: Optional["MCPOAuthClientSettings"] = None + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + +class MCPAuthorizationServerSettings(BaseModel): + """Configuration for exposing the MCP Agent server as an OAuth protected resource.""" + + enabled: bool = False + issuer_url: AnyHttpUrl | None = None + resource_server_url: AnyHttpUrl | None = None + service_documentation_url: AnyHttpUrl | None = None + required_scopes: List[str] = Field(default_factory=list) + jwks_uri: AnyHttpUrl | None = None + introspection_endpoint: AnyHttpUrl | None = None + introspection_client_id: str | None = None + introspection_client_secret: str | None = None + token_cache_ttl_seconds: int = Field(300, ge=0) + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + @model_validator(mode="after") + def _validate_required_urls(self) -> "MCPAuthorizationServerSettings": + if self.enabled: + missing = [] + if self.issuer_url is None: + missing.append("issuer_url") + if self.resource_server_url is None: + missing.append("resource_server_url") + if missing: + raise ValueError( + " | ".join(missing) + " must be set when authorization is enabled" + ) + return self + + +class MCPOAuthClientSettings(BaseModel): + """Configuration for authenticating to downstream OAuth-protected MCP servers.""" + + enabled: bool = False + scopes: List[str] = Field(default_factory=list) + resource: AnyHttpUrl | None = None + authorization_server: AnyHttpUrl | None = None + client_id: str | None = None + client_secret: str | None = None + redirect_uri_options: List[str] = Field(default_factory=list) + extra_authorize_params: Dict[str, str] = Field(default_factory=dict) + extra_token_params: Dict[str, str] = Field(default_factory=dict) + require_pkce: bool = True + use_internal_callback: bool = True + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + +class OAuthTokenStoreSettings(BaseModel): + """Settings for OAuth token persistence.""" + + backend: Literal["memory", "redis"] = "memory" + redis_url: str | None = None + redis_prefix: str = "mcp_agent:oauth_tokens" + refresh_leeway_seconds: int = Field(60, ge=0) + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + +class OAuthSettings(BaseModel): + """Global OAuth-related settings for MCP Agent.""" + + token_store: OAuthTokenStoreSettings = Field( + default_factory=OAuthTokenStoreSettings + ) + flow_timeout_seconds: int = Field(300, ge=30) + callback_base_url: AnyHttpUrl | None = None model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) @@ -639,6 +720,12 @@ class Settings(BaseSettings): agents: SubagentSettings | None = SubagentSettings() """Settings for defining and loading subagents for the MCP Agent application""" + authorization: MCPAuthorizationServerSettings | None = None + """Settings for exposing this MCP application as an OAuth protected resource""" + + oauth: OAuthSettings | None = Field(default_factory=OAuthSettings) + """Global OAuth client configuration (token store, delegated auth defaults)""" + def __eq__(self, other): # type: ignore[override] if not isinstance(other, Settings): return NotImplemented diff --git a/src/mcp_agent/core/context.py b/src/mcp_agent/core/context.py index d449c938a..cc7bee78e 100644 --- a/src/mcp_agent/core/context.py +++ b/src/mcp_agent/core/context.py @@ -33,6 +33,7 @@ from mcp_agent.workflows.llm.llm_selector import ModelSelector from mcp_agent.logging.logger import get_logger from mcp_agent.tracing.token_counter import TokenCounter +from mcp_agent.oauth.identity import OAuthUserIdentity if TYPE_CHECKING: @@ -42,6 +43,8 @@ from mcp_agent.executor.workflow_signal import SignalWaitCallback from mcp_agent.executor.workflow_registry import WorkflowRegistry from mcp_agent.app import MCPApp + from mcp_agent.oauth.manager import TokenManager + from mcp_agent.oauth.store import TokenStore else: # Runtime placeholders for the types AgentSpec = Any @@ -50,6 +53,8 @@ SignalWaitCallback = Any WorkflowRegistry = Any MCPApp = Any + TokenManager = Any + TokenStore = Any logger = get_logger(__name__) @@ -93,6 +98,13 @@ class Context(BaseModel): gateway_url: str | None = None gateway_token: str | None = None + # Current authenticated user (set when acting as an MCP server) + current_user: Optional[OAuthUserIdentity] = None + + # OAuth helpers for downstream servers + token_store: Optional[TokenStore] = None + token_manager: Optional[TokenManager] = None + model_config = ConfigDict( extra="allow", arbitrary_types_allowed=True, # Tell Pydantic to defer type evaluation @@ -256,6 +268,14 @@ async def cleanup_context(shutdown_logger: bool = False): shutdown_logger: If True, completely shutdown OTEL infrastructure. If False, just cleanup app-specific resources. """ + global _global_context + + if _global_context and getattr(_global_context, "token_manager", None): + try: + await _global_context.token_manager.aclose() # type: ignore[call-arg] + except Exception: + pass + if shutdown_logger: # Shutdown logging and telemetry completely await LoggingConfig.shutdown() diff --git a/src/mcp_agent/mcp/mcp_server_registry.py b/src/mcp_agent/mcp/mcp_server_registry.py index a28735373..04a8cad08 100644 --- a/src/mcp_agent/mcp/mcp_server_registry.py +++ b/src/mcp_agent/mcp/mcp_server_registry.py @@ -31,6 +31,7 @@ from mcp_agent.logging.logger import get_logger from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession +from mcp_agent.oauth.http import OAuthHttpxAuth from mcp_agent.mcp.mcp_connection_manager import MCPConnectionManager if TYPE_CHECKING: @@ -215,6 +216,24 @@ async def start_server( kwargs["sse_read_timeout"] = sse_read_timeout # For Streamable HTTP, we get an additional callback for session ID + auth_handler = None + oauth_cfg = config.auth.oauth if config.auth else None + if oauth_cfg and oauth_cfg.enabled: + if context is None or getattr(context, "token_manager", None) is None: + logger.warning( + f"{server_name}: OAuth configured but token manager not available; skipping auth" + ) + else: + auth_handler = OAuthHttpxAuth( + token_manager=context.token_manager, + context=context, + server_name=server_name, + server_config=config, + scopes=oauth_cfg.scopes, + ) + if auth_handler: + kwargs["auth"] = auth_handler + async with streamablehttp_client( **kwargs, ) as (read_stream, write_stream, session_id_callback): diff --git a/src/mcp_agent/oauth/__init__.py b/src/mcp_agent/oauth/__init__.py new file mode 100644 index 000000000..7612bd080 --- /dev/null +++ b/src/mcp_agent/oauth/__init__.py @@ -0,0 +1,19 @@ +"""OAuth support utilities for MCP Agent. + +Modules export their own public APIs; this package file avoids importing them +eagerly to sidestep circular dependencies during initialization. +""" + +__all__ = [ + "access_token", + "callbacks", + "errors", + "flow", + "http", + "identity", + "manager", + "metadata", + "pkce", + "records", + "store", +] diff --git a/src/mcp_agent/oauth/access_token.py b/src/mcp_agent/oauth/access_token.py new file mode 100644 index 000000000..fe3d4bab4 --- /dev/null +++ b/src/mcp_agent/oauth/access_token.py @@ -0,0 +1,82 @@ +"""Extended access token model for MCP Agent authorization flows.""" + +from __future__ import annotations + +from datetime import datetime, timezone +from typing import Any, Dict, Iterable, List + +from mcp.server.auth.provider import AccessToken + + +class MCPAccessToken(AccessToken): + """Access token enriched with identity and claim metadata.""" + + subject: str | None = None + email: str | None = None + issuer: str | None = None + resource_indicator: str | None = None + claims: Dict[str, Any] | None = None + + @classmethod + def from_introspection( + cls, + token: str, + payload: Dict[str, Any], + *, + resource_hint: str | None = None, + ) -> "MCPAccessToken": + """Build an access token instance from an OAuth 2.0 introspection response.""" + client_id = _first_non_empty( + payload.get("client_id"), + payload.get("clientId"), + payload.get("cid"), + ) + scope_value = payload.get("scope") or payload.get("scp") + if isinstance(scope_value, str): + scopes: List[str] = [s for s in scope_value.split() if s] + elif isinstance(scope_value, Iterable): + scopes = [str(item) for item in scope_value] + else: + scopes = [] + + audience = payload.get("resource") or payload.get("aud") + if isinstance(audience, (list, tuple)): + audience_value = _first_non_empty(*audience) + else: + audience_value = audience + + resource = resource_hint or audience_value + + expires_at = payload.get("exp") + + return cls( + token=token, + client_id=str(client_id) if client_id is not None else "", + scopes=scopes, + expires_at=expires_at, + resource=resource, + subject=_first_non_empty(payload.get("sub"), payload.get("subject")), + email=_first_non_empty( + payload.get("email"), payload.get("preferred_username") + ), + issuer=payload.get("iss"), + resource_indicator=resource, + claims=payload, + ) + + def is_expired(self, *, leeway_seconds: int = 0) -> bool: + """Return True if token is expired considering optional leeway.""" + if self.expires_at is None: + return False + now = datetime.now(tz=timezone.utc).timestamp() + return now >= (self.expires_at - leeway_seconds) + + +def _first_non_empty(*values: Any) -> Any | None: + for value in values: + if value is None: + continue + if isinstance(value, str) and not value: + continue + return value + return None diff --git a/src/mcp_agent/oauth/callbacks.py b/src/mcp_agent/oauth/callbacks.py new file mode 100644 index 000000000..7cae8c992 --- /dev/null +++ b/src/mcp_agent/oauth/callbacks.py @@ -0,0 +1,53 @@ +"""Callback coordination for delegated OAuth flows.""" + +from __future__ import annotations + +import asyncio +from typing import Any, Dict + + +class OAuthCallbackRegistry: + """Manage asynchronous delivery of OAuth authorization callbacks.""" + + def __init__(self) -> None: + self._pending: Dict[str, asyncio.Future[Dict[str, Any]]] = {} + self._lock = asyncio.Lock() + + async def create_handle(self, flow_id: str) -> asyncio.Future[Dict[str, Any]]: + """Create (or reuse) a future associated with a flow identifier.""" + async with self._lock: + future = self._pending.get(flow_id) + if future is None or future.done(): + loop = asyncio.get_running_loop() + future = loop.create_future() + self._pending[flow_id] = future + return future + + async def deliver(self, flow_id: str, payload: Dict[str, Any]) -> bool: + """Set the result for a pending flow, returning False when no listener exists.""" + async with self._lock: + future = self._pending.get(flow_id) + if future is None: + return False + if not future.done(): + future.set_result(payload) + return True + + async def fail(self, flow_id: str, exc: Exception) -> bool: + async with self._lock: + future = self._pending.get(flow_id) + if future is None: + return False + if not future.done(): + future.set_exception(exc) + return True + + async def discard(self, flow_id: str) -> None: + async with self._lock: + future = self._pending.pop(flow_id, None) + if future and not future.done(): + future.cancel() + + +# Global registry used by server + flow coordinator +callback_registry = OAuthCallbackRegistry() diff --git a/src/mcp_agent/oauth/errors.py b/src/mcp_agent/oauth/errors.py new file mode 100644 index 000000000..3b1b5ce7a --- /dev/null +++ b/src/mcp_agent/oauth/errors.py @@ -0,0 +1,21 @@ +"""Custom exception types for OAuth workflows.""" + + +class OAuthFlowError(Exception): + """Base class for OAuth-related failures.""" + + +class AuthorizationDeclined(OAuthFlowError): + """Raised when the user declines an authorization request.""" + + +class CallbackTimeoutError(OAuthFlowError): + """Raised when the delegated authorization callback is not received in time.""" + + +class TokenRefreshError(OAuthFlowError): + """Raised when refreshing an access token fails irrecoverably.""" + + +class MissingUserIdentityError(OAuthFlowError): + """Raised when an OAuth flow is attempted without a known user identity.""" diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py new file mode 100644 index 000000000..424385538 --- /dev/null +++ b/src/mcp_agent/oauth/flow.py @@ -0,0 +1,218 @@ +"""Delegated OAuth authorization flow coordinator.""" + +from __future__ import annotations + +import asyncio +import time +import uuid +from typing import Any, Dict, Sequence +from urllib.parse import parse_qs, urlparse + +import httpx +from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata +from mcp.server.session import ServerSession + +from mcp_agent.config import MCPOAuthClientSettings, OAuthSettings +from mcp_agent.core.context import Context +from mcp_agent.logging.logger import get_logger +from mcp_agent.oauth.callbacks import callback_registry +from mcp_agent.oauth.errors import ( + AuthorizationDeclined, + CallbackTimeoutError, + MissingUserIdentityError, + OAuthFlowError, +) +from mcp_agent.oauth.identity import OAuthUserIdentity +from mcp_agent.oauth.pkce import ( + generate_code_challenge, + generate_code_verifier, + generate_state, +) +from mcp_agent.oauth.records import TokenRecord + +logger = get_logger(__name__) + + +class AuthorizationFlowCoordinator: + """Handles the interactive OAuth Authorization Code flow via MCP clients.""" + + def __init__(self, *, http_client: httpx.AsyncClient, settings: OAuthSettings): + self._http_client = http_client + self._settings = settings + + async def authorize( + self, + *, + context: Context, + user: OAuthUserIdentity, + server_name: str, + oauth_config: MCPOAuthClientSettings, + resource: str, + authorization_server_url: str, + resource_metadata: ProtectedResourceMetadata, + auth_metadata: OAuthMetadata, + scopes: Sequence[str], + ) -> TokenRecord: + if not user: + raise MissingUserIdentityError( + "Cannot begin OAuth flow without authenticated MCP user" + ) + + client_id = oauth_config.client_id + if not client_id: + raise OAuthFlowError( + f"No OAuth client_id configured for server '{server_name}'." + ) + + redirect_options = list(oauth_config.redirect_uri_options or []) + flow_id = uuid.uuid4().hex + internal_redirect = None + if oauth_config.use_internal_callback and self._settings.callback_base_url: + internal_redirect = f"{self._settings.callback_base_url.rstrip('/')}/internal/oauth/callback/{flow_id}" + redirect_options.insert(0, internal_redirect) + + if not redirect_options: + raise OAuthFlowError( + "No redirect URI options configured for OAuth authorization flow" + ) + + redirect_uri = redirect_options[0] + + code_verifier = generate_code_verifier() + code_challenge = generate_code_challenge(code_verifier) + state = generate_state() + scope_param = " ".join(scopes) + + authorize_url = httpx.URL( + str(auth_metadata.authorization_endpoint) + ).include_query_params( + response_type="code", + client_id=client_id, + redirect_uri=redirect_uri, + scope=scope_param, + state=state, + code_challenge=code_challenge, + code_challenge_method="S256", + resource=resource, + **(oauth_config.extra_authorize_params or {}), + ) + + callback_future = None + if internal_redirect is not None: + callback_future = await callback_registry.create_handle(flow_id) + + request_payload = { + "url": str(authorize_url), + "message": f"Authorization required for {server_name}", + "redirect_uri_options": redirect_options, + } + + result = await _send_auth_request(context, request_payload) + + try: + if result and result.get("url"): + callback_data = _parse_callback_params(result["url"]) + if callback_future is not None: + await callback_registry.discard(flow_id) + elif callback_future is not None: + timeout = self._settings.flow_timeout_seconds or 300 + try: + callback_data = await asyncio.wait_for( + callback_future, timeout=timeout + ) + except asyncio.TimeoutError as exc: + raise CallbackTimeoutError( + f"Timed out waiting for OAuth callback after {timeout} seconds" + ) from exc + else: + raise AuthorizationDeclined( + "Authorization request was declined by the user" + ) + finally: + if callback_future is not None: + await callback_registry.discard(flow_id) + + error = callback_data.get("error") + if error: + description = callback_data.get("error_description") or error + raise OAuthFlowError(f"Authorization server returned error: {description}") + + returned_state = callback_data.get("state") + if returned_state != state: + raise OAuthFlowError("State mismatch detected in OAuth callback") + + authorization_code = callback_data.get("code") + if not authorization_code: + raise OAuthFlowError("Authorization callback did not include code") + + token_endpoint = str(auth_metadata.token_endpoint) + data: Dict[str, Any] = { + "grant_type": "authorization_code", + "code": authorization_code, + "redirect_uri": redirect_uri, + "client_id": client_id, + "code_verifier": code_verifier, + "resource": resource, + } + if scope_param: + data["scope"] = scope_param + if oauth_config.extra_token_params: + data.update(oauth_config.extra_token_params) + + auth = None + if oauth_config.client_secret: + data["client_secret"] = oauth_config.client_secret + + token_response = await self._http_client.post( + token_endpoint, data=data, auth=auth + ) + token_response.raise_for_status() + payload = token_response.json() + + access_token = payload.get("access_token") + if not access_token: + raise OAuthFlowError("Token endpoint response missing access_token") + refresh_token = payload.get("refresh_token") + expires_in = payload.get("expires_in") + expires_at = None + if isinstance(expires_in, (int, float)): + expires_at = time.time() + float(expires_in) + + scope_from_payload = payload.get("scope") + if isinstance(scope_from_payload, str) and scope_from_payload.strip(): + effective_scopes = tuple(scope_from_payload.split()) + else: + effective_scopes = tuple(scopes) + + return TokenRecord( + access_token=access_token, + refresh_token=refresh_token, + expires_at=expires_at, + scopes=effective_scopes, + token_type=str(payload.get("token_type", "Bearer")), + resource=resource, + authorization_server=authorization_server_url, + metadata={"raw": payload}, + ) + + +def _parse_callback_params(url: str) -> Dict[str, str]: + parsed = urlparse(url) + params = {} + params.update({k: v[-1] for k, v in parse_qs(parsed.query).items()}) + if parsed.fragment: + params.update({k: v[-1] for k, v in parse_qs(parsed.fragment).items()}) + return params + + +async def _send_auth_request( + context: Context, payload: Dict[str, Any] +) -> Dict[str, Any]: + session = getattr(context, "upstream_session", None) + if session and isinstance(session, ServerSession): + rpc = getattr(session, "rpc", None) + if rpc and hasattr(rpc, "request"): + return await rpc.request("auth/request", payload) + raise AuthorizationDeclined( + "No upstream MCP session available to prompt user for authorization" + ) diff --git a/src/mcp_agent/oauth/http/__init__.py b/src/mcp_agent/oauth/http/__init__.py new file mode 100644 index 000000000..60479ab9e --- /dev/null +++ b/src/mcp_agent/oauth/http/__init__.py @@ -0,0 +1,5 @@ +"""HTTP client helpers for OAuth flows.""" + +from .auth import OAuthHttpxAuth + +__all__ = ["OAuthHttpxAuth"] diff --git a/src/mcp_agent/oauth/http/auth.py b/src/mcp_agent/oauth/http/auth.py new file mode 100644 index 000000000..29b2028ce --- /dev/null +++ b/src/mcp_agent/oauth/http/auth.py @@ -0,0 +1,68 @@ +"""httpx.Auth adapter that acquires tokens via TokenManager.""" + +from __future__ import annotations + +import httpx + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from mcp_agent.oauth.manager import TokenManager + from mcp_agent.core.context import Context + + +class OAuthHttpxAuth(httpx.Auth): + requires_request_body = True + + def __init__( + self, + *, + token_manager: "TokenManager", + context: "Context", + server_name: str, + server_config, + scopes=None, + ) -> None: + self._token_manager = token_manager + self._context = context + self._server_name = server_name + self._server_config = server_config + self._scopes = list(scopes) if scopes is not None else None + + async def async_auth_flow(self, request: httpx.Request): + token_record = await self._token_manager.ensure_access_token( + context=self._context, + server_name=self._server_name, + server_config=self._server_config, + scopes=self._scopes, + ) + request.headers["Authorization"] = ( + f"{token_record.token_type} {token_record.access_token}" + ) + retry_request = request.copy() + response = yield request + + if response.status_code != 401: + return + + user = self._context.current_user + if user is None: + return + + await self._token_manager.invalidate( + user=user, + resource=token_record.resource or "", + authorization_server=token_record.authorization_server, + scopes=token_record.scopes, + ) + + refreshed_record = await self._token_manager.ensure_access_token( + context=self._context, + server_name=self._server_name, + server_config=self._server_config, + scopes=self._scopes, + ) + retry_request.headers["Authorization"] = ( + f"{refreshed_record.token_type} {refreshed_record.access_token}" + ) + yield retry_request diff --git a/src/mcp_agent/oauth/identity.py b/src/mcp_agent/oauth/identity.py new file mode 100644 index 000000000..54c6d6fed --- /dev/null +++ b/src/mcp_agent/oauth/identity.py @@ -0,0 +1,46 @@ +"""Utilities for representing authenticated MCP users.""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Dict + +from .access_token import MCPAccessToken + + +@dataclass(frozen=True) +class OAuthUserIdentity: + """Canonical identifier for an authenticated user within MCP Agent.""" + + provider: str + subject: str + email: str | None = None + claims: Dict[str, Any] | None = None + + @property + def cache_key(self) -> str: + """Return a deterministic cache key for token storage.""" + return f"{self.provider}:{self.subject}" + + @classmethod + def from_access_token( + cls, token: MCPAccessToken | None + ) -> "OAuthUserIdentity" | None: + """Build an identity from an enriched access token.""" + if token is None: + return None + subject = token.subject or _claim(token, "sub") + if not subject: + return None + provider = token.issuer or _claim(token, "iss") or "unknown" + email = ( + token.email or _claim(token, "email") or _claim(token, "preferred_username") + ) + claims = token.claims or {} + return cls(provider=provider, subject=subject, email=email, claims=claims) + + +def _claim(token: MCPAccessToken, key: str) -> Any | None: + if not token.claims: + return None + return token.claims.get(key) diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py new file mode 100644 index 000000000..62d0308b9 --- /dev/null +++ b/src/mcp_agent/oauth/manager.py @@ -0,0 +1,249 @@ +"""Token management for downstream OAuth-protected MCP servers.""" + +from __future__ import annotations + +import asyncio +import time +from collections import defaultdict +from typing import Dict, Iterable, Sequence, TYPE_CHECKING + +import httpx +from httpx import URL + +from mcp_agent.config import MCPOAuthClientSettings, OAuthSettings +from mcp_agent.logging.logger import get_logger +from mcp_agent.oauth.errors import ( + MissingUserIdentityError, + OAuthFlowError, + TokenRefreshError, +) +from mcp_agent.oauth.flow import AuthorizationFlowCoordinator +from mcp_agent.oauth.identity import OAuthUserIdentity +from mcp_agent.oauth.metadata import ( + fetch_authorization_server_metadata, + fetch_resource_metadata, + normalize_resource, + select_authorization_server, +) +from mcp_agent.oauth.records import TokenRecord +from mcp_agent.oauth.store import ( + InMemoryTokenStore, + TokenStore, + TokenStoreKey, + scope_fingerprint, +) + +if TYPE_CHECKING: + from mcp_agent.core.context import Context + +logger = get_logger(__name__) + + +class TokenManager: + """High-level orchestrator for acquiring and refreshing OAuth tokens.""" + + def __init__( + self, + *, + http_client: httpx.AsyncClient | None = None, + token_store: TokenStore | None = None, + settings: OAuthSettings | None = None, + ) -> None: + self._settings = settings or OAuthSettings() + self._token_store = token_store or InMemoryTokenStore() + self._http_client = http_client or httpx.AsyncClient(timeout=30.0) + self._own_http_client = http_client is None + self._flow = AuthorizationFlowCoordinator( + http_client=self._http_client, settings=self._settings + ) + self._locks: Dict[TokenStoreKey, asyncio.Lock] = defaultdict(asyncio.Lock) + self._resource_metadata_cache: Dict[str, tuple[float, object]] = {} + self._auth_metadata_cache: Dict[str, tuple[float, object]] = {} + + async def ensure_access_token( + self, + *, + context: "Context", + server_name: str, + server_config, + scopes: Iterable[str] | None = None, + ) -> TokenRecord: + oauth_config: MCPOAuthClientSettings | None = None + if server_config and server_config.auth: + oauth_config = getattr(server_config.auth, "oauth", None) + if not oauth_config or not oauth_config.enabled: + raise OAuthFlowError( + f"Server '{server_name}' is not configured for OAuth authentication" + ) + + user = context.current_user + if not user: + raise MissingUserIdentityError( + "No authenticated MCP user available for delegated OAuth flow" + ) + + resource_hint = oauth_config.resource + server_url = getattr(server_config, "url", None) + resource = normalize_resource(resource_hint, server_url) + + metadata_url = str(URL(resource).join("/.well-known/oauth-protected-resource")) + resource_metadata = await self._get_resource_metadata(metadata_url) + auth_server_url = select_authorization_server( + resource_metadata, oauth_config.authorization_server + ) + auth_metadata = await self._get_authorization_metadata(auth_server_url) + + scope_list = ( + list(scopes) if scopes is not None else list(oauth_config.scopes or []) + ) + key = TokenStoreKey( + user_key=user.cache_key, + resource=resource, + authorization_server=auth_server_url, + scope_fingerprint=scope_fingerprint(scope_list), + ) + + lock = self._locks[key] + async with lock: + record = await self._token_store.get(key) + leeway = ( + self._settings.token_store.refresh_leeway_seconds + if self._settings and self._settings.token_store + else 60 + ) + if record and not record.is_expired(leeway_seconds=leeway): + return record + + if record and record.refresh_token: + try: + refreshed = await self._refresh_token( + record, + oauth_config=oauth_config, + auth_metadata=auth_metadata, + resource=resource, + scopes=scope_list, + ) + except TokenRefreshError: + await self._token_store.delete(key) + else: + if refreshed: + await self._token_store.set(key, refreshed) + return refreshed + await self._token_store.delete(key) + + # Need to run full authorization flow + record = await self._flow.authorize( + context=context, + user=user, + server_name=server_name, + oauth_config=oauth_config, + resource=resource, + authorization_server_url=auth_server_url, + resource_metadata=resource_metadata, + auth_metadata=auth_metadata, + scopes=scope_list, + ) + await self._token_store.set(key, record) + return record + + async def invalidate( + self, + *, + user: OAuthUserIdentity, + resource: str, + authorization_server: str | None, + scopes: Iterable[str], + ) -> None: + key = TokenStoreKey( + user_key=user.cache_key, + resource=resource, + authorization_server=authorization_server, + scope_fingerprint=scope_fingerprint(scopes), + ) + await self._token_store.delete(key) + + async def _refresh_token( + self, + record: TokenRecord, + *, + oauth_config: MCPOAuthClientSettings, + auth_metadata, + resource: str, + scopes: Sequence[str], + ) -> TokenRecord | None: + if not record.refresh_token: + return None + + token_endpoint = str(auth_metadata.token_endpoint) + data = { + "grant_type": "refresh_token", + "refresh_token": record.refresh_token, + "client_id": oauth_config.client_id, + "resource": resource, + } + if scopes: + data["scope"] = " ".join(scopes) + if oauth_config.client_secret: + data["client_secret"] = oauth_config.client_secret + if oauth_config.extra_token_params: + data.update(oauth_config.extra_token_params) + + try: + response = await self._http_client.post(token_endpoint, data=data) + except httpx.HTTPError as exc: + logger.warning("Refresh token request failed", exc_info=True) + raise TokenRefreshError(str(exc)) from exc + + if response.status_code != 200: + logger.warning( + "Refresh token request returned non-success status", + data={"status_code": response.status_code}, + ) + return None + + payload = response.json() + new_access = payload.get("access_token") + if not new_access: + return None + new_refresh = payload.get("refresh_token", record.refresh_token) + expires_in = payload.get("expires_in") + new_expires = record.expires_at + if isinstance(expires_in, (int, float)): + new_expires = time.time() + float(expires_in) + + scope_from_payload = payload.get("scope") + if isinstance(scope_from_payload, str) and scope_from_payload.strip(): + scopes_tuple = tuple(scope_from_payload.split()) + else: + scopes_tuple = record.scopes + + return TokenRecord( + access_token=new_access, + refresh_token=new_refresh, + expires_at=new_expires, + scopes=scopes_tuple, + token_type=str(payload.get("token_type", record.token_type)), + resource=record.resource, + authorization_server=record.authorization_server, + metadata={"raw": payload}, + ) + + async def _get_resource_metadata(self, url: str): + cached = self._resource_metadata_cache.get(url) + if cached and time.time() - cached[0] < 300: + return cached[1] + metadata = await fetch_resource_metadata(self._http_client, url) + self._resource_metadata_cache[url] = (time.time(), metadata) + return metadata + + async def _get_authorization_metadata(self, url: str): + cached = self._auth_metadata_cache.get(url) + if cached and time.time() - cached[0] < 300: + return cached[1] + metadata = await fetch_authorization_server_metadata(self._http_client, url) + self._auth_metadata_cache[url] = (time.time(), metadata) + return metadata + + async def aclose(self) -> None: + if self._own_http_client: + await self._http_client.aclose() diff --git a/src/mcp_agent/oauth/metadata.py b/src/mcp_agent/oauth/metadata.py new file mode 100644 index 000000000..24ac6b5c8 --- /dev/null +++ b/src/mcp_agent/oauth/metadata.py @@ -0,0 +1,60 @@ +"""Helpers for OAuth metadata discovery.""" + +from __future__ import annotations + +from typing import List + +import httpx +from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata + +from mcp_agent.logging.logger import get_logger + +logger = get_logger(__name__) + + +async def fetch_resource_metadata( + client: httpx.AsyncClient, + resource_metadata_url: str, +) -> ProtectedResourceMetadata: + response = await client.get(resource_metadata_url) + response.raise_for_status() + data = response.json() + return ProtectedResourceMetadata.model_validate(data) + + +async def fetch_authorization_server_metadata( + client: httpx.AsyncClient, + metadata_url: str, +) -> OAuthMetadata: + response = await client.get(metadata_url) + response.raise_for_status() + return OAuthMetadata.model_validate(response.json()) + + +def select_authorization_server( + metadata: ProtectedResourceMetadata, + preferred: str | None = None, +) -> str: + candidates: List[str] = list(metadata.authorization_servers or []) + if not candidates: + raise ValueError( + "Protected resource metadata did not include authorization servers" + ) + + if preferred and preferred in candidates: + return preferred + + if preferred: + logger.warning( + "Preferred authorization server not listed; falling back to first entry", + data={"preferred": preferred, "candidates": candidates}, + ) + return candidates[0] + + +def normalize_resource(resource: str | None, fallback: str | None) -> str: + if resource: + return resource.rstrip("/") + if fallback: + return fallback.rstrip("/") + raise ValueError("Unable to determine resource identifier for OAuth flow") diff --git a/src/mcp_agent/oauth/pkce.py b/src/mcp_agent/oauth/pkce.py new file mode 100644 index 000000000..1709dc332 --- /dev/null +++ b/src/mcp_agent/oauth/pkce.py @@ -0,0 +1,27 @@ +"""PKCE utilities.""" + +from __future__ import annotations + +import base64 +import hashlib +import secrets + + +def generate_code_verifier(length: int = 64) -> str: + if length < 43 or length > 128: + raise ValueError("PKCE code verifier length must be between 43 and 128") + # token_urlsafe returns ~1.3 chars per byte; adjust to reach desired length + needed_bytes = int(length * 0.8) + 1 + verifier = secrets.token_urlsafe(needed_bytes) + if len(verifier) < length: + verifier = (verifier + secrets.token_urlsafe(needed_bytes))[:length] + return verifier[:length] + + +def generate_code_challenge(verifier: str) -> str: + digest = hashlib.sha256(verifier.encode()).digest() + return base64.urlsafe_b64encode(digest).rstrip(b"=").decode() + + +def generate_state(length: int = 32) -> str: + return secrets.token_urlsafe(length) diff --git a/src/mcp_agent/oauth/records.py b/src/mcp_agent/oauth/records.py new file mode 100644 index 000000000..2a7c47be0 --- /dev/null +++ b/src/mcp_agent/oauth/records.py @@ -0,0 +1,46 @@ +"""Shared record types for OAuth token management.""" + +from __future__ import annotations + +from datetime import datetime, timezone +from typing import Any, Dict, Tuple + +from pydantic import BaseModel, Field + + +class TokenRecord(BaseModel): + """Persisted token bundle for a user/resource/authorization server combination.""" + + access_token: str + refresh_token: str | None = None + scopes: Tuple[str, ...] = () + expires_at: float | None = None + token_type: str = "Bearer" + resource: str | None = None + authorization_server: str | None = None + obtained_at: float = Field( + default_factory=lambda: datetime.now(tz=timezone.utc).timestamp() + ) + metadata: Dict[str, Any] = Field(default_factory=dict) + + def is_expired(self, *, leeway_seconds: int = 0) -> bool: + if self.expires_at is None: + return False + now = datetime.now(tz=timezone.utc).timestamp() + return now >= (self.expires_at - leeway_seconds) + + def with_tokens( + self, + *, + access_token: str, + refresh_token: str | None, + expires_at: float | None, + ) -> "TokenRecord": + return self.model_copy( + update={ + "access_token": access_token, + "refresh_token": refresh_token, + "expires_at": expires_at, + "obtained_at": datetime.now(tz=timezone.utc).timestamp(), + } + ) diff --git a/src/mcp_agent/oauth/store/__init__.py b/src/mcp_agent/oauth/store/__init__.py new file mode 100644 index 000000000..226953f43 --- /dev/null +++ b/src/mcp_agent/oauth/store/__init__.py @@ -0,0 +1,11 @@ +"""Token store implementations.""" + +from .base import TokenStore, TokenStoreKey, scope_fingerprint +from .in_memory import InMemoryTokenStore + +__all__ = [ + "TokenStore", + "TokenStoreKey", + "scope_fingerprint", + "InMemoryTokenStore", +] diff --git a/src/mcp_agent/oauth/store/base.py b/src/mcp_agent/oauth/store/base.py new file mode 100644 index 000000000..a03f7da83 --- /dev/null +++ b/src/mcp_agent/oauth/store/base.py @@ -0,0 +1,33 @@ +"""Abstract token store definition.""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Iterable, Protocol + +from ..records import TokenRecord + + +@dataclass(frozen=True) +class TokenStoreKey: + """Uniquely identifies a cached token.""" + + user_key: str + resource: str + authorization_server: str | None + scope_fingerprint: str + + +def scope_fingerprint(scopes: Iterable[str]) -> str: + """Return a deterministic fingerprint for a scope list.""" + return " ".join(sorted({scope.strip() for scope in scopes if scope})) + + +class TokenStore(Protocol): + """Persistence interface for OAuth tokens.""" + + async def get(self, key: TokenStoreKey) -> TokenRecord | None: ... + + async def set(self, key: TokenStoreKey, record: TokenRecord) -> None: ... + + async def delete(self, key: TokenStoreKey) -> None: ... diff --git a/src/mcp_agent/oauth/store/in_memory.py b/src/mcp_agent/oauth/store/in_memory.py new file mode 100644 index 000000000..d1aa40460 --- /dev/null +++ b/src/mcp_agent/oauth/store/in_memory.py @@ -0,0 +1,30 @@ +"""In-memory token store for local development and testing.""" + +from __future__ import annotations + +import asyncio +from typing import Dict + +from .base import TokenStore, TokenStoreKey +from ..records import TokenRecord + + +class InMemoryTokenStore(TokenStore): + def __init__(self) -> None: + self._records: Dict[TokenStoreKey, TokenRecord] = {} + self._lock = asyncio.Lock() + + async def get(self, key: TokenStoreKey) -> TokenRecord | None: + async with self._lock: + record = self._records.get(key) + if record is None: + return None + return record + + async def set(self, key: TokenStoreKey, record: TokenRecord) -> None: + async with self._lock: + self._records[key] = record + + async def delete(self, key: TokenStoreKey) -> None: + async with self._lock: + self._records.pop(key, None) diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index ec56574c1..dfdbccd4c 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -12,8 +12,13 @@ import asyncio from mcp.server.fastmcp import Context as MCPContext, FastMCP +from mcp.server.fastmcp.server import AuthSettings +from mcp.server.auth.middleware.auth_context import ( + AuthenticatedUser, + auth_context_var, +) from starlette.requests import Request -from starlette.responses import JSONResponse +from starlette.responses import HTMLResponse, JSONResponse from mcp.server.fastmcp.exceptions import ToolError from mcp.server.fastmcp.tools import Tool as FastTool @@ -30,6 +35,9 @@ from mcp_agent.logging.logger import get_logger from mcp_agent.logging.logger import LoggingConfig from mcp_agent.mcp.mcp_server_registry import ServerRegistry +from mcp_agent.oauth.identity import OAuthUserIdentity +from mcp_agent.oauth.callbacks import callback_registry +from mcp_agent.server.token_verifier import MCPAgentTokenVerifier if TYPE_CHECKING: from mcp_agent.core.context import Context @@ -178,6 +186,32 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: # ctx.session property might raise ValueError if context not available pass + # Capture authenticated user information if available + identity: OAuthUserIdentity | None = None + try: + auth_user = auth_context_var.get() + except LookupError: + auth_user = None + + if isinstance(auth_user, AuthenticatedUser): + access_token = getattr(auth_user, "access_token", None) + if access_token is not None: + # Prefer enriched token instances but fall back to raw data if necessary + try: + from mcp_agent.oauth.access_token import MCPAccessToken + + if isinstance(access_token, MCPAccessToken): + identity = OAuthUserIdentity.from_access_token(access_token) + else: + token_dict = getattr(access_token, "model_dump", None) + if callable(token_dict): + maybe_token = MCPAccessToken.model_validate( + access_token.model_dump() + ) + identity = OAuthUserIdentity.from_access_token(maybe_token) + except Exception: + identity = None + if session is not None: app: MCPApp | None = _get_attached_app(ctx.fastmcp) if app is not None and getattr(app, "context", None) is not None: @@ -185,9 +219,15 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: # Previously captured; no need to keep old value # Use direct assignment for Pydantic model app.context.upstream_session = session + app.context.current_user = identity return else: return + else: + # Update identity even if we failed to resolve a session + app: MCPApp | None = _get_attached_app(ctx.fastmcp) + if app is not None and getattr(app, "context", None) is not None: + app.context.current_user = identity def _resolve_workflows_and_context( @@ -322,6 +362,34 @@ def create_mcp_server_for_app(app: MCPApp, **kwargs: Any) -> FastMCP: A configured FastMCP server instance """ + auth_settings_config = None + try: + if app.context and app.context.config: + auth_settings_config = app.context.config.authorization + except Exception: + auth_settings_config = None + + effective_auth_settings: AuthSettings | None = None + token_verifier: MCPAgentTokenVerifier | None = None + owns_token_verifier = False + if auth_settings_config and auth_settings_config.enabled: + try: + effective_auth_settings = AuthSettings( + issuer_url=auth_settings_config.issuer_url, # type: ignore[arg-type] + resource_server_url=auth_settings_config.resource_server_url, # type: ignore[arg-type] + service_documentation_url=auth_settings_config.service_documentation_url, # type: ignore[arg-type] + required_scopes=auth_settings_config.required_scopes or None, + ) + token_verifier = MCPAgentTokenVerifier(auth_settings_config) + except Exception as exc: + logger.error( + "Failed to configure authorization server integration", + exc_info=True, + data={"error": str(exc)}, + ) + effective_auth_settings = None + token_verifier = None + # Create a lifespan function specific to this app @asynccontextmanager async def app_specific_lifespan(mcp: FastMCP) -> AsyncIterator[ServerContext]: @@ -341,7 +409,11 @@ async def app_specific_lifespan(mcp: FastMCP) -> AsyncIterator[ServerContext]: yield server_context finally: # Don't clean up the MCPApp here - let the caller handle that - pass + if owns_token_verifier and token_verifier is not None: + try: + await token_verifier.aclose() + except Exception: + pass # Helper: install internal HTTP routes (not MCP tools) def _install_internal_routes(mcp_server: FastMCP) -> None: @@ -358,6 +430,41 @@ def _get_fallback_upstream_session() -> Any | None: return None return None + @mcp_server.custom_route( + "/internal/oauth/callback/{flow_id}", + methods=["GET", "POST"], + include_in_schema=False, + ) + async def _oauth_callback(request: Request): + flow_id = request.path_params.get("flow_id") + if not flow_id: + return JSONResponse({"error": "missing_flow_id"}, status_code=400) + + payload: Dict[str, Any] = {} + try: + payload.update({k: v for k, v in request.query_params.multi_items()}) + except Exception: + payload.update(dict(request.query_params)) + + if request.method.upper() == "POST": + content_type = request.headers.get("content-type", "") + try: + if "application/json" in content_type: + body_data = await request.json() + else: + form = await request.form() + body_data = {k: v for k, v in form.multi_items()} + except Exception: + body_data = {} + payload.update(body_data) + + delivered = await callback_registry.deliver(flow_id, payload) + if not delivered: + return JSONResponse({"error": "unknown_flow"}, status_code=404) + + html = """

Authorization complete.

You may close this window and return to MCP Agent.

""" + return HTMLResponse(html) + @mcp_server.custom_route( "/internal/session/by-run/{execution_id}/notify", methods=["POST"], @@ -1039,6 +1146,11 @@ async def _internal_human_prompts(request: Request): except Exception: pass else: + if "auth" not in kwargs and effective_auth_settings is not None: + kwargs["auth"] = effective_auth_settings + if "token_verifier" not in kwargs and token_verifier is not None: + kwargs["token_verifier"] = token_verifier + owns_token_verifier = True mcp = FastMCP( name=app.name or "mcp_agent_server", # TODO: saqadri (MAC) - create a much more detailed description diff --git a/src/mcp_agent/server/token_verifier.py b/src/mcp_agent/server/token_verifier.py new file mode 100644 index 000000000..324f389b6 --- /dev/null +++ b/src/mcp_agent/server/token_verifier.py @@ -0,0 +1,138 @@ +"""Token verification for MCP Agent Cloud authorization server.""" + +from __future__ import annotations + +import asyncio +from datetime import datetime, timezone +from typing import Any, Dict + +import httpx + +from mcp.server.auth.provider import AccessToken +from mcp.server.auth.provider import TokenVerifier + +from mcp_agent.config import MCPAuthorizationServerSettings +from mcp_agent.logging.logger import get_logger +from mcp_agent.oauth.access_token import MCPAccessToken + +logger = get_logger(__name__) + + +class MCPAgentTokenVerifier(TokenVerifier): + """Verify bearer tokens issued by the MCP Agent Cloud authorization server.""" + + def __init__(self, settings: MCPAuthorizationServerSettings): + if not settings.introspection_endpoint: + raise ValueError( + "introspection_endpoint must be configured to verify tokens" + ) + self._settings = settings + timeout = httpx.Timeout(10.0) + self._client = httpx.AsyncClient(timeout=timeout) + self._cache: Dict[str, MCPAccessToken] = {} + self._lock = asyncio.Lock() + + async def verify_token(self, token: str) -> AccessToken | None: # type: ignore[override] + cached = self._cache.get(token) + if cached and not cached.is_expired(leeway_seconds=30): + return cached + + async with self._lock: + # Double-check cache after acquiring lock to avoid duplicate refresh + cached = self._cache.get(token) + if cached and not cached.is_expired(leeway_seconds=30): + return cached + + verified = await self._introspect(token) + if verified: + self._cache[token] = verified + else: + self._cache.pop(token, None) + return verified + + async def _introspect(self, token: str) -> MCPAccessToken | None: + data = {"token": token} + auth = None + if ( + self._settings.introspection_client_id + and self._settings.introspection_client_secret + ): + auth = httpx.BasicAuth( + self._settings.introspection_client_id, + self._settings.introspection_client_secret, + ) + + try: + response = await self._client.post( + str(self._settings.introspection_endpoint), + data=data, + auth=auth, + ) + except httpx.HTTPError as exc: + logger.warning(f"Token introspection request failed: {exc}") + return None + + if response.status_code != 200: + logger.warning( + "Token introspection returned non-success status", + data={"status_code": response.status_code}, + ) + return None + + try: + payload: Dict[str, Any] = response.json() + except ValueError: + logger.warning("Token introspection response was not valid JSON") + return None + + if not payload.get("active"): + return None + + if self._settings.issuer_url and payload.get("iss"): + if str(payload.get("iss")) != str(self._settings.issuer_url): + logger.warning( + "Token issuer mismatch", + data={ + "expected": str(self._settings.issuer_url), + "actual": payload.get("iss"), + }, + ) + return None + + token_model = MCPAccessToken.from_introspection( + token, + payload, + resource_hint=str(self._settings.resource_server_url) + if self._settings.resource_server_url + else None, + ) + + # Respect cache TTL limit if configured + ttl_seconds = max(0, self._settings.token_cache_ttl_seconds or 0) + if ttl_seconds and token_model.expires_at is not None: + now_ts = datetime.now(tz=timezone.utc).timestamp() + cache_limit = now_ts + ttl_seconds + token_model.expires_at = min(token_model.expires_at, cache_limit) + + # Optionally enforce required scopes + required_scopes = self._settings.required_scopes or [] + missing = [ + scope for scope in required_scopes if scope not in token_model.scopes + ] + if missing: + logger.warning( + "Token missing required scopes", + data={"missing_scopes": missing}, + ) + return None + + return token_model + + async def aclose(self) -> None: + await self._client.aclose() + + async def __aenter__(self) -> "MCPAgentTokenVerifier": + return self + + async def __aexit__(self, exc_type, exc, tb) -> None: + await self.aclose() diff --git a/tests/test_oauth_utils.py b/tests/test_oauth_utils.py new file mode 100644 index 000000000..87488c41a --- /dev/null +++ b/tests/test_oauth_utils.py @@ -0,0 +1,85 @@ +import time +import pathlib +import sys + +import pytest + +PROJECT_ROOT = pathlib.Path(__file__).resolve().parents[1] +SRC_ROOT = PROJECT_ROOT / "src" +if str(SRC_ROOT) not in sys.path: + sys.path.insert(0, str(SRC_ROOT)) + +try: + from mcp_agent.oauth.metadata import normalize_resource, select_authorization_server + from mcp_agent.oauth.records import TokenRecord + from mcp_agent.oauth.store import ( + InMemoryTokenStore, + TokenStoreKey, + scope_fingerprint, + ) + from mcp.shared.auth import ProtectedResourceMetadata +except ModuleNotFoundError: # pragma: no cover - optional dependency + pytest.skip("MCP SDK not installed", allow_module_level=True) + + +def test_scope_fingerprint_ordering(): + scopes = ["email", "profile", "email"] + fingerprint = scope_fingerprint(scopes) + assert fingerprint == "email profile" + + +def test_token_record_expiry(): + record = TokenRecord( + access_token="tok", + expires_at=time.time() + 5, + ) + assert not record.is_expired(leeway_seconds=0) + assert record.is_expired(leeway_seconds=10) + + +@pytest.mark.asyncio +async def test_in_memory_token_store_round_trip(): + store = InMemoryTokenStore() + key = TokenStoreKey( + user_key="provider:subject", + resource="https://example.com", + authorization_server="https://auth.example.com", + scope_fingerprint="scope", + ) + record = TokenRecord(access_token="abc123") + + await store.set(key, record) + fetched = await store.get(key) + assert fetched.access_token == record.access_token + await store.delete(key) + assert await store.get(key) is None + + +def test_select_authorization_server_prefers_explicit(): + metadata = ProtectedResourceMetadata( + resource="https://example.com", + authorization_servers=[ + "https://auth1.example.com", + "https://auth2.example.com", + ], + ) + assert ( + select_authorization_server(metadata, "https://auth2.example.com") + == "https://auth2.example.com" + ) + assert ( + select_authorization_server(metadata, "https://unknown.example.com") + == "https://auth1.example.com" + ) + + +def test_normalize_resource_with_fallback(): + assert ( + normalize_resource("https://example.com/api", None) == "https://example.com/api" + ) + assert ( + normalize_resource(None, "https://fallback.example.com") + == "https://fallback.example.com" + ) + with pytest.raises(ValueError): + normalize_resource(None, None) From efb63e1d4caf7c5d6b1602344f7f773065c4a9a8 Mon Sep 17 00:00:00 2001 From: Roman van der Krogt Date: Wed, 24 Sep 2025 21:29:41 +0100 Subject: [PATCH 05/25] add audience validation --- src/mcp_agent/config.py | 11 ++ src/mcp_agent/oauth/access_token.py | 43 ++++- src/mcp_agent/oauth/metadata.py | 2 +- src/mcp_agent/server/token_verifier.py | 64 ++++++- tests/test_audience_validation.py | 250 +++++++++++++++++++++++++ tests/test_oauth_utils.py | 7 +- 6 files changed, 366 insertions(+), 11 deletions(-) create mode 100644 tests/test_audience_validation.py diff --git a/src/mcp_agent/config.py b/src/mcp_agent/config.py index d72f972ec..59d8ef84d 100644 --- a/src/mcp_agent/config.py +++ b/src/mcp_agent/config.py @@ -49,6 +49,14 @@ class MCPAuthorizationServerSettings(BaseModel): introspection_client_secret: str | None = None token_cache_ttl_seconds: int = Field(300, ge=0) + # RFC 9068 audience validation settings + # TODO: this should really depend on the app_id, or config_id so that we can enforce unique values. + # To be removed and replaced with a fixed value once we have app_id/config_id support + expected_audiences: List[str] = Field(default_factory=list) + """List of audience values this resource server accepts. + MUST be configured to comply with RFC 9068 audience validation. + Audience validation is always enforced when authorization is enabled.""" + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) @model_validator(mode="after") @@ -59,6 +67,9 @@ def _validate_required_urls(self) -> "MCPAuthorizationServerSettings": missing.append("issuer_url") if self.resource_server_url is None: missing.append("resource_server_url") + # Validate audience configuration for RFC 9068 compliance + if not self.expected_audiences: + missing.append("expected_audiences (required for RFC 9068 compliance)") if missing: raise ValueError( " | ".join(missing) + " must be set when authorization is enabled" diff --git a/src/mcp_agent/oauth/access_token.py b/src/mcp_agent/oauth/access_token.py index fe3d4bab4..0ec75a190 100644 --- a/src/mcp_agent/oauth/access_token.py +++ b/src/mcp_agent/oauth/access_token.py @@ -16,6 +16,7 @@ class MCPAccessToken(AccessToken): issuer: str | None = None resource_indicator: str | None = None claims: Dict[str, Any] | None = None + audiences: List[str] | None = None @classmethod def from_introspection( @@ -39,12 +40,9 @@ def from_introspection( else: scopes = [] - audience = payload.get("resource") or payload.get("aud") - if isinstance(audience, (list, tuple)): - audience_value = _first_non_empty(*audience) - else: - audience_value = audience - + # Enhanced audience extraction for RFC 9068 compliance + audiences = _extract_all_audiences(payload) + audience_value = audiences[0] if audiences else None resource = resource_hint or audience_value expires_at = payload.get("exp") @@ -61,6 +59,7 @@ def from_introspection( ), issuer=payload.get("iss"), resource_indicator=resource, + audiences=audiences, claims=payload, ) @@ -71,6 +70,38 @@ def is_expired(self, *, leeway_seconds: int = 0) -> bool: now = datetime.now(tz=timezone.utc).timestamp() return now >= (self.expires_at - leeway_seconds) + def validate_audience(self, expected_audiences: List[str]) -> bool: + """Validate this token's audience claims against expected values per RFC 9068.""" + if not self.audiences: + return False + if not expected_audiences: + return False + + return bool(set(expected_audiences).intersection(set(self.audiences))) + + +def _extract_all_audiences(payload: Dict[str, Any]) -> List[str]: + """Extract all audience values from token payload per RFC 9068.""" + audiences = [] + + # Extract from 'aud' claim + aud_claim = payload.get("aud") + if aud_claim: + if isinstance(aud_claim, str): + audiences.append(aud_claim) + elif isinstance(aud_claim, (list, tuple)): + audiences.extend([str(aud) for aud in aud_claim if aud]) + + # Extract from 'resource' claim (OAuth 2.0 resource indicators) + resource_claim = payload.get("resource") + if resource_claim: + if isinstance(resource_claim, str): + audiences.append(resource_claim) + elif isinstance(resource_claim, (list, tuple)): + audiences.extend([str(res) for res in resource_claim if res]) + + return list(set(audiences)) # Remove duplicates + def _first_non_empty(*values: Any) -> Any | None: for value in values: diff --git a/src/mcp_agent/oauth/metadata.py b/src/mcp_agent/oauth/metadata.py index 24ac6b5c8..c4986b011 100644 --- a/src/mcp_agent/oauth/metadata.py +++ b/src/mcp_agent/oauth/metadata.py @@ -35,7 +35,7 @@ def select_authorization_server( metadata: ProtectedResourceMetadata, preferred: str | None = None, ) -> str: - candidates: List[str] = list(metadata.authorization_servers or []) + candidates: List[str] = [str(url) for url in (metadata.authorization_servers or [])] if not candidates: raise ValueError( "Protected resource metadata did not include authorization servers" diff --git a/src/mcp_agent/server/token_verifier.py b/src/mcp_agent/server/token_verifier.py index 324f389b6..799341585 100644 --- a/src/mcp_agent/server/token_verifier.py +++ b/src/mcp_agent/server/token_verifier.py @@ -4,7 +4,7 @@ import asyncio from datetime import datetime, timezone -from typing import Any, Dict +from typing import Any, Dict, List import httpx @@ -99,6 +99,18 @@ async def _introspect(self, token: str) -> MCPAccessToken | None: ) return None + # RFC 9068 Audience Validation (always enforced) + token_audiences = self._extract_audiences(payload) + if not self._validate_audiences(token_audiences): + logger.warning( + "Token audience validation failed", + data={ + "token_audiences": token_audiences, + "expected_audiences": self._settings.expected_audiences, + }, + ) + return None + token_model = MCPAccessToken.from_introspection( token, payload, @@ -128,6 +140,56 @@ async def _introspect(self, token: str) -> MCPAccessToken | None: return token_model + def _extract_audiences(self, payload: Dict[str, Any]) -> List[str]: + """Extract audience values from token payload according to RFC 9068.""" + audiences = [] + + # Check both 'aud' and 'resource' claims (OAuth 2.0 resource indicators) + aud_claim = payload.get("aud") + resource_claim = payload.get("resource") + + # Handle 'aud' claim (can be string or array) + if aud_claim: + if isinstance(aud_claim, str): + audiences.append(aud_claim) + elif isinstance(aud_claim, (list, tuple)): + audiences.extend([str(aud) for aud in aud_claim if aud]) + + # Handle 'resource' claim (OAuth 2.0 resource indicator) + if resource_claim: + if isinstance(resource_claim, str): + audiences.append(resource_claim) + elif isinstance(resource_claim, (list, tuple)): + audiences.extend([str(res) for res in resource_claim if res]) + + return list(set(audiences)) # Remove duplicates + + def _validate_audiences(self, token_audiences: List[str]) -> bool: + """Validate token audiences against expected values per RFC 9068.""" + if not token_audiences: + logger.warning("Token contains no audience claims") + return False + + if not self._settings.expected_audiences: + logger.warning("No expected audiences configured for validation") + return False + + # RFC 9068: Token MUST contain at least one expected audience + valid_audiences = set(self._settings.expected_audiences) + token_audience_set = set(token_audiences) + + if not valid_audiences.intersection(token_audience_set): + logger.warning( + "Token audience validation failed - no matching audiences", + data={ + "token_audiences": list(token_audience_set), + "valid_audiences": list(valid_audiences), + }, + ) + return False + + return True + async def aclose(self) -> None: await self._client.aclose() diff --git a/tests/test_audience_validation.py b/tests/test_audience_validation.py new file mode 100644 index 000000000..058774fe1 --- /dev/null +++ b/tests/test_audience_validation.py @@ -0,0 +1,250 @@ +"""Test audience validation functionality for RFC 9068 compliance.""" + +import pytest +from unittest.mock import Mock, AsyncMock +import httpx +from mcp_agent.config import MCPAuthorizationServerSettings +from mcp_agent.server.token_verifier import MCPAgentTokenVerifier +from mcp_agent.oauth.access_token import MCPAccessToken, _extract_all_audiences + + +@pytest.mark.asyncio +async def test_audience_validation_success(): + """Test successful audience validation with matching audiences.""" + settings = MCPAuthorizationServerSettings( + enabled=True, + issuer_url="https://auth.example.com", + resource_server_url="https://api.example.com", + introspection_endpoint="https://auth.example.com/introspect", + expected_audiences=["https://api.example.com", "api.example.com"], + ) + + # Mock successful introspection response with valid audience + payload = { + "active": True, + "aud": ["https://api.example.com", "other.example.com"], + "sub": "user123", + "exp": 1234567890, + "iss": "https://auth.example.com/", + } + + token = MCPAccessToken.from_introspection("test_token", payload) + assert token.validate_audience(settings.expected_audiences) is True + + +@pytest.mark.asyncio +async def test_audience_validation_failure(): + """Test audience validation failure with non-matching audiences.""" + settings = MCPAuthorizationServerSettings( + enabled=True, + issuer_url="https://auth.example.com", + resource_server_url="https://api.example.com", + introspection_endpoint="https://auth.example.com/introspect", + expected_audiences=["https://api.example.com"], + ) + + payload = { + "active": True, + "aud": ["https://malicious.example.com"], # Wrong audience + "sub": "user123", + "exp": 1234567890, + "iss": "https://auth.example.com/", + } + + token = MCPAccessToken.from_introspection("test_token", payload) + assert token.validate_audience(settings.expected_audiences) is False + + +@pytest.mark.asyncio +async def test_resource_claim_audience_validation(): + """Test audience validation using OAuth 2.0 resource indicators.""" + settings = MCPAuthorizationServerSettings( + enabled=True, + issuer_url="https://auth.example.com", + resource_server_url="https://api.example.com", + introspection_endpoint="https://auth.example.com/introspect", + expected_audiences=["https://api.example.com"], + ) + + # Token with resource claim instead of aud claim + payload = { + "active": True, + "resource": "https://api.example.com", # OAuth 2.0 resource indicator + "sub": "user123", + "exp": 1234567890, + "iss": "https://auth.example.com/", + } + + token = MCPAccessToken.from_introspection("test_token", payload) + assert token.validate_audience(settings.expected_audiences) is True + + +@pytest.mark.asyncio +async def test_multiple_audiences_extraction(): + """Test extraction of multiple audiences from both aud and resource claims.""" + payload = { + "aud": ["https://api1.example.com", "https://api2.example.com"], + "resource": "https://api3.example.com", + } + + audiences = _extract_all_audiences(payload) + expected = {"https://api1.example.com", "https://api2.example.com", "https://api3.example.com"} + assert set(audiences) == expected + + +@pytest.mark.asyncio +async def test_audience_extraction_string_values(): + """Test extraction when aud and resource are strings rather than arrays.""" + payload = { + "aud": "https://api1.example.com", + "resource": "https://api2.example.com", + } + + audiences = _extract_all_audiences(payload) + expected = {"https://api1.example.com", "https://api2.example.com"} + assert set(audiences) == expected + + +@pytest.mark.asyncio +async def test_empty_audience_validation(): + """Test validation fails when no audiences are present.""" + payload = { + "active": True, + "sub": "user123", + "exp": 1234567890, + "iss": "https://auth.example.com/", + # No aud or resource claims + } + + token = MCPAccessToken.from_introspection("test_token", payload) + assert token.validate_audience(["https://api.example.com"]) is False + + +def test_configuration_validation(): + """Test that configuration validation always enforces audience settings.""" + # Should raise error when no audiences configured (always enforced now) + with pytest.raises(ValueError, match="expected_audiences.*required for RFC 9068"): + MCPAuthorizationServerSettings( + enabled=True, + issuer_url="https://auth.example.com", + resource_server_url="https://api.example.com", + expected_audiences=[], # Empty list should always fail + ) + + # Should succeed with proper configuration + settings = MCPAuthorizationServerSettings( + enabled=True, + issuer_url="https://auth.example.com", + resource_server_url="https://api.example.com", + expected_audiences=["https://api.example.com"], + ) + assert "https://api.example.com" in settings.expected_audiences + + + + +@pytest.mark.asyncio +async def test_token_verifier_audience_validation_integration(): + """Test full integration of audience validation in token verifier.""" + settings = MCPAuthorizationServerSettings( + enabled=True, + issuer_url="https://auth.example.com", + resource_server_url="https://api.example.com", + introspection_endpoint="https://auth.example.com/introspect", + introspection_client_id="test-client", + introspection_client_secret="test-secret", + expected_audiences=["https://api.example.com"], + ) + + verifier = MCPAgentTokenVerifier(settings) + + # Mock HTTP client + mock_client = Mock(spec=httpx.AsyncClient) + + # Mock successful response with valid audience + valid_response = Mock() + valid_response.status_code = 200 + valid_response.json.return_value = { + "active": True, + "aud": "https://api.example.com", + "sub": "user123", + "exp": 1234567890, + "iss": "https://auth.example.com/", + } + mock_client.post = AsyncMock(return_value=valid_response) + verifier._client = mock_client + + # Should succeed with valid audience + token = await verifier._introspect("valid_token") + assert token is not None + assert "https://api.example.com" in token.audiences + + # Mock response with invalid audience + invalid_response = Mock() + invalid_response.status_code = 200 + invalid_response.json.return_value = { + "active": True, + "aud": "https://malicious.example.com", # Wrong audience + "sub": "user123", + "exp": 1234567890, + "iss": "https://auth.example.com/", + } + mock_client.post = AsyncMock(return_value=invalid_response) + + # Should fail with invalid audience + token = await verifier._introspect("invalid_token") + assert token is None + + + + +def test_audience_extraction_edge_cases(): + """Test audience extraction handles edge cases properly.""" + # Empty payload + assert _extract_all_audiences({}) == [] + + # None values + assert _extract_all_audiences({"aud": None, "resource": None}) == [] + + # Mixed empty and valid values + payload = { + "aud": ["", "https://valid.com", None], + "resource": ["https://another.com", ""] + } + audiences = _extract_all_audiences(payload) + expected = {"https://valid.com", "https://another.com"} + assert set(audiences) == expected + + # Duplicate values should be removed + payload = { + "aud": ["https://api.com", "https://api.com"], + "resource": "https://api.com" + } + audiences = _extract_all_audiences(payload) + assert audiences == ["https://api.com"] + + +@pytest.mark.asyncio +async def test_partial_audience_match(): + """Test that partial audience matches are sufficient for validation.""" + settings = MCPAuthorizationServerSettings( + enabled=True, + issuer_url="https://auth.example.com", + resource_server_url="https://api.example.com", + introspection_endpoint="https://auth.example.com/introspect", + expected_audiences=["https://api.example.com", "https://other-api.com"], + strict_audience_validation=True, + ) + + # Token has one matching and one non-matching audience + payload = { + "active": True, + "aud": ["https://api.example.com", "https://unrelated.com"], + "sub": "user123", + "exp": 1234567890, + "iss": "https://auth.example.com/", + } + + token = MCPAccessToken.from_introspection("test_token", payload) + # Should succeed because at least one audience matches + assert token.validate_audience(settings.expected_audiences) is True \ No newline at end of file diff --git a/tests/test_oauth_utils.py b/tests/test_oauth_utils.py index 87488c41a..cd3de139f 100644 --- a/tests/test_oauth_utils.py +++ b/tests/test_oauth_utils.py @@ -63,13 +63,14 @@ def test_select_authorization_server_prefers_explicit(): "https://auth2.example.com", ], ) + # URLs get normalized with trailing slashes by pydantic assert ( - select_authorization_server(metadata, "https://auth2.example.com") - == "https://auth2.example.com" + select_authorization_server(metadata, "https://auth2.example.com/") + == "https://auth2.example.com/" ) assert ( select_authorization_server(metadata, "https://unknown.example.com") - == "https://auth1.example.com" + == "https://auth1.example.com/" # Falls back to first, which gets normalized ) From 6cd9b407573c6f0795fdf8febbdedb79b40fd5ba Mon Sep 17 00:00:00 2001 From: Roman van der Krogt Date: Thu, 25 Sep 2025 22:01:26 +0100 Subject: [PATCH 06/25] add comfigured token support; add workflow_pre_auth; oauth example against github --- examples/oauth/preconfigured/README.md | 402 +++++++++++++++++ examples/oauth/preconfigured/main.py | 188 ++++++++ .../oauth/preconfigured/mcp_agent.config.yaml | 115 +++++ .../mcp_agent.secrets.yaml.example | 41 ++ examples/oauth/preconfigured/oauth_demo.py | 384 ++++++++++++++++ examples/oauth/preconfigured/requirements.txt | 37 ++ .../oauth/preconfigured/workflow_example.py | 427 ++++++++++++++++++ examples/oauth/workflow_pre_auth/client.py | 193 ++++++++ examples/oauth/workflow_pre_auth/main.py | 139 ++++++ src/mcp_agent/app.py | 44 ++ src/mcp_agent/config.py | 5 + src/mcp_agent/oauth/http/auth.py | 24 +- src/mcp_agent/oauth/manager.py | 139 ++++-- src/mcp_agent/server/app_server.py | 152 +++++++ 14 files changed, 2252 insertions(+), 38 deletions(-) create mode 100644 examples/oauth/preconfigured/README.md create mode 100644 examples/oauth/preconfigured/main.py create mode 100644 examples/oauth/preconfigured/mcp_agent.config.yaml create mode 100644 examples/oauth/preconfigured/mcp_agent.secrets.yaml.example create mode 100644 examples/oauth/preconfigured/oauth_demo.py create mode 100644 examples/oauth/preconfigured/requirements.txt create mode 100644 examples/oauth/preconfigured/workflow_example.py create mode 100644 examples/oauth/workflow_pre_auth/client.py create mode 100644 examples/oauth/workflow_pre_auth/main.py diff --git a/examples/oauth/preconfigured/README.md b/examples/oauth/preconfigured/README.md new file mode 100644 index 000000000..846eded46 --- /dev/null +++ b/examples/oauth/preconfigured/README.md @@ -0,0 +1,402 @@ +# OAuth MCP Agent Example + +This example demonstrates how to build MCP agents that use OAuth authentication to access OAuth-protected MCP servers, specifically showing integration with the GitHub MCP server. + +## 📋 Overview + +This example includes: + +- **Basic OAuth Integration** - Connect to OAuth-protected MCP servers +- **GitHub Organization Search** - Use the `search_orgs` tool from GitHub MCP server +- **Workflow Pre-Authorization** - Demonstrate the new `workflow_pre_auth` endpoint +- **Interactive OAuth Flow** - Complete OAuth setup and token management +- **Production-Ready Configuration** - Comprehensive config with security best practices + +## 🚀 Quick Start + +### 1. Prerequisites + +```bash +# Install Python dependencies +pip install -r requirements.txt + +# Install GitHub MCP server +uvx install github-mcp-server + +# Optional: Install additional MCP servers +npm install -g @modelcontextprotocol/server-filesystem +uvx install mcp-server-fetch +``` + +### 2. Set Up GitHub OAuth App + +1. Go to [GitHub Settings → Developer settings → OAuth Apps](https://github.com/settings/applications/new) +2. Click **"New OAuth App"** +3. Fill in the details: + - **Application name**: `MCP Agent OAuth Example` + - **Homepage URL**: `https://github.com/yourusername/your-repo` + - **Authorization callback URL**: `http://localhost:8080/oauth/callback` +4. Click **"Register application"** +5. Copy the **Client ID** and generate a **Client Secret** + +### 3. Configure Secrets + +```bash +# Copy the secrets template +cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml + +# Edit with your credentials +nano mcp_agent.secrets.yaml +``` + +Add your GitHub OAuth app credentials: + +```yaml +mcp: + servers: + github: + auth: + oauth: + client_id: "your_github_oauth_app_client_id_here" + client_secret: "your_github_oauth_app_client_secret_here" + access_token: "your_github_access_token_here" # Optional: skip OAuth flow +``` + +### 4. Run the Examples + +#### Basic OAuth Example +```bash +python main.py +``` + +#### Interactive OAuth Setup +```bash +python oauth_demo.py +``` + +#### Workflow with Pre-Authorization +```bash +python workflow_example.py +``` + +## 📁 File Structure + +``` +examples/oauth/ +├── README.md # This file +├── main.py # Basic OAuth MCP agent +├── workflow_example.py # Workflow with pre-auth demo +├── oauth_demo.py # Interactive OAuth flow +├── mcp_agent.config.yaml # Agent configuration +├── mcp_agent.secrets.yaml.example # Secrets template +└── requirements.txt # Python dependencies +``` + +## 🔐 Authentication Methods + +### Method 1: OAuth Flow (Recommended) + +Full OAuth 2.0 flow with refresh tokens: + +1. **Run Interactive Setup**: + ```bash + GITHUB_CLIENT_ID=your_id GITHUB_CLIENT_SECRET=your_secret python oauth_demo.py + ``` + +2. **Follow Browser Flow**: Authorize the application in your browser + +3. **Token Storage**: Tokens are automatically stored for reuse + +### Method 2: Personal Access Token (Development) + +For development and testing, you can use a GitHub Personal Access Token: + +1. Go to [GitHub Settings → Developer settings → Personal access tokens](https://github.com/settings/tokens) +2. Generate a token with scopes: `read:org`, `public_repo`, `user:email` +3. Configure in `mcp_agent.secrets.yaml`: + +```yaml +mcp: + servers: + github: + auth: + api_key: "ghp_your_personal_access_token_here" +``` + +## 🔄 Workflow Pre-Authorization + +The `workflow_pre_auth` endpoint allows you to pre-store OAuth tokens for workflows: + +### 1. Start MCP Agent Server + +```bash +mcp-agent server --config mcp_agent.config.yaml +``` + +### 2. Pre-Authorize Tokens + +```bash +curl -X POST http://localhost:8080/tools/workflows-pre-auth \ + -H "Content-Type: application/json" \ + -d '{ + "workflow_name": "github_analysis_workflow", + "tokens": [ + { + "access_token": "your_github_access_token", + "refresh_token": "your_refresh_token", + "server_name": "github", + "scopes": ["read:org", "public_repo"], + "authorization_server": "https://github.com/login/oauth/authorize" + } + ] + }' +``` + +### 3. Run Workflow + +```bash +curl -X POST http://localhost:8080/tools/workflows-run \ + -H "Content-Type: application/json" \ + -d '{ + "workflow_name": "analyze_github_ecosystem", + "run_parameters": { + "focus_areas": ["AI/ML", "cloud", "security"], + "include_details": true + } + }' +``` + +## 🛠 Examples Explained + +### main.py - Basic OAuth Integration + +Demonstrates: +- Connecting to GitHub MCP server with OAuth +- Using the `search_orgs` tool +- Error handling and token management +- Both single-use and persistent connections + +Key features: +```python +async with gen_client("github", server_registry=context.server_registry) as github_client: + result = await github_client.call_tool("search_orgs", { + "query": "microsoft", + "perPage": 10, + "sort": "best-match" + }) +``` + +### workflow_example.py - Advanced Workflow + +Demonstrates: +- Custom agent (`GitHubOrganizationAnalyzer`) +- Workflow with `@app.async_tool` decorator +- Pre-authorization token usage +- Comprehensive GitHub ecosystem analysis + +Key features: +```python +@app.async_tool +async def analyze_github_ecosystem( + app_ctx: Context, + focus_areas: List[str], + include_details: bool = True +) -> Dict[str, Any]: + # Uses pre-authorized tokens automatically + analyzer = GitHubOrganizationAnalyzer(context=app_ctx) + return await analyzer.analyze_organizations(queries, include_details) +``` + +### oauth_demo.py - Interactive OAuth Setup + +Demonstrates: +- Complete OAuth 2.0 flow +- Local callback server +- Token testing and validation +- Token persistence + +Key features: +- Automatic browser opening +- CSRF protection with state parameter +- Token testing with GitHub API +- Export tokens for MCP agent use + +## ⚙ Configuration Details + +### OAuth Configuration + +```yaml +oauth: + token_store: + backend: memory # or 'redis' for production + refresh_leeway_seconds: 60 + flow_timeout_seconds: 300 + callback_base_url: http://localhost:8080 + +mcp: + servers: + github: + auth: + oauth: + enabled: true + scopes: ["read:org", "public_repo", "user:email"] + authorization_server: "https://github.com/login/oauth/authorize" + resource: "https://api.github.com" +``` + +### GitHub Scopes Required + +| Scope | Purpose | Required | +|-------|---------|----------| +| `read:org` | Search organizations | ✅ Yes | +| `public_repo` | Access public repositories | ✅ Yes | +| `user:email` | User information | ⚠ Recommended | +| `repo` | Private repositories | ❌ Optional | + +## 🔧 Production Deployment + +### Redis Token Storage + +For production with multiple processes: + +```yaml +oauth: + token_store: + backend: redis + redis_url: "redis://localhost:6379" + redis_prefix: "mcp_agent:oauth_tokens" +``` + +### Environment Variables + +```bash +export GITHUB_CLIENT_ID="your_client_id" +export GITHUB_CLIENT_SECRET="your_client_secret" +export REDIS_URL="redis://localhost:6379" +export OPENAI_API_KEY="your_openai_key" +``` + +### Security Best Practices + +1. **Never commit secrets** - Use `.gitignore` for `mcp_agent.secrets.yaml` +2. **Rotate tokens regularly** - Set up token refresh workflows +3. **Minimal scopes** - Only request necessary permissions +4. **Secure storage** - Use Redis or encrypted storage in production +5. **HTTPS callbacks** - Use HTTPS URLs for production OAuth callbacks + +## 🐛 Troubleshooting + +### Common Issues + +#### OAuth Flow Fails +``` +Error: OAuth error: access_denied +``` +**Solution**: Check callback URL matches OAuth app configuration + +#### Token Test Fails +``` +Error: Token test failed: 401 +``` +**Solution**: Verify token scopes and GitHub app permissions + +#### MCP Server Connection Fails +``` +Error: GitHub MCP server not found +``` +**Solution**: Install GitHub MCP server with `uvx install github-mcp-server` + +#### Import Errors +``` +ImportError: No module named 'mcp_agent' +``` +**Solution**: Install with `pip install mcp-agent[oauth]` + +### Debug Mode + +Enable detailed logging: + +```yaml +logger: + level: debug + debug_oauth: true +``` + +### Testing Tokens + +Test your GitHub token manually: + +```bash +curl -H "Authorization: Bearer YOUR_TOKEN" https://api.github.com/user +``` + +## 📚 Advanced Usage + +### Multiple OAuth Providers + +```yaml +mcp: + servers: + github: + auth: + oauth: + client_id: "github_client_id" + # ... GitHub config + + slack: + auth: + oauth: + client_id: "slack_client_id" + # ... Slack config +``` + +### Custom Token Refresh + +```python +async def refresh_github_token(old_token: str) -> str: + # Custom token refresh logic + async with aiohttp.ClientSession() as session: + # ... refresh implementation + return new_token +``` + +### Workflow Chaining + +```python +@app.async_tool +async def multi_step_analysis(app_ctx: Context, orgs: List[str]): + # Step 1: Search organizations + github_results = await search_organizations(orgs) + + # Step 2: Analyze with different service + analysis = await analyze_with_ai(github_results) + + # Step 3: Store results + await store_results(analysis) + + return analysis +``` + +## 🤝 Contributing + +1. Fork the repository +2. Create your feature branch +3. Add tests for new functionality +4. Ensure all examples work +5. Submit a pull request + +## 📄 License + +This example is part of the MCP Agent project and follows the same license terms. + +## 🔗 Related Resources + +- [MCP Agent Documentation](../../README.md) +- [GitHub MCP Server](https://github.com/github/github-mcp-server) +- [OAuth 2.0 Specification](https://tools.ietf.org/html/rfc6749) +- [GitHub OAuth Apps](https://docs.github.com/en/developers/apps/building-oauth-apps) +- [Model Context Protocol](https://modelcontextprotocol.io) + +--- + +For questions or issues with this example, please check the [main repository issues](../../issues) or create a new issue with the `oauth-example` label. \ No newline at end of file diff --git a/examples/oauth/preconfigured/main.py b/examples/oauth/preconfigured/main.py new file mode 100644 index 000000000..64d228151 --- /dev/null +++ b/examples/oauth/preconfigured/main.py @@ -0,0 +1,188 @@ +""" +OAuth MCP Agent Example + +This example demonstrates how to use an MCP agent with OAuth authentication +to access the GitHub MCP server and search for organizations. + +Features demonstrated: +- OAuth flow setup and configuration +- Connecting to GitHub MCP server with OAuth +- Using the search_orgs tool +- Error handling and token refresh +""" + +import asyncio +import json +import logging +from typing import Any, Dict, List + +from mcp_agent.app import MCPApp +from mcp_agent.mcp.gen_client import gen_client +from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession +from mcp_agent.mcp.mcp_connection_manager import MCPConnectionManager + +# Create the MCP app with OAuth configuration +app = MCPApp(name="oauth_github_example") + +async def search_github_orgs(query: str, limit: int = 5) -> List[Dict[str, Any]]: + """ + Search for GitHub organizations using the GitHub MCP server with OAuth. + + Args: + query: Search query (e.g., 'microsoft', 'location:california') + limit: Maximum number of results to return + + Returns: + List of organization data from GitHub + """ + async with app.run() as github_app: + context = github_app.context + logger = github_app.logger + + logger.info(f"Searching GitHub organizations for: '{query}'") + + try: + # Connect to the GitHub MCP server with OAuth + async with gen_client( + "github", + server_registry=context.server_registry, + context=context + ) as github_client: + logger.info("Connected to GitHub MCP server with OAuth") + + # List available tools to verify connection + tools_result = await github_client.list_tools() + logger.info(f"Available tools: {len(tools_result.tools)} tools found") + + # Find the search_orgs tool + search_orgs_tool = None + for tool in tools_result.tools: + if tool.name == "search_orgs": + search_orgs_tool = tool + break + + if not search_orgs_tool: + logger.error("search_orgs tool not found") + return [] + + logger.info(f"Found search_orgs tool: {search_orgs_tool.description}") + + # Call the search_orgs tool + result = await github_client.call_tool( + "search_orgs", + { + "query": query, + "perPage": min(limit, 100), # GitHub API max is 100 + "sort": "best-match", + "order": "desc" + } + ) + + logger.info(f"Search completed, processing results...") + + # Parse and return the results + if result.content: + # The result content should contain the organization data + organizations = [] + for content_item in result.content: + if hasattr(content_item, 'text'): + try: + # Try to parse as JSON if it's structured data + data = json.loads(content_item.text) + if isinstance(data, dict) and 'items' in data: + organizations.extend(data['items'][:limit]) + elif isinstance(data, list): + organizations.extend(data[:limit]) + else: + organizations.append(data) + except json.JSONDecodeError: + # If not JSON, treat as text description + organizations.append({"description": content_item.text}) + + logger.info(f"Found {len(organizations)} organizations") + return organizations[:limit] + + return [] + + except Exception as e: + logger.error(f"Error searching GitHub organizations: {e}") + # Check if it's an OAuth-related error + if "authentication" in str(e).lower() or "oauth" in str(e).lower(): + logger.error( + "Authentication failed. Please check your OAuth configuration " + "and ensure your GitHub token is valid." + ) + raise + + +async def demonstrate_org_search(): + """ + Demonstrate searching for different types of organizations. + """ + search_queries = [ + "microsoft", + # "location:california", + # "created:>=2020-01-01", + # "language:python", + # "repositories:>100" + ] + + for query in search_queries: + print(f"\n{'='*50}") + print(f"Searching for: {query}") + print('='*50) + + try: + orgs = await search_github_orgs(query, limit=3) + + if orgs: + for i, org in enumerate(orgs, 1): + print(f"\n{i}. {org.get('login', 'Unknown')}") + if 'description' in org and org['description']: + print(f" Description: {org['description']}") + if 'html_url' in org: + print(f" URL: {org['html_url']}") + if 'public_repos' in org: + print(f" Public repos: {org['public_repos']}") + if 'location' in org and org['location']: + print(f" Location: {org['location']}") + else: + print("No organizations found.") + + except Exception as e: + print(f"Error: {e}") + continue + + + +async def main(): + """ + Main function demonstrating various OAuth MCP agent usage patterns. + """ + print("OAuth MCP Agent Example - GitHub Organization Search") + print("=" * 60) + + try: + # Demonstrate basic organization search + await demonstrate_org_search() + + except Exception as e: + print(f"\nExample failed with error: {e}") + print("\nPlease ensure:") + print("1. You have configured your GitHub OAuth app correctly") + print("2. Your mcp_agent.secrets.yaml file contains valid OAuth credentials") + print("3. The GitHub MCP server is properly installed and accessible") + print("4. Your OAuth token has the required scopes (read:org)") + + # Log the full error for debugging + logging.exception("Full error details:") + + +if __name__ == "__main__": + # Set up logging to show detailed information + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" + ) + + asyncio.run(main()) \ No newline at end of file diff --git a/examples/oauth/preconfigured/mcp_agent.config.yaml b/examples/oauth/preconfigured/mcp_agent.config.yaml new file mode 100644 index 000000000..61fa80456 --- /dev/null +++ b/examples/oauth/preconfigured/mcp_agent.config.yaml @@ -0,0 +1,115 @@ +$schema: ../../schema/mcp-agent.config.schema.json + +# OAuth MCP Agent Configuration +# This configuration demonstrates how to set up OAuth authentication +# for accessing OAuth-protected MCP servers like the GitHub MCP server + +execution_engine: asyncio + +# Logging configuration +logger: + type: console + level: debug + path: "./mcp-agent.log" + # Enable detailed OAuth and authentication logging + debug_oauth: true + +# OpenTelemetry tracing (optional) +tracing: + enabled: true + service_name: "OAuth-MCP-Agent-Example" + exporters: ["console"] + +# OAuth-specific configuration +oauth: + # Token store configuration + token_store: + backend: memory # Use 'redis' for production with multiple processes + refresh_leeway_seconds: 60 # Refresh tokens 60 seconds before expiry + + # OAuth flow timeout (5 minutes) + flow_timeout_seconds: 300 + + # Callback base URL for OAuth flows (adjust if running behind proxy) + callback_base_url: http://localhost:8080 + +# MCP server configurations +mcp: + servers: + # GitHub MCP Server with OAuth authentication + github: + # Use the remote GitHub MCP server + transport: "streamable_http" + url: "https://api.githubcopilot.com/mcp/" + + # OAuth authentication configuration + auth: + oauth: + enabled: true + # Required scopes for GitHub MCP server functionality + scopes: + - "read:org" # Required for search_orgs tool + - "public_repo" # Access to public repositories + - "user:email" # User information access + + # GitHub OAuth endpoints + authorization_server: "https://github.com/login/oauth" + resource: "https://api.githubcopilot.com/mcp" + + # Use internal callback handling (recommended) + use_internal_callback: true + + # Example: Additional MCP server (filesystem for local operations) + filesystem: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-filesystem", "."] + # No auth required for local filesystem server + + # Example: Fetch server (no auth required) + fetch: + command: "uvx" + args: ["mcp-server-fetch"] + +# Authorization server configuration (if exposing this agent as an MCP server) +authorization: + enabled: false # Set to true if you want to expose this agent with OAuth protection + # issuer_url: "https://your-oauth-provider.com" + # resource_server_url: "https://your-agent-server.com" + # required_scopes: ["agent:read", "agent:execute"] + +# Model configuration (for LLM-based agents) +openai: + # API keys are stored in mcp_agent.secrets.yaml + model: "gpt-4" + temperature: 0.1 + max_tokens: 2000 + +anthropic: + # API keys are stored in mcp_agent.secrets.yaml + model: "claude-3-sonnet-20240229" + max_tokens: 2000 + +# Agent-specific settings +agents: + # Configuration for the GitHubOrganizationAnalyzer agent + default_timeout: 30 + max_retries: 3 + + # GitHub-specific settings + github: + max_orgs_per_query: 10 + default_search_sort: "best-match" + include_detailed_analysis: true + +# Workflow configuration +workflows: + # Default workflow timeout (30 minutes) + default_timeout_minutes: 30 + + # Enable workflow pre-authorization + enable_pre_auth: true + + # Workflow-specific settings + github_analysis: + max_concurrent_searches: 5 + analysis_depth: "detailed" # "basic" or "detailed" diff --git a/examples/oauth/preconfigured/mcp_agent.secrets.yaml.example b/examples/oauth/preconfigured/mcp_agent.secrets.yaml.example new file mode 100644 index 000000000..1feea2c6f --- /dev/null +++ b/examples/oauth/preconfigured/mcp_agent.secrets.yaml.example @@ -0,0 +1,41 @@ +$schema: ../../schema/mcp-agent.config.schema.json + +# OAuth MCP Agent Secrets Template +# +# This file contains sensitive configuration like API keys and OAuth credentials. +# Copy this file to mcp_agent.secrets.yaml and fill in your actual values. +# + +# OpenAI API configuration +openai: + api_key: "sk-your-openai-api-key-here" + +# Anthropic API configuration +anthropic: + api_key: "sk-ant-api03-your-anthropic-api-key-here" + +# GitHub OAuth App Configuration +# To set up a GitHub OAuth app: +# 1. Go to GitHub Settings > Developer settings > OAuth Apps +# 2. Click "New OAuth App" +# 3. Fill in the application details: +# - Application name: "MCP Agent OAuth Example" +# - Homepage URL: "https://github.com/your-username/your-repo" +# - Authorization callback URL: "http://localhost:8080/oauth/callback" +# 4. Click "Register application" +# 5. Copy the Client ID and generate a Client Secret +# 6. Fill in the values below + +mcp: + servers: + github: + auth: + oauth: + # GitHub OAuth App credentials + client_id: "your-github-client-id-here" + client_secret: "your-github-client-secret-here" + + # Optional: Pre-configured access token (from oauth_demo.py or manual setup) + # If you have a valid access token, you can specify it here to skip the OAuth flow + access_token: "your_github_access_token_here" + # refresh_token: "your_refresh_token_here" # If available diff --git a/examples/oauth/preconfigured/oauth_demo.py b/examples/oauth/preconfigured/oauth_demo.py new file mode 100644 index 000000000..9fb41d80b --- /dev/null +++ b/examples/oauth/preconfigured/oauth_demo.py @@ -0,0 +1,384 @@ +""" +Standalone OAuth Flow Demonstration + +This script demonstrates the OAuth flow for authenticating with GitHub +and storing tokens for use with MCP agents. This is useful for: +- Understanding the OAuth process +- Testing token acquisition and storage +- Debugging authentication issues +- Setting up tokens for the first time + +Run this script interactively to authenticate with GitHub and store tokens. +""" + +import asyncio +import json +import os +import secrets +import time +import urllib.parse +import webbrowser +from typing import Any, Dict, Optional + +import aiohttp +from aiohttp import web + + +class GitHubOAuthDemo: + """ + Demonstration of GitHub OAuth flow for MCP agent authentication. + """ + + def __init__(self, client_id: str, client_secret: str, redirect_uri: str = None): + """ + Initialize OAuth demo. + + Args: + client_id: GitHub OAuth app client ID + client_secret: GitHub OAuth app client secret + redirect_uri: OAuth redirect URI (defaults to localhost) + """ + self.client_id = client_id + self.client_secret = client_secret + self.redirect_uri = redirect_uri or "http://localhost:8080/oauth/callback" + self.state = secrets.token_urlsafe(32) # CSRF protection + self.access_token: Optional[str] = None + self.refresh_token: Optional[str] = None + self.token_expires_at: Optional[float] = None + + def get_authorization_url(self, scopes: list = None) -> str: + """ + Generate the GitHub authorization URL. + + Args: + scopes: List of OAuth scopes to request + + Returns: + Authorization URL for the user to visit + """ + if scopes is None: + scopes = ["read:org", "public_repo"] # Default scopes for GitHub MCP server + + params = { + "client_id": self.client_id, + "redirect_uri": self.redirect_uri, + "scope": " ".join(scopes), + "state": self.state, + "response_type": "code", + } + + base_url = "https://github.com/login/oauth/authorize" + return f"{base_url}?{urllib.parse.urlencode(params)}" + + async def exchange_code_for_token(self, code: str, state: str) -> Dict[str, Any]: + """ + Exchange authorization code for access token. + + Args: + code: Authorization code from GitHub + state: State parameter for CSRF protection + + Returns: + Token response data + + Raises: + ValueError: If state doesn't match or token exchange fails + """ + if state != self.state: + raise ValueError("State parameter mismatch - possible CSRF attack") + + token_url = "https://github.com/login/oauth/access_token" + data = { + "client_id": self.client_id, + "client_secret": self.client_secret, + "code": code, + "redirect_uri": self.redirect_uri, + } + + headers = { + "Accept": "application/json", + "User-Agent": "MCP-Agent-OAuth-Demo/1.0" + } + + async with aiohttp.ClientSession() as session: + async with session.post(token_url, data=data, headers=headers) as response: + if response.status != 200: + raise ValueError(f"Token exchange failed: {response.status}") + + token_data = await response.json() + + if "error" in token_data: + raise ValueError(f"Token error: {token_data['error_description']}") + + self.access_token = token_data.get("access_token") + self.refresh_token = token_data.get("refresh_token") + + # Calculate expiration time + expires_in = token_data.get("expires_in") + if expires_in: + self.token_expires_at = time.time() + expires_in + else: + # GitHub tokens typically don't expire, but set a far future date + self.token_expires_at = time.time() + (365 * 24 * 3600) # 1 year + + return token_data + + async def test_token(self) -> Dict[str, Any]: + """ + Test the access token by making a simple GitHub API call. + + Returns: + User information from GitHub API + """ + if not self.access_token: + raise ValueError("No access token available") + + headers = { + "Authorization": f"Bearer {self.access_token}", + "Accept": "application/vnd.github.v3+json", + "User-Agent": "MCP-Agent-OAuth-Demo/1.0" + } + + async with aiohttp.ClientSession() as session: + # Test with a simple user info call + async with session.get("https://api.github.com/user", headers=headers) as response: + if response.status != 200: + raise ValueError(f"Token test failed: {response.status}") + + user_data = await response.json() + return user_data + + def get_token_for_mcp_agent(self) -> Dict[str, Any]: + """ + Get token data in the format expected by MCP agent workflow_pre_auth. + + Returns: + Token data dictionary for MCP agent + """ + if not self.access_token: + raise ValueError("No access token available") + + return { + "access_token": self.access_token, + "refresh_token": self.refresh_token, + "server_name": "github", + "scopes": ["read:org", "public_repo"], + "expires_at": self.token_expires_at, + "authorization_server": "https://github.com/login/oauth/authorize", + "token_type": "Bearer" + } + + async def save_token_to_file(self, filename: str = "github_oauth_token.json"): + """ + Save the token to a JSON file for later use. + + Args: + filename: File to save token data + """ + token_data = self.get_token_for_mcp_agent() + + with open(filename, 'w') as f: + json.dump(token_data, f, indent=2) + + print(f"Token saved to {filename}") + print("You can now use this token with the MCP agent workflow_pre_auth endpoint.") + + async def run_oauth_flow(self, scopes: list = None) -> Dict[str, Any]: + """ + Run the complete OAuth flow interactively. + + Args: + scopes: OAuth scopes to request + + Returns: + Complete token data + """ + print("Starting GitHub OAuth flow...") + print("=" * 50) + + # Step 1: Generate authorization URL + auth_url = self.get_authorization_url(scopes) + print(f"\n1. Please visit this URL to authorize the application:") + print(f" {auth_url}") + print("\n2. After authorization, you'll be redirected to a callback URL.") + + # Step 2: Start local server to handle callback + callback_received = asyncio.Event() + callback_data = {} + + async def handle_callback(request): + nonlocal callback_data + try: + code = request.query.get('code') + state = request.query.get('state') + error = request.query.get('error') + + if error: + callback_data['error'] = error + callback_data['error_description'] = request.query.get('error_description', '') + else: + callback_data['code'] = code + callback_data['state'] = state + + callback_received.set() + + # Return a simple success page + html = """ + + +

OAuth Authorization Complete

+

You can close this window and return to the terminal.

+ + + + """ + return web.Response(text=html, content_type='text/html') + + except Exception as e: + print(f"Error in callback handler: {e}") + return web.Response(text=f"Error: {e}", status=500) + + # Start local server + app = web.Application() + app.router.add_get('/oauth/callback', handle_callback) + + runner = web.AppRunner(app) + await runner.setup() + site = web.TCPSite(runner, 'localhost', 8080) + await site.start() + + print("\n3. Local callback server started on http://localhost:8080") + print(" Opening browser to authorization URL...") + + # Open browser automatically + try: + webbrowser.open(auth_url) + except Exception: + print(" (Could not open browser automatically)") + + print("\n4. Waiting for authorization callback...") + + # Wait for callback with timeout + try: + await asyncio.wait_for(callback_received.wait(), timeout=300) # 5 minute timeout + except asyncio.TimeoutError: + print(" Timeout waiting for authorization callback") + await runner.cleanup() + raise ValueError("OAuth flow timeout") + + await runner.cleanup() + + # Step 3: Handle callback result + if 'error' in callback_data: + raise ValueError(f"OAuth error: {callback_data['error']} - {callback_data.get('error_description', '')}") + + code = callback_data.get('code') + state = callback_data.get('state') + + if not code: + raise ValueError("No authorization code received") + + print("5. Authorization code received, exchanging for access token...") + + # Step 4: Exchange code for token + token_data = await self.exchange_code_for_token(code, state) + print(" ✓ Access token obtained successfully") + + # Step 5: Test the token + print("6. Testing access token...") + try: + user_info = await self.test_token() + username = user_info.get('login', 'unknown') + print(f" ✓ Token test successful - authenticated as: {username}") + except Exception as e: + print(f" ⚠ Token test failed: {e}") + + return self.get_token_for_mcp_agent() + + +async def main(): + """ + Main interactive OAuth demonstration. + """ + print("GitHub OAuth Demo for MCP Agent") + print("=" * 40) + + # Check for environment variables + client_id = os.getenv('GITHUB_CLIENT_ID') + client_secret = os.getenv('GITHUB_CLIENT_SECRET') + + if not client_id or not client_secret: + print("\nTo use this demo, you need to set up a GitHub OAuth App:") + print("1. Go to GitHub Settings > Developer settings > OAuth Apps") + print("2. Click 'New OAuth App'") + print("3. Set Authorization callback URL to: http://localhost:8080/oauth/callback") + print("4. Set environment variables:") + print(" export GITHUB_CLIENT_ID='your_client_id'") + print(" export GITHUB_CLIENT_SECRET='your_client_secret'") + print("\nAlternatively, you can pass them as command line arguments.") + return + + try: + # Create OAuth demo instance + oauth_demo = GitHubOAuthDemo(client_id, client_secret) + + # Run the OAuth flow + scopes = ["read:org", "public_repo", "user:email"] + token_data = await oauth_demo.run_oauth_flow(scopes) + + print(token_data) + + print("\n" + "=" * 50) + print("OAuth Flow Completed Successfully!") + print("=" * 50) + + print(f"\nToken Details:") + print(f" Access Token: {token_data['access_token'][:20]}...") + print(f" Expires At: {time.ctime(token_data['expires_at'])}") + print(f" Scopes: {', '.join(token_data['scopes'])}") + + # Save token to file + save_choice = input("\nSave token to file? (y/n): ").lower().strip() + if save_choice in ['y', 'yes']: + filename = input("Enter filename (default: github_oauth_token.json): ").strip() + if not filename: + filename = "github_oauth_token.json" + await oauth_demo.save_token_to_file(filename) + + # Show usage instructions + print("\n" + "=" * 50) + print("Next Steps:") + print("=" * 50) + print("1. Use this token with the MCP agent workflow_pre_auth endpoint:") + + example_usage = { + "workflow_name": "github_analysis_workflow", + "tokens": [token_data] + } + print(f" {json.dumps(example_usage, indent=2)}") + + print("\n2. Or configure it in your mcp_agent.secrets.yaml:") + secrets_example = { + "mcp": { + "servers": { + "github": { + "auth": { + "oauth": { + "access_token": token_data['access_token'], + "refresh_token": token_data.get('refresh_token'), + "scopes": token_data['scopes'] + } + } + } + } + } + } + print(f" {json.dumps(secrets_example, indent=2)}") + + except Exception as e: + print(f"\nOAuth flow failed: {e}") + print("Please check your GitHub OAuth app configuration and try again.") + + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/examples/oauth/preconfigured/requirements.txt b/examples/oauth/preconfigured/requirements.txt new file mode 100644 index 000000000..12966f2cf --- /dev/null +++ b/examples/oauth/preconfigured/requirements.txt @@ -0,0 +1,37 @@ +# OAuth MCP Agent Example Requirements +# +# This file specifies the Python dependencies needed to run the OAuth examples. +# Install with: pip install -r requirements.txt + +# Core MCP Agent with OAuth support +mcp-agent[oauth,cli]>=0.1.27 + +# Additional dependencies for OAuth flow and HTTP handling +aiohttp>=3.11.13 +# For OAuth flow demonstration and token management +urllib3>=2.0.0 + +# GitHub MCP Server (install separately with uvx or npm) +# Note: The GitHub MCP server is installed via uvx, not pip +# Run: uvx install github-mcp-server + +# Optional: Enhanced JSON handling +ujson>=5.0.0 + +# Optional: Enhanced async support +trio>=0.30.0 + +# Optional: Redis for production token storage +redis>=4.0.0 + +# Development and testing dependencies (optional) +pytest>=7.4.0 +pytest-asyncio>=0.21.1 + +# For the interactive OAuth demo +webbrowser # Standard library - no explicit install needed + +# Note: Additional MCP servers can be installed as needed: +# - Filesystem server: npm install -g @modelcontextprotocol/server-filesystem +# - Fetch server: uvx install mcp-server-fetch +# - Other servers: See https://github.com/modelcontextprotocol/servers \ No newline at end of file diff --git a/examples/oauth/preconfigured/workflow_example.py b/examples/oauth/preconfigured/workflow_example.py new file mode 100644 index 000000000..47521f584 --- /dev/null +++ b/examples/oauth/preconfigured/workflow_example.py @@ -0,0 +1,427 @@ +""" +OAuth Workflow Pre-Authorization Example + +This example demonstrates how to use the workflow_pre_auth endpoint to +pre-store OAuth tokens for a workflow, then execute the workflow to +access GitHub MCP server tools. + +Features demonstrated: +- Using the workflow_pre_auth endpoint to store OAuth tokens +- Creating a workflow that uses pre-authorized tokens +- Accessing multiple MCP servers with different tokens +- Error handling for token expiration and OAuth issues +""" + +import asyncio +import json +import time +from typing import Any, Dict, List + +from mcp_agent.app import MCPApp +from mcp_agent.agents.agent import Agent +from mcp_agent.core.context import Context + + +class GitHubOrganizationAnalyzer(Agent): + """ + An agent that analyzes GitHub organizations using pre-authorized OAuth tokens. + """ + + def __init__(self, context: Context): + super().__init__(context=context) + self.name = "github_org_analyzer" + + async def analyze_organizations( + self, + queries: List[str], + detailed_analysis: bool = True + ) -> Dict[str, Any]: + """ + Analyze multiple organizations based on search queries. + + Args: + queries: List of search queries for organizations + detailed_analysis: Whether to fetch detailed information + + Returns: + Analysis results for all organizations + """ + logger = self.context.logger + results = {"organizations": [], "summary": {}, "errors": []} + + try: + # The OAuth tokens should be pre-authorized for this workflow + # and available through the context + logger.info(f"Starting analysis of {len(queries)} organization queries") + + for query in queries: + try: + orgs = await self._search_organizations(query) + + for org in orgs: + org_analysis = { + "query": query, + "organization": org.get("login", "unknown"), + "description": org.get("description", ""), + "url": org.get("html_url", ""), + "public_repos": org.get("public_repos", 0), + "followers": org.get("followers", 0), + "location": org.get("location", ""), + "created_at": org.get("created_at", ""), + } + + if detailed_analysis: + # Add more detailed analysis + org_analysis.update( + await self._analyze_organization_details(org) + ) + + results["organizations"].append(org_analysis) + + except Exception as e: + error_msg = f"Error processing query '{query}': {e}" + logger.error(error_msg) + results["errors"].append(error_msg) + + # Generate summary + results["summary"] = self._generate_summary(results["organizations"]) + + logger.info(f"Analysis completed: {len(results['organizations'])} organizations analyzed") + return results + + except Exception as e: + logger.error(f"Organization analysis failed: {e}") + raise + + async def _search_organizations(self, query: str) -> List[Dict[str, Any]]: + """Search for organizations using the GitHub MCP server.""" + from mcp_agent.mcp.gen_client import gen_client + + async with gen_client( + "github", + server_registry=self.context.server_registry, + context=self.context + ) as github_client: + result = await github_client.call_tool( + "search_orgs", + { + "query": query, + "perPage": 10, + "sort": "best-match", + "order": "desc" + } + ) + + organizations = [] + if result.content: + for content_item in result.content: + if hasattr(content_item, 'text'): + try: + data = json.loads(content_item.text) + if isinstance(data, dict) and 'items' in data: + organizations.extend(data['items']) + elif isinstance(data, list): + organizations.extend(data) + except json.JSONDecodeError: + pass + + return organizations + + async def _analyze_organization_details(self, org: Dict[str, Any]) -> Dict[str, Any]: + """Analyze detailed information about an organization.""" + details = { + "activity_score": self._calculate_activity_score(org), + "size_category": self._categorize_size(org.get("public_repos", 0)), + "age_years": self._calculate_age(org.get("created_at", "")), + } + + return details + + def _calculate_activity_score(self, org: Dict[str, Any]) -> float: + """Calculate a simple activity score based on available metrics.""" + repos = org.get("public_repos", 0) + followers = org.get("followers", 0) + + # Simple scoring algorithm + score = (repos * 0.1) + (followers * 0.01) + return min(score, 100.0) # Cap at 100 + + def _categorize_size(self, repo_count: int) -> str: + """Categorize organization size based on repository count.""" + if repo_count < 10: + return "small" + elif repo_count < 50: + return "medium" + elif repo_count < 200: + return "large" + else: + return "enterprise" + + def _calculate_age(self, created_at: str) -> float: + """Calculate organization age in years.""" + if not created_at: + return 0.0 + + try: + from datetime import datetime + created = datetime.fromisoformat(created_at.replace("Z", "+00:00")) + now = datetime.now(created.tzinfo) + return (now - created).days / 365.25 + except Exception: + return 0.0 + + def _generate_summary(self, organizations: List[Dict[str, Any]]) -> Dict[str, Any]: + """Generate summary statistics from organization analysis.""" + if not organizations: + return {"total": 0, "message": "No organizations analyzed"} + + total_repos = sum(org.get("public_repos", 0) for org in organizations) + total_followers = sum(org.get("followers", 0) for org in organizations) + + size_categories = {} + for org in organizations: + category = org.get("size_category", "unknown") + size_categories[category] = size_categories.get(category, 0) + 1 + + return { + "total_organizations": len(organizations), + "total_public_repos": total_repos, + "total_followers": total_followers, + "average_repos_per_org": total_repos / len(organizations), + "size_distribution": size_categories, + "top_organizations": sorted( + organizations, + key=lambda x: x.get("activity_score", 0), + reverse=True + )[:5] + } + + +# Create workflow using the @app.async_tool decorator +app = MCPApp(name="oauth_workflow_example") + + +@app.async_tool +async def analyze_github_ecosystem( + app_ctx: Context, + focus_areas: List[str], + include_details: bool = True +) -> Dict[str, Any]: + """ + Analyze the GitHub ecosystem based on focus areas. + + This workflow demonstrates using pre-authorized OAuth tokens + to analyze organizations across different domains. + + Args: + focus_areas: Areas to focus on (e.g., ["AI/ML", "cloud", "security"]) + include_details: Whether to include detailed analysis + + Returns: + Comprehensive analysis of the GitHub ecosystem + """ + logger = app_ctx.logger + logger.info(f"Starting GitHub ecosystem analysis for: {focus_areas}") + + # Create the analyzer agent + analyzer = GitHubOrganizationAnalyzer(context=app_ctx) + + # Map focus areas to search queries + query_mapping = { + "AI/ML": ["machine-learning", "artificial-intelligence", "deep-learning", "tensorflow", "pytorch"], + "cloud": ["cloud-computing", "aws", "azure", "kubernetes", "docker"], + "security": ["cybersecurity", "security", "encryption", "vulnerability"], + "web": ["web-development", "javascript", "react", "vue", "angular"], + "mobile": ["mobile-development", "android", "ios", "react-native", "flutter"], + "data": ["data-science", "analytics", "big-data", "database", "sql"], + "devtools": ["developer-tools", "ci-cd", "testing", "monitoring", "automation"] + } + + all_queries = [] + for area in focus_areas: + queries = query_mapping.get(area.lower(), [area.lower()]) + all_queries.extend(queries) + + # Remove duplicates while preserving order + unique_queries = list(dict.fromkeys(all_queries)) + + logger.info(f"Executing {len(unique_queries)} organization searches") + + try: + # Perform the analysis + analysis_results = await analyzer.analyze_organizations( + queries=unique_queries, + detailed_analysis=include_details + ) + + # Add ecosystem-level insights + ecosystem_analysis = { + "focus_areas": focus_areas, + "timestamp": time.time(), + "queries_executed": unique_queries, + "results": analysis_results, + "insights": _generate_ecosystem_insights(analysis_results) + } + + logger.info("GitHub ecosystem analysis completed successfully") + return ecosystem_analysis + + except Exception as e: + logger.error(f"Ecosystem analysis failed: {e}") + raise + + +def _generate_ecosystem_insights(results: Dict[str, Any]) -> Dict[str, Any]: + """Generate high-level insights from the ecosystem analysis.""" + organizations = results.get("organizations", []) + summary = results.get("summary", {}) + + if not organizations: + return {"message": "No data available for insights"} + + # Find trends and patterns + insights = { + "dominant_languages": _analyze_language_trends(organizations), + "geographic_distribution": _analyze_geographic_distribution(organizations), + "maturity_analysis": _analyze_organization_maturity(organizations), + "activity_patterns": _analyze_activity_patterns(organizations) + } + + return insights + + +def _analyze_language_trends(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: + """Analyze programming language trends from organization data.""" + # This is a simplified example - in a real implementation, + # you might use additional GitHub API calls to get language data + return { + "message": "Language trend analysis would require additional API calls", + "suggestion": "Use repository listing and language detection APIs" + } + + +def _analyze_geographic_distribution(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: + """Analyze geographic distribution of organizations.""" + locations = {} + for org in organizations: + location = org.get("location", "").strip() + if location: + locations[location] = locations.get(location, 0) + 1 + + return { + "total_with_location": len([org for org in organizations if org.get("location")]), + "top_locations": dict(sorted(locations.items(), key=lambda x: x[1], reverse=True)[:10]) + } + + +def _analyze_organization_maturity(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: + """Analyze the maturity of organizations.""" + mature_count = sum(1 for org in organizations if org.get("age_years", 0) > 5) + established_count = sum(1 for org in organizations if 2 <= org.get("age_years", 0) <= 5) + new_count = sum(1 for org in organizations if org.get("age_years", 0) < 2) + + return { + "mature_orgs": mature_count, # > 5 years + "established_orgs": established_count, # 2-5 years + "new_orgs": new_count, # < 2 years + "maturity_ratio": mature_count / len(organizations) if organizations else 0 + } + + +def _analyze_activity_patterns(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: + """Analyze activity patterns across organizations.""" + if not organizations: + return {} + + activity_scores = [org.get("activity_score", 0) for org in organizations] + + return { + "average_activity": sum(activity_scores) / len(activity_scores), + "high_activity_count": sum(1 for score in activity_scores if score > 75), + "low_activity_count": sum(1 for score in activity_scores if score < 25), + "activity_distribution": { + "high": sum(1 for score in activity_scores if score > 75), + "medium": sum(1 for score in activity_scores if 25 <= score <= 75), + "low": sum(1 for score in activity_scores if score < 25) + } + } + + +async def demonstrate_pre_auth_workflow(): + """ + Demonstrate the workflow with pre-authorization. + """ + print("OAuth Workflow Pre-Authorization Example") + print("=" * 50) + + # Note: In a real scenario, you would use the MCP agent server + # to call the workflow_pre_auth endpoint before running the workflow + print("\n1. Pre-authorization step:") + print(" Before running this workflow, you should pre-authorize OAuth tokens:") + print(" Use the workflow_pre_auth endpoint with the following structure:") + + example_tokens = [ + { + "access_token": "github_oauth_access_token_here", + "refresh_token": "github_oauth_refresh_token_here", + "server_name": "github", + "scopes": ["read:org", "public_repo"], + "authorization_server": "https://github.com/login/oauth/authorize" + } + ] + + print(f" Token structure: {json.dumps(example_tokens, indent=2)}") + + print("\n2. Running workflow with pre-authorized tokens:") + + try: + async with app.run() as workflow_app: + # Simulate workflow execution + # In practice, this would be called through the MCP agent server + context = workflow_app.context + + result = await analyze_github_ecosystem( + app_ctx=context, + focus_areas=["AI/ML", "cloud", "security"], + include_details=True + ) + + print(f"\n3. Workflow Results:") + print(f" - Focus areas analyzed: {result['focus_areas']}") + print(f" - Queries executed: {len(result['queries_executed'])}") + print(f" - Organizations found: {result['results']['summary'].get('total_organizations', 0)}") + + if result['results']['errors']: + print(f" - Errors encountered: {len(result['results']['errors'])}") + + print(f"\n4. Ecosystem Insights:") + insights = result['insights'] + if 'geographic_distribution' in insights: + top_locations = insights['geographic_distribution'].get('top_locations', {}) + if top_locations: + print(f" - Top locations: {list(top_locations.keys())[:3]}") + + if 'maturity_analysis' in insights: + maturity = insights['maturity_analysis'] + print(f" - Mature organizations: {maturity.get('mature_orgs', 0)}") + print(f" - Maturity ratio: {maturity.get('maturity_ratio', 0):.2%}") + + except Exception as e: + print(f" Workflow failed: {e}") + print("\n This is expected if OAuth tokens are not properly configured.") + print(" To run this example successfully:") + print(" 1. Set up a GitHub OAuth app") + print(" 2. Configure mcp_agent.config.yaml with OAuth settings") + print(" 3. Use workflow_pre_auth to store valid tokens") + print(" 4. Run the workflow through the MCP agent server") + + +async def main(): + """ + Main function demonstrating the workflow pre-authorization pattern. + """ + await demonstrate_pre_auth_workflow() + + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/examples/oauth/workflow_pre_auth/client.py b/examples/oauth/workflow_pre_auth/client.py new file mode 100644 index 000000000..ce80b488b --- /dev/null +++ b/examples/oauth/workflow_pre_auth/client.py @@ -0,0 +1,193 @@ +import argparse +import asyncio +import json +import time +import os + +from datetime import timedelta +from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream +from mcp import ClientSession +from mcp.types import CallToolResult, LoggingMessageNotificationParams +from mcp_agent.app import MCPApp +from mcp_agent.config import MCPServerSettings +from mcp_agent.core.context import Context +from mcp_agent.executor.workflow import WorkflowExecution +from mcp_agent.mcp.gen_client import gen_client +from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession +from mcp_agent.human_input.console_handler import console_input_callback +from mcp_agent.elicitation.handler import console_elicitation_callback + +from rich import print + +try: + from exceptiongroup import ExceptionGroup as _ExceptionGroup # Python 3.10 backport +except Exception: # pragma: no cover + _ExceptionGroup = None # type: ignore +try: + from anyio import BrokenResourceError as _BrokenResourceError +except Exception: # pragma: no cover + _BrokenResourceError = None # type: ignore + +# Get GitHub access token from environment or ask user +access_token = os.getenv('GITHUB_ACCESS_TOKEN') + +if not access_token: + print("\nGitHub access token not found in environment variable GITHUB_ACCESS_TOKEN") + print("\nTo get a GitHub access token:") + print("1. Run the oauth_demo.py script from examples/oauth/ to get a fresh token") + print("2. Or go to GitHub Settings > Developer settings > Personal access tokens") + print("3. Create a token with 'read:org' and 'public_repo' scopes") + print("\nThen set the token:") + print("export GITHUB_ACCESS_TOKEN='your_token_here'") + +# Verify token format +if not access_token.startswith(('gho_', 'ghp_', 'github_pat_')): + print(f"Warning: Token doesn't look like a GitHub token (got: {access_token[:10]}...)") + print("GitHub tokens usually start with 'gho_', 'ghp_', or 'github_pat_'") + + +async def main(): + # Create MCPApp to get the server registry + app = MCPApp( + name="workflow_mcp_client", + human_input_callback=console_input_callback, + elicitation_callback=console_elicitation_callback, + ) + async with app.run() as client_app: + logger = client_app.logger + context = client_app.context + + # Connect to the workflow server + logger.info("Connecting to workflow server...") + + # Override the server configuration to point to our local script + context.server_registry.registry["basic_agent_server"] = MCPServerSettings( + name="basic_agent_server", + description="Local workflow server running the basic agent example", + command="uv", + args=["run", "main.py"], + ) + + # Define a logging callback to receive server-side log notifications + async def on_server_log(params: LoggingMessageNotificationParams) -> None: + level = params.level.upper() + name = params.logger or "server" + print(f"[SERVER LOG] [{level}] [{name}] {params.data}") + + # Provide a client session factory that installs our logging callback + # and prints non-logging notifications to the console + class ConsolePrintingClientSession(MCPAgentClientSession): + async def _received_notification(self, notification): # type: ignore[override] + try: + method = getattr(notification.root, "method", None) + except Exception: + method = None + + # Avoid duplicating server log prints (handled by logging_callback) + if method and method != "notifications/message": + try: + data = notification.model_dump() + except Exception: + data = str(notification) + print(f"[SERVER NOTIFY] {method}: {data}") + + return await super()._received_notification(notification) + + def make_session( + read_stream: MemoryObjectReceiveStream, + write_stream: MemoryObjectSendStream, + read_timeout_seconds: timedelta | None, + context: Context | None = None, + ) -> ClientSession: + return ConsolePrintingClientSession( + read_stream=read_stream, + write_stream=write_stream, + read_timeout_seconds=read_timeout_seconds, + logging_callback=on_server_log, + context=context, + ) + + try: + async with gen_client( + "basic_agent_server", + context.server_registry, + client_session_factory=make_session, + ) as server: + # List available tools + tools_result = await server.list_tools() + logger.info( + "Available tools:", + data={"tools": [tool.name for tool in tools_result.tools]}, + ) + + await server.call_tool("workflows-pre-auth", + arguments={ + "workflow_name": "github_org_search", + "tokens": [ + { + "access_token": access_token, + "server_name": "github", + "scopes": ["read:org", "public_repo", "user:email"], + "authorization_server": "https://github.com/login/oauth", + "token_type": "Bearer" + } + ] + }) + + print(await server.call_tool("github_org_search", {"query": "last mile ai"})) + except Exception as e: + # Tolerate benign shutdown races from stdio client (BrokenResourceError within ExceptionGroup) + if _ExceptionGroup is not None and isinstance(e, _ExceptionGroup): + subs = getattr(e, "exceptions", []) or [] + if ( + _BrokenResourceError is not None + and subs + and all(isinstance(se, _BrokenResourceError) for se in subs) + ): + logger.debug("Ignored BrokenResourceError from stdio shutdown") + else: + raise + elif _BrokenResourceError is not None and isinstance( + e, _BrokenResourceError + ): + logger.debug("Ignored BrokenResourceError from stdio shutdown") + elif "BrokenResourceError" in str(e): + logger.debug( + "Ignored BrokenResourceError from stdio shutdown (string match)" + ) + else: + raise + # Nudge cleanup of subprocess transports before the loop closes to avoid + # 'Event loop is closed' from BaseSubprocessTransport.__del__ on GC. + try: + await asyncio.sleep(0) + except Exception: + pass + try: + import gc + + gc.collect() + except Exception: + pass + + +def _tool_result_to_json(tool_result: CallToolResult): + if tool_result.content and len(tool_result.content) > 0: + text = tool_result.content[0].text + try: + # Try to parse the response as JSON if it's a string + import json + + return json.loads(text) + except (json.JSONDecodeError, TypeError): + # If it's not valid JSON, just use the text + return None + + +if __name__ == "__main__": + start = time.time() + asyncio.run(main()) + end = time.time() + t = end - start + + print(f"Total run time: {t:.2f}s") diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py new file mode 100644 index 000000000..f725875f4 --- /dev/null +++ b/examples/oauth/workflow_pre_auth/main.py @@ -0,0 +1,139 @@ +""" +Workflow MCP Server Example + +This example demonstrates three approaches to creating agents and workflows: +1. Traditional workflow-based approach with manual agent creation +2. Programmatic agent configuration using AgentConfig +3. Declarative agent configuration using FastMCPApp decorators +""" + +import argparse +import asyncio +import json +import os +from typing import Dict, Any, Optional +from pydantic import AnyHttpUrl + +from mcp.server.fastmcp import FastMCP +from mcp_agent.core.context import Context as AppContext + +from mcp_agent.app import MCPApp +from mcp_agent.server.app_server import create_mcp_server_for_app +from mcp_agent.agents.agent import Agent +from mcp_agent.workflows.llm.augmented_llm import RequestParams +from mcp_agent.workflows.llm.llm_selector import ModelPreferences +from mcp_agent.workflows.llm.augmented_llm_anthropic import AnthropicAugmentedLLM +from mcp_agent.workflows.llm.augmented_llm_openai import OpenAIAugmentedLLM +from mcp_agent.workflows.parallel.parallel_llm import ParallelLLM +from mcp_agent.executor.workflow import Workflow, WorkflowResult +from mcp_agent.tracing.token_counter import TokenNode +from mcp_agent.human_input.console_handler import console_input_callback +from mcp_agent.elicitation.handler import console_elicitation_callback +from mcp_agent.mcp.gen_client import gen_client +from mcp_agent.config import MCPServerSettings, Settings, LoggerSettings, MCPSettings, MCPServerAuthSettings, \ + MCPOAuthClientSettings + +# Note: This is purely optional: +# if not provided, a default FastMCP server will be created by MCPApp using create_mcp_server_for_app() +mcp = FastMCP(name="basic_agent_server", instructions="My basic agent server example.") + + +class MCPServerOAuthSettings: + pass + + +settings = Settings( + execution_engine="asyncio", + logger=LoggerSettings(level="info"), + mcp=MCPSettings( + servers={ + "github": MCPServerSettings( + name="github", + transport="streamable_http", + url="https://api.githubcopilot.com/mcp/", + auth=MCPServerAuthSettings( + oauth=MCPOAuthClientSettings( + enabled=True, + scopes= [ + "read:org", # Required for search_orgs tool + "public_repo", # Access to public repositories + "user:email" # User information access + ], + authorization_server=AnyHttpUrl("https://github.com/login/oauth"), + resource=AnyHttpUrl("https://api.githubcopilot.com/mcp") + ) + ) + ) + } + ), + ) + +# Define the MCPApp instance. The server created for this app will advertise the +# MCP logging capability and forward structured logs upstream to connected clients. +app = MCPApp( + name="basic_agent_server", + description="Basic agent server example", + mcp=mcp, + settings=settings, +) + + +@app.tool(name="github_org_search") +async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: + from mcp_agent.mcp.gen_client import gen_client + + try: + async with gen_client( + "github", + server_registry=app_ctx.server_registry, + context=app_ctx + ) as github_client: + result = await github_client.call_tool( + "search_orgs", + { + "query": query, + "perPage": 10, + "sort": "best-match", + "order": "desc" + } + ) + + organizations = [] + if result.content: + for content_item in result.content: + if hasattr(content_item, 'text'): + try: + data = json.loads(content_item.text) + if isinstance(data, dict) and 'items' in data: + organizations.extend(data['items']) + elif isinstance(data, list): + organizations.extend(data) + except json.JSONDecodeError: + pass + + return str(organizations) + except Exception as e: + import traceback + return f"Error: {traceback.format_exc()}" + +async def main(): + async with app.run() as agent_app: + # Log registered workflows and agent configurations + agent_app.logger.info(f"Creating MCP server for {agent_app.name}") + + agent_app.logger.info("Registered workflows:") + for workflow_id in agent_app.workflows: + agent_app.logger.info(f" - {workflow_id}") + + # Create the MCP server that exposes both workflows and agent configurations, + # optionally using custom FastMCP settings + mcp_server = create_mcp_server_for_app(agent_app) + agent_app.logger.info(f"MCP Server settings: {mcp_server.settings}") + + # Run the server + await mcp_server.run_stdio_async() + # await mcp_server.run_sse_async() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/src/mcp_agent/app.py b/src/mcp_agent/app.py index 558691071..2c3336a0d 100644 --- a/src/mcp_agent/app.py +++ b/src/mcp_agent/app.py @@ -260,6 +260,7 @@ async def initialize(self): oauth_settings = None if oauth_settings: + self.logger.debug("Initializing OAuth token management") token_store = InMemoryTokenStore() token_manager = TokenManager( token_store=token_store, @@ -268,6 +269,11 @@ async def initialize(self): self._context.token_store = token_store self._context.token_manager = token_manager + # Check for pre-configured tokens and store them with synthetic users + await self._initialize_preconfigured_tokens(token_manager) + else: + self.logger.debug("No OAuth settings found, skipping OAuth initialization") + # Provide a safe default bound context for loggers created after init without explicit context try: set_default_bound_context(self._context) @@ -345,6 +351,44 @@ async def initialize(self): }, ) + async def _initialize_preconfigured_tokens(self, token_manager): + """Check for pre-configured OAuth tokens and store them with a single synthetic user.""" + + mcp_config = getattr(self._context.config, 'mcp', None) + if not mcp_config or not getattr(mcp_config, 'servers', None): + self.logger.debug("No MCP servers found in config, skipping token initialization") + return + + servers = mcp_config.servers + self.logger.debug(f"Found MCP servers in config: {list(servers.keys())}") + + servers_with_tokens = [] + + # First pass: check which servers have pre-configured tokens + for server_name, server_config in servers.items(): + if not hasattr(server_config, 'auth') or not server_config.auth: + self.logger.debug(f"Server '{server_name}' has no auth config, skipping") + continue + + oauth_config = getattr(server_config.auth, 'oauth', None) + + if not oauth_config or not oauth_config.enabled or not oauth_config.access_token: + continue + + self.logger.debug(f"Server '{server_name}' has pre-configured OAuth token") + servers_with_tokens.append((server_name, server_config)) + + # If we have any servers with pre-configured tokens, create a single synthetic user + if servers_with_tokens: + synthetic_user = token_manager.create_default_user_for_preconfigured_tokens() + self._context.current_user = synthetic_user + self.logger.info(f"Created synthetic user for pre-configured OAuth tokens: {synthetic_user.cache_key}") + + # Second pass: store all tokens using the same synthetic user + for server_name, server_config in servers_with_tokens: + self.logger.info(f"Storing pre-configured OAuth token for server: {server_name}") + await token_manager.store_preconfigured_token(server_name, server_config, synthetic_user) + async def get_token_node(self): """Return the root app token node, if available.""" if not self._context or not getattr(self._context, "token_counter", None): diff --git a/src/mcp_agent/config.py b/src/mcp_agent/config.py index 59d8ef84d..ddc14ea8a 100644 --- a/src/mcp_agent/config.py +++ b/src/mcp_agent/config.py @@ -86,6 +86,11 @@ class MCPOAuthClientSettings(BaseModel): authorization_server: AnyHttpUrl | None = None client_id: str | None = None client_secret: str | None = None + # Support for pre-configured access tokens (bypasses OAuth flow) + access_token: str | None = None + refresh_token: str | None = None + expires_at: float | None = None + token_type: str = "Bearer" redirect_uri_options: List[str] = Field(default_factory=list) extra_authorize_params: Dict[str, str] = Field(default_factory=dict) extra_token_params: Dict[str, str] = Field(default_factory=dict) diff --git a/src/mcp_agent/oauth/http/auth.py b/src/mcp_agent/oauth/http/auth.py index 29b2028ce..8fba21757 100644 --- a/src/mcp_agent/oauth/http/auth.py +++ b/src/mcp_agent/oauth/http/auth.py @@ -30,16 +30,18 @@ def __init__( self._scopes = list(scopes) if scopes is not None else None async def async_auth_flow(self, request: httpx.Request): - token_record = await self._token_manager.ensure_access_token( - context=self._context, - server_name=self._server_name, - server_config=self._server_config, - scopes=self._scopes, - ) + try: + token_record = await self._token_manager.ensure_access_token( + context=self._context, + server_name=self._server_name, + server_config=self._server_config, + scopes=self._scopes, + ) + except Exception as e: + raise request.headers["Authorization"] = ( f"{token_record.token_type} {token_record.access_token}" ) - retry_request = request.copy() response = yield request if response.status_code != 401: @@ -62,6 +64,14 @@ async def async_auth_flow(self, request: httpx.Request): server_config=self._server_config, scopes=self._scopes, ) + + # Create a new request with the refreshed token + retry_request = httpx.Request( + method=request.method, + url=request.url, + headers=request.headers.copy(), + content=request.content, + ) retry_request.headers["Authorization"] = ( f"{refreshed_record.token_type} {refreshed_record.access_token}" ) diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index 62d0308b9..d2bd3d6b2 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -39,6 +39,17 @@ logger = get_logger(__name__) +def create_default_user_for_preconfigured_tokens() -> "OAuthUserIdentity": + """Create a synthetic user identity for pre-configured tokens.""" + from mcp_agent.oauth.identity import OAuthUserIdentity + + return OAuthUserIdentity( + provider="mcp-agent", + subject="preconfigured-tokens", + claims={"token_source": "preconfigured", "description": "Synthetic user for pre-configured OAuth tokens"} + ) + + class TokenManager: """High-level orchestrator for acquiring and refreshing OAuth tokens.""" @@ -60,6 +71,44 @@ def __init__( self._resource_metadata_cache: Dict[str, tuple[float, object]] = {} self._auth_metadata_cache: Dict[str, tuple[float, object]] = {} + async def store_preconfigured_token( + self, + server_name: str, + server_config, + synthetic_user: "OAuthUserIdentity" + ) -> None: + """Store a pre-configured token in the token store.""" + oauth_config = server_config.auth.oauth + + # Create token record + resource_str = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) + auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server else None + + from datetime import datetime, timezone + record = TokenRecord( + access_token=oauth_config.access_token, + refresh_token=oauth_config.refresh_token, + scopes=tuple(oauth_config.scopes or []), + expires_at=oauth_config.expires_at, + token_type=oauth_config.token_type, + resource=resource_str, + authorization_server=auth_server_str, + obtained_at=datetime.now(tz=timezone.utc).timestamp(), + metadata={"server_name": server_name, "pre_configured": True} + ) + + # Create storage key + key = TokenStoreKey( + user_key=synthetic_user.cache_key, + resource=resource_str or "", + authorization_server=auth_server_str, + scope_fingerprint=scope_fingerprint(oauth_config.scopes or []) + ) + + # Store the token + logger.debug(f"Storing token with key: user_key={key.user_key}, resource={key.resource}, auth_server={key.authorization_server}, scope_fingerprint={key.scope_fingerprint}") + await self._token_store.set(key, record) + async def ensure_access_token( self, *, @@ -79,33 +128,26 @@ async def ensure_access_token( user = context.current_user if not user: raise MissingUserIdentityError( - "No authenticated MCP user available for delegated OAuth flow" + "No authenticated MCP user available for OAuth flow (neither interactive nor pre-configured)" ) - resource_hint = oauth_config.resource - server_url = getattr(server_config, "url", None) - resource = normalize_resource(resource_hint, server_url) - - metadata_url = str(URL(resource).join("/.well-known/oauth-protected-resource")) - resource_metadata = await self._get_resource_metadata(metadata_url) - auth_server_url = select_authorization_server( - resource_metadata, oauth_config.authorization_server - ) - auth_metadata = await self._get_authorization_metadata(auth_server_url) + # Use the same key construction logic as store_preconfigured_token to ensure consistency + resource_str = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) + auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server else None + scope_list = list(scopes) if scopes is not None else list(oauth_config.scopes or []) - scope_list = ( - list(scopes) if scopes is not None else list(oauth_config.scopes or []) - ) key = TokenStoreKey( user_key=user.cache_key, - resource=resource, - authorization_server=auth_server_url, - scope_fingerprint=scope_fingerprint(scope_list), + resource=resource_str, + authorization_server=auth_server_str, + scope_fingerprint=scope_fingerprint(scope_list) ) + logger.debug(f"Looking for token with key: user_key={key.user_key}, resource={key.resource}, auth_server={key.authorization_server}, scope_fingerprint={key.scope_fingerprint}") lock = self._locks[key] async with lock: record = await self._token_store.get(key) + logger.debug(f"Found existing record: {record is not None}") leeway = ( self._settings.token_store.refresh_leeway_seconds if self._settings and self._settings.token_store @@ -114,7 +156,22 @@ async def ensure_access_token( if record and not record.is_expired(leeway_seconds=leeway): return record + # If token exists but expired, try to refresh it if record and record.refresh_token: + # For refresh, we need OAuth metadata + resource_hint = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) + server_url = getattr(server_config, "url", None) + resource = normalize_resource(resource_hint, server_url) + + # Get OAuth metadata for token refresh + parsed_resource = URL(resource) + metadata_url = str(parsed_resource.copy_with(path="/.well-known/oauth-protected-resource" + parsed_resource.path)) + resource_metadata = await self._get_resource_metadata(metadata_url) + auth_server_url = select_authorization_server( + resource_metadata, str(oauth_config.authorization_server) + ) + auth_metadata = await self._get_authorization_metadata(auth_server_url) + try: refreshed = await self._refresh_token( record, @@ -131,19 +188,37 @@ async def ensure_access_token( return refreshed await self._token_store.delete(key) - # Need to run full authorization flow - record = await self._flow.authorize( - context=context, - user=user, - server_name=server_name, - oauth_config=oauth_config, - resource=resource, - authorization_server_url=auth_server_url, - resource_metadata=resource_metadata, - auth_metadata=auth_metadata, - scopes=scope_list, - ) - await self._token_store.set(key, record) + # Need to run full authorization flow - only if no token found or refresh failed + if not record: + resource_hint = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) + server_url = getattr(server_config, "url", None) + resource = normalize_resource(resource_hint, server_url) + + # Get OAuth metadata for full authorization flow + parsed_resource = URL(resource) + metadata_url = str(parsed_resource.copy_with(path="/.well-known/oauth-protected-resource" + parsed_resource.path)) + resource_metadata = await self._get_resource_metadata(metadata_url) + auth_server_url = select_authorization_server( + resource_metadata, str(oauth_config.authorization_server) + ) + auth_metadata = await self._get_authorization_metadata(auth_server_url) + + record = await self._flow.authorize( + context=context, + user=user, + server_name=server_name, + oauth_config=oauth_config, + resource=resource, + authorization_server_url=auth_server_url, + resource_metadata=resource_metadata, + auth_metadata=auth_metadata, + scopes=scope_list, + ) + await self._token_store.set(key, record) + return record + + # If we reach here, we have an expired token with no refresh token + # Return it anyway - the caller will handle 401s return record async def invalidate( @@ -240,7 +315,9 @@ async def _get_authorization_metadata(self, url: str): cached = self._auth_metadata_cache.get(url) if cached and time.time() - cached[0] < 300: return cached[1] - metadata = await fetch_authorization_server_metadata(self._http_client, url) + # Construct OAuth authorization server metadata URL + metadata_url = url.rstrip('/') + '/.well-known/oauth-authorization-server' + metadata = await fetch_authorization_server_metadata(self._http_client, metadata_url) self._auth_metadata_cache[url] = (time.time(), metadata) return metadata diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index dfdbccd4c..526e84935 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -37,6 +37,7 @@ from mcp_agent.mcp.mcp_server_registry import ServerRegistry from mcp_agent.oauth.identity import OAuthUserIdentity from mcp_agent.oauth.callbacks import callback_registry +from mcp_agent.oauth.manager import create_default_user_for_preconfigured_tokens from mcp_agent.server.token_verifier import MCPAgentTokenVerifier if TYPE_CHECKING: @@ -1493,6 +1494,157 @@ async def cancel_workflow( return result + @mcp.tool(name="workflows-pre-auth") + async def workflow_pre_auth( + ctx: MCPContext, workflow_name: str, tokens: List[Dict[str, Any]] + ) -> Dict[str, Any]: + """ + Pre-authorize OAuth tokens for a workflow to use with MCP servers. + + Stores OAuth tokens that the workflow can use when connecting to various MCP servers. + This allows workflows to authenticate with external services without requiring + interactive OAuth flows during execution. + + Args: + workflow_name: The name of the workflow that will use these tokens. + tokens: List of OAuth token objects, each containing: + - access_token (str): The OAuth access token + - refresh_token (str, optional): The OAuth refresh token + - server_name (str): Name/identifier of the MCP server + - scopes (List[str], optional): List of OAuth scopes + - expires_at (float, optional): Token expiration timestamp + - authorization_server (str, optional): Authorization server URL + + Returns: + Dictionary with success status and count of stored tokens. + """ + # Ensure upstream session is available for any logs + try: + _set_upstream_from_request_ctx_if_available(ctx) + except Exception: + pass + + workflows_dict, app_context = _resolve_workflows_and_context(ctx) + if not workflows_dict or not app_context: + raise ToolError("Server context not available for MCPApp Server.") + + if workflow_name not in workflows_dict: + raise ToolError(f"Workflow '{workflow_name}' not found.") + + if not app_context.token_store: + raise ToolError("Token storage not available.") + + if not tokens: + raise ToolError("At least one token must be provided.") + + stored_count = 0 + errors = [] + + try: + for i, token_data in enumerate(tokens): + try: + # Validate required fields + if not isinstance(token_data, dict): + errors.append(f"Token {i}: must be a dictionary") + continue + + access_token = token_data.get("access_token") + server_name = token_data.get("server_name") + + if not access_token: + errors.append( + f"Token {i}: missing required 'access_token' field" + ) + continue + + if not server_name: + errors.append( + f"Token {i}: missing required 'server_name' field" + ) + continue + + # Create TokenRecord + from mcp_agent.oauth.records import TokenRecord + from mcp_agent.oauth.store.base import ( + TokenStoreKey, + scope_fingerprint, + ) + + scopes = token_data.get("scopes", []) + if isinstance(scopes, str): + scopes = [scopes] + elif not isinstance(scopes, list): + scopes = [] + + token_record = TokenRecord( + access_token=access_token, + refresh_token=token_data.get("refresh_token"), + scopes=tuple(scopes), + expires_at=token_data.get("expires_at"), + token_type=token_data.get("token_type", "Bearer"), + resource=server_name, + authorization_server=token_data.get("authorization_server"), + metadata={"workflow_name": workflow_name}, + ) + + # Ensure we have a user context for token storage + if not app_context.current_user: + # Create synthetic user if none exists + synthetic_user = create_default_user_for_preconfigured_tokens() + app_context.current_user = synthetic_user + logger.info(f"Created synthetic user for workflow pre-auth: {synthetic_user.cache_key}") + + # Create storage key using current user + store_key = TokenStoreKey( + user_key=app_context.current_user.cache_key, + resource=server_name, + authorization_server=token_data.get("authorization_server"), + scope_fingerprint=scope_fingerprint(scopes), + ) + + # Store the token + await app_context.token_store.set(store_key, token_record) + stored_count += 1 + + logger.info( + f"Stored OAuth token for workflow '{workflow_name}' and server '{server_name}'" + ) + + except Exception as e: + errors.append(f"Token {i}: {str(e)}") + logger.error( + f"Error storing token {i} for workflow '{workflow_name}': {e}" + ) + + if errors and stored_count == 0: + raise ToolError( + f"Failed to store any tokens. Errors: {'; '.join(errors)}" + ) + + result = { + "success": True, + "workflow_name": workflow_name, + "stored_tokens": stored_count, + "total_tokens": len(tokens), + } + + if errors: + result["errors"] = errors + result["partial_success"] = True + + logger.info( + f"Pre-authorization completed for workflow '{workflow_name}': " + f"{stored_count}/{len(tokens)} tokens stored" + ) + + return result + + except Exception as e: + logger.error( + f"Error in workflow pre-authorization for '{workflow_name}': {e}" + ) + raise ToolError(f"Failed to store tokens: {str(e)}") + # endregion return mcp From 1ddb4600fae7b31085ce3be4d9e079abc68c0c6b Mon Sep 17 00:00:00 2001 From: Roman van der Krogt Date: Fri, 26 Sep 2025 14:28:39 +0100 Subject: [PATCH 07/25] working oauth example with workflow_pre_auth --- examples/oauth/workflow_pre_auth/client.py | 11 +++-- examples/oauth/workflow_pre_auth/main.py | 7 +++ src/mcp_agent/oauth/manager.py | 12 +++-- src/mcp_agent/server/app_server.py | 57 ++++++++++++++++------ 4 files changed, 64 insertions(+), 23 deletions(-) diff --git a/examples/oauth/workflow_pre_auth/client.py b/examples/oauth/workflow_pre_auth/client.py index ce80b488b..a8014d3db 100644 --- a/examples/oauth/workflow_pre_auth/client.py +++ b/examples/oauth/workflow_pre_auth/client.py @@ -113,6 +113,12 @@ def make_session( context.server_registry, client_session_factory=make_session, ) as server: + try: + await server.set_logging_level("info") + except Exception: + # Older servers may not support logging capability + print("[client] Server does not support logging/setLevel") + # List available tools tools_result = await server.list_tools() logger.info( @@ -127,14 +133,11 @@ def make_session( { "access_token": access_token, "server_name": "github", - "scopes": ["read:org", "public_repo", "user:email"], - "authorization_server": "https://github.com/login/oauth", - "token_type": "Bearer" } ] }) - print(await server.call_tool("github_org_search", {"query": "last mile ai"})) + print(await server.call_tool("github_org_search", {"query": "lastmileai"})) except Exception as e: # Tolerate benign shutdown races from stdio client (BrokenResourceError within ExceptionGroup) if _ExceptionGroup is not None and isinstance(e, _ExceptionGroup): diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py index f725875f4..01194ef42 100644 --- a/examples/oauth/workflow_pre_auth/main.py +++ b/examples/oauth/workflow_pre_auth/main.py @@ -82,6 +82,13 @@ class MCPServerOAuthSettings: async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: from mcp_agent.mcp.gen_client import gen_client + # Use the context's app if available for proper logging with upstream_session + _app = app_ctx.app if app_ctx else app + # Ensure the app's logger is bound to the current context with upstream_session + if _app._logger and hasattr(_app._logger, "_bound_context"): + _app._logger._bound_context = app_ctx + logger = _app.logger + try: async with gen_client( "github", diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index d2bd3d6b2..9a74c89ae 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -127,9 +127,15 @@ async def ensure_access_token( user = context.current_user if not user: - raise MissingUserIdentityError( - "No authenticated MCP user available for OAuth flow (neither interactive nor pre-configured)" - ) + # TODO: with a proper oauth flow, we should always have a user in the context; since we don't have a server + # yet, mock a user if necessary. In the future, should be replaced by: something like: + # raise MissingUserIdentityError("No authenticated MCP user available for OAuth flow (neither + # interactive nor pre-configured)") + + # Create synthetic user if none exists + user = create_default_user_for_preconfigured_tokens() + context.current_user = user + logger.info(f"Created synthetic user for token access: {user.cache_key}") # Use the same key construction logic as store_preconfigured_token to ensure consistency resource_str = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index 526e84935..f2b03e923 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -24,6 +24,7 @@ from mcp_agent.app import MCPApp from mcp_agent.agents.agent import Agent +from mcp_agent.config import MCPOAuthClientSettings from mcp_agent.core.context_dependent import ContextDependent from mcp_agent.executor.workflow import Workflow from mcp_agent.executor.workflow_registry import ( @@ -1563,6 +1564,32 @@ async def workflow_pre_auth( ) continue + server_config = app_context.server_registry.get_server_config(server_name) + if not server_config: + errors.append( + f"Token {i}: server '{server_name}' not recognized" + ) + continue + + oauth_config: MCPOAuthClientSettings | None = None + if server_config and server_config.auth: + oauth_config = getattr(server_config.auth, "oauth", None) + if not oauth_config or not oauth_config.enabled: + errors.append( + f"Token {i}: Server '{server_name}' is not configured for OAuth authentication" + ) + continue + + # Ensure we have a user context for token storage + # TODO: This is a temporary workaround until we have proper oauth service, so that we have a user + # in the context from the oauth token + if not app_context.current_user: + # Create synthetic user if none exists + synthetic_user = create_default_user_for_preconfigured_tokens() + app_context.current_user = synthetic_user + logger.info(f"Created synthetic user for workflow pre-auth: {synthetic_user.cache_key}") + logger.info(f"{id(app_context)}: {app_context}") + # Create TokenRecord from mcp_agent.oauth.records import TokenRecord from mcp_agent.oauth.store.base import ( @@ -1570,38 +1597,36 @@ async def workflow_pre_auth( scope_fingerprint, ) - scopes = token_data.get("scopes", []) - if isinstance(scopes, str): - scopes = [scopes] - elif not isinstance(scopes, list): - scopes = [] + resource_str = str(oauth_config.resource) if oauth_config.resource \ + else getattr(server_config, "url", None) + auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server \ + else None + scope_list = list(oauth_config.scopes or []) token_record = TokenRecord( access_token=access_token, refresh_token=token_data.get("refresh_token"), - scopes=tuple(scopes), + scopes=tuple(scope_list), expires_at=token_data.get("expires_at"), token_type=token_data.get("token_type", "Bearer"), resource=server_name, - authorization_server=token_data.get("authorization_server"), + authorization_server=auth_server_str, metadata={"workflow_name": workflow_name}, ) - # Ensure we have a user context for token storage - if not app_context.current_user: - # Create synthetic user if none exists - synthetic_user = create_default_user_for_preconfigured_tokens() - app_context.current_user = synthetic_user - logger.info(f"Created synthetic user for workflow pre-auth: {synthetic_user.cache_key}") + str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) # Create storage key using current user store_key = TokenStoreKey( user_key=app_context.current_user.cache_key, - resource=server_name, - authorization_server=token_data.get("authorization_server"), - scope_fingerprint=scope_fingerprint(scopes), + resource=resource_str, + authorization_server=auth_server_str, + scope_fingerprint=scope_fingerprint(scope_list), ) + logger.debug( + f"Storing token with key: user_key={store_key.user_key}, resource={store_key.resource}, auth_server={store_key.authorization_server}, scope_fingerprint={store_key.scope_fingerprint}") + # Store the token await app_context.token_store.set(store_key, token_record) stored_count += 1 From 9500f8a714f49857d7deff2520604608203611a7 Mon Sep 17 00:00:00 2001 From: Roman van der Krogt Date: Fri, 26 Sep 2025 21:04:16 +0100 Subject: [PATCH 08/25] fixes to oauth discovery; add dynamic oath example --- examples/oauth/README.md | 19 +++ examples/oauth/dynamic_auth/client.py | 185 +++++++++++++++++++++ examples/oauth/dynamic_auth/main.py | 156 +++++++++++++++++ examples/oauth/dynamic_auth/worker.py | 31 ++++ examples/oauth/workflow_pre_auth/worker.py | 31 ++++ src/mcp_agent/oauth/flow.py | 31 ++-- src/mcp_agent/oauth/manager.py | 4 +- src/mcp_agent/server/app_server.py | 19 +++ 8 files changed, 463 insertions(+), 13 deletions(-) create mode 100644 examples/oauth/README.md create mode 100644 examples/oauth/dynamic_auth/client.py create mode 100644 examples/oauth/dynamic_auth/main.py create mode 100644 examples/oauth/dynamic_auth/worker.py create mode 100644 examples/oauth/workflow_pre_auth/worker.py diff --git a/examples/oauth/README.md b/examples/oauth/README.md new file mode 100644 index 000000000..dd966ba1f --- /dev/null +++ b/examples/oauth/README.md @@ -0,0 +1,19 @@ +# OAUTH scenarios + +## preconfigured + +In this case, a token is hard-coded into the configuration. +This is useful for testing or when the token is static. + +## workflow_pre_auth + +In this case, the client can call a `workflows_pre_auth` tool before calling a workflow to seed the tokens. +This is useful when the client can do the auth step, but the workflow cannot (e.g. because it runs async). +There is a slight hack employed here: since we don't have oauth for the mcp app, we do not have a user. +Since we need a user to store the token against, we create a synthetic user and use that. + +## dynamic_auth + +In this case, no tokens are provided, and the calls comes back to the client to do the auth step. +Currently implemented as an elicitation request (to align with the future elicit URL scheme). +I have not achieved full end-to-end flow here. \ No newline at end of file diff --git a/examples/oauth/dynamic_auth/client.py b/examples/oauth/dynamic_auth/client.py new file mode 100644 index 000000000..1a0374b57 --- /dev/null +++ b/examples/oauth/dynamic_auth/client.py @@ -0,0 +1,185 @@ +import argparse +import asyncio +import json +import time +import os + +from datetime import timedelta +from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream +from mcp import ClientSession +from mcp.types import CallToolResult, LoggingMessageNotificationParams +from mcp_agent.app import MCPApp +from mcp_agent.config import MCPServerSettings +from mcp_agent.core.context import Context +from mcp_agent.executor.workflow import WorkflowExecution +from mcp_agent.mcp.gen_client import gen_client +from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession +from mcp_agent.human_input.console_handler import console_input_callback +from mcp_agent.elicitation.handler import console_elicitation_callback + +from rich import print + +try: + from exceptiongroup import ExceptionGroup as _ExceptionGroup # Python 3.10 backport +except Exception: # pragma: no cover + _ExceptionGroup = None # type: ignore +try: + from anyio import BrokenResourceError as _BrokenResourceError +except Exception: # pragma: no cover + _BrokenResourceError = None # type: ignore + +# Get GitHub access token from environment or ask user +access_token = os.getenv('GITHUB_ACCESS_TOKEN') + +if not access_token: + print("\nGitHub access token not found in environment variable GITHUB_ACCESS_TOKEN") + print("\nTo get a GitHub access token:") + print("1. Run the oauth_demo.py script from examples/oauth/ to get a fresh token") + print("2. Or go to GitHub Settings > Developer settings > Personal access tokens") + print("3. Create a token with 'read:org' and 'public_repo' scopes") + print("\nThen set the token:") + print("export GITHUB_ACCESS_TOKEN='your_token_here'") + +# Verify token format +if not access_token.startswith(('gho_', 'ghp_', 'github_pat_')): + print(f"Warning: Token doesn't look like a GitHub token (got: {access_token[:10]}...)") + print("GitHub tokens usually start with 'gho_', 'ghp_', or 'github_pat_'") + + +async def main(): + # Create MCPApp to get the server registry + app = MCPApp( + name="workflow_mcp_client", + human_input_callback=console_input_callback, + elicitation_callback=console_elicitation_callback, + ) + async with app.run() as client_app: + logger = client_app.logger + context = client_app.context + + # Connect to the workflow server + logger.info("Connecting to workflow server...") + + # Override the server configuration to point to our local script + context.server_registry.registry["basic_agent_server"] = MCPServerSettings( + name="basic_agent_server", + description="Local workflow server running the basic agent example", + transport="sse", + url="http://127.0.0.1:8000/sse", + ) + + # Define a logging callback to receive server-side log notifications + async def on_server_log(params: LoggingMessageNotificationParams) -> None: + level = params.level.upper() + name = params.logger or "server" + print(f"[SERVER LOG] [{level}] [{name}] {params.data}") + + # Provide a client session factory that installs our logging callback + # and prints non-logging notifications to the console + class ConsolePrintingClientSession(MCPAgentClientSession): + async def _received_notification(self, notification): # type: ignore[override] + try: + method = getattr(notification.root, "method", None) + except Exception: + method = None + + # Avoid duplicating server log prints (handled by logging_callback) + if method and method != "notifications/message": + try: + data = notification.model_dump() + except Exception: + data = str(notification) + print(f"[SERVER NOTIFY] {method}: {data}") + + return await super()._received_notification(notification) + + def make_session( + read_stream: MemoryObjectReceiveStream, + write_stream: MemoryObjectSendStream, + read_timeout_seconds: timedelta | None, + context: Context | None = None, + ) -> ClientSession: + return ConsolePrintingClientSession( + read_stream=read_stream, + write_stream=write_stream, + read_timeout_seconds=read_timeout_seconds, + logging_callback=on_server_log, + context=context, + ) + + try: + async with gen_client( + "basic_agent_server", + context.server_registry, + client_session_factory=make_session, + ) as server: + try: + await server.set_logging_level("info") + except Exception: + # Older servers may not support logging capability + print("[client] Server does not support logging/setLevel") + + # List available tools + tools_result = await server.list_tools() + logger.info( + "Available tools:", + data={"tools": [tool.name for tool in tools_result.tools]}, + ) + + print(await server.call_tool("github_org_search", {"query": "lastmileai"})) + except Exception as e: + # Tolerate benign shutdown races from stdio client (BrokenResourceError within ExceptionGroup) + if _ExceptionGroup is not None and isinstance(e, _ExceptionGroup): + subs = getattr(e, "exceptions", []) or [] + if ( + _BrokenResourceError is not None + and subs + and all(isinstance(se, _BrokenResourceError) for se in subs) + ): + logger.debug("Ignored BrokenResourceError from stdio shutdown") + else: + raise + elif _BrokenResourceError is not None and isinstance( + e, _BrokenResourceError + ): + logger.debug("Ignored BrokenResourceError from stdio shutdown") + elif "BrokenResourceError" in str(e): + logger.debug( + "Ignored BrokenResourceError from stdio shutdown (string match)" + ) + else: + raise + # Nudge cleanup of subprocess transports before the loop closes to avoid + # 'Event loop is closed' from BaseSubprocessTransport.__del__ on GC. + try: + await asyncio.sleep(0) + except Exception: + pass + try: + import gc + + gc.collect() + except Exception: + pass + + +def _tool_result_to_json(tool_result: CallToolResult): + if tool_result.content and len(tool_result.content) > 0: + text = tool_result.content[0].text + try: + # Try to parse the response as JSON if it's a string + import json + + return json.loads(text) + except (json.JSONDecodeError, TypeError): + # If it's not valid JSON, just use the text + return None + + +if __name__ == "__main__": + start = time.time() + asyncio.run(main()) + end = time.time() + t = end - start + + print(f"Total run time: {t:.2f}s") diff --git a/examples/oauth/dynamic_auth/main.py b/examples/oauth/dynamic_auth/main.py new file mode 100644 index 000000000..8dbae64a1 --- /dev/null +++ b/examples/oauth/dynamic_auth/main.py @@ -0,0 +1,156 @@ +""" +Workflow MCP Server Example + +This example demonstrates three approaches to creating agents and workflows: +1. Traditional workflow-based approach with manual agent creation +2. Programmatic agent configuration using AgentConfig +3. Declarative agent configuration using FastMCPApp decorators +""" + +import asyncio +import json +import os +from pydantic import AnyHttpUrl + +from mcp.server.fastmcp import FastMCP + +from mcp_agent.app import MCPApp +from mcp_agent.server.app_server import create_mcp_server_for_app + +from mcp_agent.config import MCPServerSettings, Settings, LoggerSettings, MCPSettings, MCPServerAuthSettings, \ + MCPOAuthClientSettings, OAuthSettings, OAuthTokenStoreSettings, TemporalSettings + +# Note: This is purely optional: +# if not provided, a default FastMCP server will be created by MCPApp using create_mcp_server_for_app() +mcp = FastMCP(name="basic_agent_server", instructions="My basic agent server example.") + +client_id = os.getenv('GITHUB_CLIENT_ID') + +settings = Settings( + execution_engine="temporal", + temporal=TemporalSettings( + host="localhost:7233", + namespace="default", + task_queue="mcp-agent", + max_concurrent_activities=10, + ), + logger=LoggerSettings(level="info"), + oauth=OAuthSettings( + callback_base_url=AnyHttpUrl("http://localhost:8080"), + flow_timeout_seconds=300, + token_store=OAuthTokenStoreSettings(refresh_leeway_seconds=60), + ), + mcp=MCPSettings( + servers={ + "github": MCPServerSettings( + name="github", + transport="streamable_http", + url="https://api.githubcopilot.com/mcp/", + auth=MCPServerAuthSettings( + oauth=MCPOAuthClientSettings( + client_id=client_id, + use_internal_callback=True, + enabled=True, + scopes= [ + "read:org", # Required for search_orgs tool + "public_repo", # Access to public repositories + "user:email" # User information access + ], + authorization_server=AnyHttpUrl("https://github.com/login/oauth"), + resource=AnyHttpUrl("https://api.githubcopilot.com/mcp") + ) + ) + ) + } + ), + ) + +# Define the MCPApp instance. The server created for this app will advertise the +# MCP logging capability and forward structured logs upstream to connected clients. +app = MCPApp( + name="basic_agent_server", + description="Basic agent server example", + mcp=mcp, + settings=settings, +) + + +@app.workflow_task(name="github_org_search_activity") +async def github_org_search_activity(query: str) -> str: + from mcp_agent.mcp.gen_client import gen_client + + print("running activity)") + try: + async with gen_client( + "github", + server_registry=app.context.server_registry, + context=app.context + ) as github_client: + print("got client") + result = await github_client.call_tool( + "search_orgs", + { + "query": query, + "perPage": 10, + "sort": "best-match", + "order": "desc" + } + ) + + organizations = [] + if result.content: + for content_item in result.content: + if hasattr(content_item, 'text'): + try: + data = json.loads(content_item.text) + if isinstance(data, dict) and 'items' in data: + organizations.extend(data['items']) + elif isinstance(data, list): + organizations.extend(data) + except json.JSONDecodeError: + pass + + print(f"Organizations: {organizations}") + return str(organizations) + except Exception as e: + import traceback + traceback.print_exc() + return f"Error: {e}" + +@app.tool(name="github_org_search") +async def github_org_search(query: str) -> str: + if app._logger and hasattr(app._logger, "_bound_context"): + app._logger._bound_context = app.context + logger = app.logger + + result = await app.executor.execute(github_org_search_activity, query) + print(f"Result: {result}, {type(result)}") + + return "ok!" + # try: + # return await app.executor.execute(github_org_search_activity, query) + # except Exception as e: + # import traceback + # traceback.print_exc() + # return f"Error: {e}" + +async def main(): + async with app.run() as agent_app: + # Log registered workflows and agent configurations + agent_app.logger.info(f"Creating MCP server for {agent_app.name}") + + agent_app.logger.info("Registered workflows:") + for workflow_id in agent_app.workflows: + agent_app.logger.info(f" - {workflow_id}") + + # Create the MCP server that exposes both workflows and agent configurations, + # optionally using custom FastMCP settings + mcp_server = create_mcp_server_for_app(agent_app) + agent_app.logger.info(f"MCP Server settings: {mcp_server.settings}") + + # Run the server + await mcp_server.run_sse_async() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/oauth/dynamic_auth/worker.py b/examples/oauth/dynamic_auth/worker.py new file mode 100644 index 000000000..39b2a3c67 --- /dev/null +++ b/examples/oauth/dynamic_auth/worker.py @@ -0,0 +1,31 @@ +""" +Worker script for the Temporal workflow example. +This script starts a Temporal worker that can execute workflows and activities. +Run this script in a separate terminal window before running the main.py script. + +This leverages the TemporalExecutor's start_worker method to handle the worker setup. +""" + +import asyncio +import logging + + +from mcp_agent.executor.temporal import create_temporal_worker_for_app + +from main import app + +# Initialize logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +async def main(): + """ + Start a Temporal worker for the example workflows using the app's executor. + """ + async with create_temporal_worker_for_app(app) as worker: + await worker.run() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/oauth/workflow_pre_auth/worker.py b/examples/oauth/workflow_pre_auth/worker.py new file mode 100644 index 000000000..39b2a3c67 --- /dev/null +++ b/examples/oauth/workflow_pre_auth/worker.py @@ -0,0 +1,31 @@ +""" +Worker script for the Temporal workflow example. +This script starts a Temporal worker that can execute workflows and activities. +Run this script in a separate terminal window before running the main.py script. + +This leverages the TemporalExecutor's start_worker method to handle the worker setup. +""" + +import asyncio +import logging + + +from mcp_agent.executor.temporal import create_temporal_worker_for_app + +from main import app + +# Initialize logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +async def main(): + """ + Start a Temporal worker for the example workflows using the app's executor. + """ + async with create_temporal_worker_for_app(app) as worker: + await worker.run() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index 424385538..95ec90169 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -68,7 +68,7 @@ async def authorize( flow_id = uuid.uuid4().hex internal_redirect = None if oauth_config.use_internal_callback and self._settings.callback_base_url: - internal_redirect = f"{self._settings.callback_base_url.rstrip('/')}/internal/oauth/callback/{flow_id}" + internal_redirect = f"{str(self._settings.callback_base_url).rstrip('/')}/internal/oauth/callback/{flow_id}" redirect_options.insert(0, internal_redirect) if not redirect_options: @@ -83,18 +83,24 @@ async def authorize( state = generate_state() scope_param = " ".join(scopes) + params = { + "response_type":"code", + "client_id":client_id, + "redirect_uri":redirect_uri, + "scope":scope_param, + "state":state, + "code_challenge":code_challenge, + "code_challenge_method":"S256", + "resource":resource, + } + + # add extra params if any + if oauth_config.extra_authorize_params: + params.update(oauth_config.extra_authorize_params) + + import urllib.parse authorize_url = httpx.URL( - str(auth_metadata.authorization_endpoint) - ).include_query_params( - response_type="code", - client_id=client_id, - redirect_uri=redirect_uri, - scope=scope_param, - state=state, - code_challenge=code_challenge, - code_challenge_method="S256", - resource=resource, - **(oauth_config.extra_authorize_params or {}), + str(auth_metadata.authorization_endpoint) +"?" + urllib.parse.urlencode(params) ) callback_future = None @@ -209,6 +215,7 @@ async def _send_auth_request( context: Context, payload: Dict[str, Any] ) -> Dict[str, Any]: session = getattr(context, "upstream_session", None) + if session and isinstance(session, ServerSession): rpc = getattr(session, "rpc", None) if rpc and hasattr(rpc, "request"): diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index 9a74c89ae..d00dfe331 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -322,7 +322,9 @@ async def _get_authorization_metadata(self, url: str): if cached and time.time() - cached[0] < 300: return cached[1] # Construct OAuth authorization server metadata URL - metadata_url = url.rstrip('/') + '/.well-known/oauth-authorization-server' + parsed_url = URL(url) + metadata_url = str( + parsed_url.copy_with(path="/.well-known/oauth-authorization-server" + parsed_url.path)) metadata = await fetch_authorization_server_metadata(self._http_client, metadata_url) self._auth_metadata_cache[url] = (time.time(), metadata) return metadata diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index f2b03e923..6205933b6 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -10,6 +10,7 @@ import os import secrets import asyncio +from pydantic import BaseModel, Field from mcp.server.fastmcp import Context as MCPContext, FastMCP from mcp.server.fastmcp.server import AuthSettings @@ -717,6 +718,24 @@ async def _handle_specific_request( result = await session.send_request( request=req, result_type=EmptyResult ) # type: ignore[attr-defined] + return result.model_dump(by_alias=True, mode="json", exclude_none=True) + elif method == "auth/request": + # TODO: special handling of auth request, should be replaced by future URL elicitation + class AuthToken(BaseModel): + token: str = Field(description="The access token") + + req = ElicitRequest( + method="elicitation/create", + params=ElicitRequestParams( + message=params["message"] + "\n\n" + params["url"] , + requestedSchema=AuthToken.model_json_schema(), + ), + ) + + result = await session.send_request( + request=req, result_type=ElicitResult + ) # type: ignore[attr-defined] + return result.model_dump(by_alias=True, mode="json", exclude_none=True) else: raise ValueError(f"unsupported method: {method}") From 5240bada87b1861f57592af0a666f9f3caa712ee Mon Sep 17 00:00:00 2001 From: Roman van der Krogt Date: Mon, 29 Sep 2025 20:52:36 +0100 Subject: [PATCH 09/25] full e2e workflow --- examples/oauth/dynamic_auth/client.py | 22 ------------- examples/oauth/dynamic_auth/main.py | 31 ++++++++++++------- examples/oauth/preconfigured/main.py | 4 +-- examples/oauth/preconfigured/oauth_demo.py | 6 ++-- .../oauth/preconfigured/workflow_example.py | 5 ++- examples/oauth/workflow_pre_auth/client.py | 3 -- examples/oauth/workflow_pre_auth/main.py | 18 ++--------- src/mcp_agent/oauth/callbacks.py | 1 + src/mcp_agent/oauth/flow.py | 26 +++++++++++----- src/mcp_agent/oauth/http/auth.py | 2 +- src/mcp_agent/oauth/manager.py | 1 - src/mcp_agent/server/app_server.py | 23 +++++++++++--- 12 files changed, 67 insertions(+), 75 deletions(-) diff --git a/examples/oauth/dynamic_auth/client.py b/examples/oauth/dynamic_auth/client.py index 1a0374b57..4e7b67c3a 100644 --- a/examples/oauth/dynamic_auth/client.py +++ b/examples/oauth/dynamic_auth/client.py @@ -1,8 +1,5 @@ -import argparse import asyncio -import json import time -import os from datetime import timedelta from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream @@ -11,7 +8,6 @@ from mcp_agent.app import MCPApp from mcp_agent.config import MCPServerSettings from mcp_agent.core.context import Context -from mcp_agent.executor.workflow import WorkflowExecution from mcp_agent.mcp.gen_client import gen_client from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession from mcp_agent.human_input.console_handler import console_input_callback @@ -28,24 +24,6 @@ except Exception: # pragma: no cover _BrokenResourceError = None # type: ignore -# Get GitHub access token from environment or ask user -access_token = os.getenv('GITHUB_ACCESS_TOKEN') - -if not access_token: - print("\nGitHub access token not found in environment variable GITHUB_ACCESS_TOKEN") - print("\nTo get a GitHub access token:") - print("1. Run the oauth_demo.py script from examples/oauth/ to get a fresh token") - print("2. Or go to GitHub Settings > Developer settings > Personal access tokens") - print("3. Create a token with 'read:org' and 'public_repo' scopes") - print("\nThen set the token:") - print("export GITHUB_ACCESS_TOKEN='your_token_here'") - -# Verify token format -if not access_token.startswith(('gho_', 'ghp_', 'github_pat_')): - print(f"Warning: Token doesn't look like a GitHub token (got: {access_token[:10]}...)") - print("GitHub tokens usually start with 'gho_', 'ghp_', or 'github_pat_'") - - async def main(): # Create MCPApp to get the server registry app = MCPApp( diff --git a/examples/oauth/dynamic_auth/main.py b/examples/oauth/dynamic_auth/main.py index 8dbae64a1..3eb54728c 100644 --- a/examples/oauth/dynamic_auth/main.py +++ b/examples/oauth/dynamic_auth/main.py @@ -24,7 +24,21 @@ # if not provided, a default FastMCP server will be created by MCPApp using create_mcp_server_for_app() mcp = FastMCP(name="basic_agent_server", instructions="My basic agent server example.") + +# Get client id and secret from environment variables client_id = os.getenv('GITHUB_CLIENT_ID') +client_secret = os.getenv('GITHUB_CLIENT_SECRET') + +if not client_id or not client_secret: + print("\nGitHub client id and/or secret not found in GITHUB_CLIENT_Id and GITHUB_CLIENT_SECRET " + "environment variables.") + print("\nTo create these:") + print("\n1. Open your profile on github.com and navigate to 'Developer Settings'") + print("\n2. Create a new OAuth app and create a client secret for it.") + print("\n3. Create environment variables:") + print("\nexport GITHUB_CLIENT_ID='your_client_id_here'") + print("\nexport GITHUB_CLIENT_SECRET='your_client_secret_here'") + settings = Settings( execution_engine="temporal", @@ -36,7 +50,7 @@ ), logger=LoggerSettings(level="info"), oauth=OAuthSettings( - callback_base_url=AnyHttpUrl("http://localhost:8080"), + callback_base_url=AnyHttpUrl("http://localhost:8000"), flow_timeout_seconds=300, token_store=OAuthTokenStoreSettings(refresh_leeway_seconds=60), ), @@ -49,6 +63,7 @@ auth=MCPServerAuthSettings( oauth=MCPOAuthClientSettings( client_id=client_id, + client_secret=client_secret, use_internal_callback=True, enabled=True, scopes= [ @@ -121,18 +136,12 @@ async def github_org_search_activity(query: str) -> str: async def github_org_search(query: str) -> str: if app._logger and hasattr(app._logger, "_bound_context"): app._logger._bound_context = app.context - logger = app.logger result = await app.executor.execute(github_org_search_activity, query) - print(f"Result: {result}, {type(result)}") - - return "ok!" - # try: - # return await app.executor.execute(github_org_search_activity, query) - # except Exception as e: - # import traceback - # traceback.print_exc() - # return f"Error: {e}" + print(f"Result: {result}") + + return result + async def main(): async with app.run() as agent_app: diff --git a/examples/oauth/preconfigured/main.py b/examples/oauth/preconfigured/main.py index 64d228151..c20e164e7 100644 --- a/examples/oauth/preconfigured/main.py +++ b/examples/oauth/preconfigured/main.py @@ -18,8 +18,6 @@ from mcp_agent.app import MCPApp from mcp_agent.mcp.gen_client import gen_client -from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession -from mcp_agent.mcp.mcp_connection_manager import MCPConnectionManager # Create the MCP app with OAuth configuration app = MCPApp(name="oauth_github_example") @@ -78,7 +76,7 @@ async def search_github_orgs(query: str, limit: int = 5) -> List[Dict[str, Any]] } ) - logger.info(f"Search completed, processing results...") + logger.info("Search completed, processing results...") # Parse and return the results if result.content: diff --git a/examples/oauth/preconfigured/oauth_demo.py b/examples/oauth/preconfigured/oauth_demo.py index 9fb41d80b..4a4c47c58 100644 --- a/examples/oauth/preconfigured/oauth_demo.py +++ b/examples/oauth/preconfigured/oauth_demo.py @@ -198,7 +198,7 @@ async def run_oauth_flow(self, scopes: list = None) -> Dict[str, Any]: # Step 1: Generate authorization URL auth_url = self.get_authorization_url(scopes) - print(f"\n1. Please visit this URL to authorize the application:") + print("\n1. Please visit this URL to authorize the application:") print(f" {auth_url}") print("\n2. After authorization, you'll be redirected to a callback URL.") @@ -281,7 +281,7 @@ async def handle_callback(request): print("5. Authorization code received, exchanging for access token...") # Step 4: Exchange code for token - token_data = await self.exchange_code_for_token(code, state) + await self.exchange_code_for_token(code, state) print(" ✓ Access token obtained successfully") # Step 5: Test the token @@ -332,7 +332,7 @@ async def main(): print("OAuth Flow Completed Successfully!") print("=" * 50) - print(f"\nToken Details:") + print("\nToken Details:") print(f" Access Token: {token_data['access_token'][:20]}...") print(f" Expires At: {time.ctime(token_data['expires_at'])}") print(f" Scopes: {', '.join(token_data['scopes'])}") diff --git a/examples/oauth/preconfigured/workflow_example.py b/examples/oauth/preconfigured/workflow_example.py index 47521f584..59948bf7b 100644 --- a/examples/oauth/preconfigured/workflow_example.py +++ b/examples/oauth/preconfigured/workflow_example.py @@ -274,7 +274,6 @@ async def analyze_github_ecosystem( def _generate_ecosystem_insights(results: Dict[str, Any]) -> Dict[str, Any]: """Generate high-level insights from the ecosystem analysis.""" organizations = results.get("organizations", []) - summary = results.get("summary", {}) if not organizations: return {"message": "No data available for insights"} @@ -386,7 +385,7 @@ async def demonstrate_pre_auth_workflow(): include_details=True ) - print(f"\n3. Workflow Results:") + print("\n3. Workflow Results:") print(f" - Focus areas analyzed: {result['focus_areas']}") print(f" - Queries executed: {len(result['queries_executed'])}") print(f" - Organizations found: {result['results']['summary'].get('total_organizations', 0)}") @@ -394,7 +393,7 @@ async def demonstrate_pre_auth_workflow(): if result['results']['errors']: print(f" - Errors encountered: {len(result['results']['errors'])}") - print(f"\n4. Ecosystem Insights:") + print("\n4. Ecosystem Insights:") insights = result['insights'] if 'geographic_distribution' in insights: top_locations = insights['geographic_distribution'].get('top_locations', {}) diff --git a/examples/oauth/workflow_pre_auth/client.py b/examples/oauth/workflow_pre_auth/client.py index a8014d3db..873fdb364 100644 --- a/examples/oauth/workflow_pre_auth/client.py +++ b/examples/oauth/workflow_pre_auth/client.py @@ -1,6 +1,4 @@ -import argparse import asyncio -import json import time import os @@ -11,7 +9,6 @@ from mcp_agent.app import MCPApp from mcp_agent.config import MCPServerSettings from mcp_agent.core.context import Context -from mcp_agent.executor.workflow import WorkflowExecution from mcp_agent.mcp.gen_client import gen_client from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession from mcp_agent.human_input.console_handler import console_input_callback diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py index 01194ef42..18634378e 100644 --- a/examples/oauth/workflow_pre_auth/main.py +++ b/examples/oauth/workflow_pre_auth/main.py @@ -7,11 +7,9 @@ 3. Declarative agent configuration using FastMCPApp decorators """ -import argparse import asyncio import json -import os -from typing import Dict, Any, Optional +from typing import Optional from pydantic import AnyHttpUrl from mcp.server.fastmcp import FastMCP @@ -19,16 +17,6 @@ from mcp_agent.app import MCPApp from mcp_agent.server.app_server import create_mcp_server_for_app -from mcp_agent.agents.agent import Agent -from mcp_agent.workflows.llm.augmented_llm import RequestParams -from mcp_agent.workflows.llm.llm_selector import ModelPreferences -from mcp_agent.workflows.llm.augmented_llm_anthropic import AnthropicAugmentedLLM -from mcp_agent.workflows.llm.augmented_llm_openai import OpenAIAugmentedLLM -from mcp_agent.workflows.parallel.parallel_llm import ParallelLLM -from mcp_agent.executor.workflow import Workflow, WorkflowResult -from mcp_agent.tracing.token_counter import TokenNode -from mcp_agent.human_input.console_handler import console_input_callback -from mcp_agent.elicitation.handler import console_elicitation_callback from mcp_agent.mcp.gen_client import gen_client from mcp_agent.config import MCPServerSettings, Settings, LoggerSettings, MCPSettings, MCPServerAuthSettings, \ MCPOAuthClientSettings @@ -80,14 +68,12 @@ class MCPServerOAuthSettings: @app.tool(name="github_org_search") async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: - from mcp_agent.mcp.gen_client import gen_client # Use the context's app if available for proper logging with upstream_session _app = app_ctx.app if app_ctx else app # Ensure the app's logger is bound to the current context with upstream_session if _app._logger and hasattr(_app._logger, "_bound_context"): _app._logger._bound_context = app_ctx - logger = _app.logger try: async with gen_client( @@ -119,7 +105,7 @@ async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> pass return str(organizations) - except Exception as e: + except Exception: import traceback return f"Error: {traceback.format_exc()}" diff --git a/src/mcp_agent/oauth/callbacks.py b/src/mcp_agent/oauth/callbacks.py index 7cae8c992..8bfa99957 100644 --- a/src/mcp_agent/oauth/callbacks.py +++ b/src/mcp_agent/oauth/callbacks.py @@ -28,6 +28,7 @@ async def deliver(self, flow_id: str, payload: Dict[str, Any]) -> bool: async with self._lock: future = self._pending.get(flow_id) if future is None: + # print all entries in _pending for debugging return False if not future.done(): future.set_result(payload) diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index 95ec90169..a93dd69ea 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -5,6 +5,7 @@ import asyncio import time import uuid +from json import JSONDecodeError from typing import Any, Dict, Sequence from urllib.parse import parse_qs, urlparse @@ -111,6 +112,7 @@ async def authorize( "url": str(authorize_url), "message": f"Authorization required for {server_name}", "redirect_uri_options": redirect_options, + "flow_id": flow_id } result = await _send_auth_request(context, request_payload) @@ -120,6 +122,10 @@ async def authorize( callback_data = _parse_callback_params(result["url"]) if callback_future is not None: await callback_registry.discard(flow_id) + elif result and result.get("code"): + callback_data = result + if callback_future is not None: + await callback_registry.discard(flow_id) elif callback_future is not None: timeout = self._settings.flow_timeout_seconds or 300 try: @@ -170,21 +176,25 @@ async def authorize( data["client_secret"] = oauth_config.client_secret token_response = await self._http_client.post( - token_endpoint, data=data, auth=auth + token_endpoint, data=data, auth=auth, headers={"Accept": "application/json"} ) token_response.raise_for_status() - payload = token_response.json() - access_token = payload.get("access_token") + try: + callback_data = token_response.json() + except JSONDecodeError: + callback_data = _parse_callback_params("?" + token_response.text) + + access_token = callback_data.get("access_token") if not access_token: raise OAuthFlowError("Token endpoint response missing access_token") - refresh_token = payload.get("refresh_token") - expires_in = payload.get("expires_in") + refresh_token = callback_data.get("refresh_token") + expires_in = callback_data.get("expires_in") expires_at = None if isinstance(expires_in, (int, float)): expires_at = time.time() + float(expires_in) - scope_from_payload = payload.get("scope") + scope_from_payload = callback_data.get("scope") if isinstance(scope_from_payload, str) and scope_from_payload.strip(): effective_scopes = tuple(scope_from_payload.split()) else: @@ -195,10 +205,10 @@ async def authorize( refresh_token=refresh_token, expires_at=expires_at, scopes=effective_scopes, - token_type=str(payload.get("token_type", "Bearer")), + token_type=str(callback_data.get("token_type", "Bearer")), resource=resource, authorization_server=authorization_server_url, - metadata={"raw": payload}, + metadata={"raw": token_response.text}, ) diff --git a/src/mcp_agent/oauth/http/auth.py b/src/mcp_agent/oauth/http/auth.py index 8fba21757..a061e02ff 100644 --- a/src/mcp_agent/oauth/http/auth.py +++ b/src/mcp_agent/oauth/http/auth.py @@ -37,7 +37,7 @@ async def async_auth_flow(self, request: httpx.Request): server_config=self._server_config, scopes=self._scopes, ) - except Exception as e: + except Exception: raise request.headers["Authorization"] = ( f"{token_record.token_type} {token_record.access_token}" diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index d00dfe331..36e3577ea 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -13,7 +13,6 @@ from mcp_agent.config import MCPOAuthClientSettings, OAuthSettings from mcp_agent.logging.logger import get_logger from mcp_agent.oauth.errors import ( - MissingUserIdentityError, OAuthFlowError, TokenRefreshError, ) diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index 6205933b6..dd4027e93 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -39,9 +39,11 @@ from mcp_agent.mcp.mcp_server_registry import ServerRegistry from mcp_agent.oauth.identity import OAuthUserIdentity from mcp_agent.oauth.callbacks import callback_registry +from mcp_agent.oauth.errors import ( + CallbackTimeoutError, +) from mcp_agent.oauth.manager import create_default_user_for_preconfigured_tokens from mcp_agent.server.token_verifier import MCPAgentTokenVerifier - if TYPE_CHECKING: from mcp_agent.core.context import Context @@ -722,12 +724,15 @@ async def _handle_specific_request( elif method == "auth/request": # TODO: special handling of auth request, should be replaced by future URL elicitation class AuthToken(BaseModel): - token: str = Field(description="The access token") + confirmation: str = Field(description="Please press enter to confirm this message has been received") + + flow_id = params["flow_id"] + callback_future = await callback_registry.create_handle(flow_id) req = ElicitRequest( method="elicitation/create", params=ElicitRequestParams( - message=params["message"] + "\n\n" + params["url"] , + message=params["message"] + "\n\n" + params["url"], requestedSchema=AuthToken.model_json_schema(), ), ) @@ -736,7 +741,17 @@ class AuthToken(BaseModel): request=req, result_type=ElicitResult ) # type: ignore[attr-defined] - return result.model_dump(by_alias=True, mode="json", exclude_none=True) + timeout = 300 + try: + callback_data = await asyncio.wait_for( + callback_future, timeout=timeout + ) + except asyncio.TimeoutError as exc: + raise CallbackTimeoutError( + f"Timed out waiting for OAuth callback after {timeout} seconds" + ) from exc + + return callback_data else: raise ValueError(f"unsupported method: {method}") From fc4a27c9a8fecae6e4778501c9cb3550b067c5c8 Mon Sep 17 00:00:00 2001 From: Roman van der Krogt Date: Tue, 30 Sep 2025 16:52:00 +0100 Subject: [PATCH 10/25] improve how we're dealing with no oauth user --- examples/oauth/preconfigured/oauth_demo.py | 6 ++-- examples/oauth/workflow_pre_auth/client.py | 29 ++++++++++++-------- examples/oauth/workflow_pre_auth/main.py | 4 +-- src/mcp_agent/oauth/manager.py | 32 ++++++++++++---------- src/mcp_agent/server/app_server.py | 27 ++++++------------ 5 files changed, 48 insertions(+), 50 deletions(-) diff --git a/examples/oauth/preconfigured/oauth_demo.py b/examples/oauth/preconfigured/oauth_demo.py index 4a4c47c58..913d6622b 100644 --- a/examples/oauth/preconfigured/oauth_demo.py +++ b/examples/oauth/preconfigured/oauth_demo.py @@ -40,7 +40,7 @@ def __init__(self, client_id: str, client_secret: str, redirect_uri: str = None) """ self.client_id = client_id self.client_secret = client_secret - self.redirect_uri = redirect_uri or "http://localhost:8080/oauth/callback" + self.redirect_uri = redirect_uri or "http://localhost:8080/internal/oauth/callback" self.state = secrets.token_urlsafe(32) # CSRF protection self.access_token: Optional[str] = None self.refresh_token: Optional[str] = None @@ -240,7 +240,7 @@ async def handle_callback(request): # Start local server app = web.Application() - app.router.add_get('/oauth/callback', handle_callback) + app.router.add_get('/internal/oauth/callback', handle_callback) runner = web.AppRunner(app) await runner.setup() @@ -311,7 +311,7 @@ async def main(): print("\nTo use this demo, you need to set up a GitHub OAuth App:") print("1. Go to GitHub Settings > Developer settings > OAuth Apps") print("2. Click 'New OAuth App'") - print("3. Set Authorization callback URL to: http://localhost:8080/oauth/callback") + print("3. Set Authorization callback URL to: http://localhost:8080/internal/oauth/callback") print("4. Set environment variables:") print(" export GITHUB_CLIENT_ID='your_client_id'") print(" export GITHUB_CLIENT_SECRET='your_client_secret'") diff --git a/examples/oauth/workflow_pre_auth/client.py b/examples/oauth/workflow_pre_auth/client.py index 873fdb364..cc8fd23bd 100644 --- a/examples/oauth/workflow_pre_auth/client.py +++ b/examples/oauth/workflow_pre_auth/client.py @@ -1,6 +1,7 @@ import asyncio import time import os +import sys from datetime import timedelta from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream @@ -61,8 +62,10 @@ async def main(): context.server_registry.registry["basic_agent_server"] = MCPServerSettings( name="basic_agent_server", description="Local workflow server running the basic agent example", - command="uv", - args=["run", "main.py"], + transport="sse", + url="http://127.0.0.1:8000/sse", + # command="uv", + # args=["run", "main.py"], ) # Define a logging callback to receive server-side log notifications @@ -123,16 +126,18 @@ def make_session( data={"tools": [tool.name for tool in tools_result.tools]}, ) - await server.call_tool("workflows-pre-auth", - arguments={ - "workflow_name": "github_org_search", - "tokens": [ - { - "access_token": access_token, - "server_name": "github", - } - ] - }) + if len(sys.argv) < 2 or sys.argv[1] != "--skip-pre-auth": + print("Performing pre-auth") + await server.call_tool("workflows-pre-auth", + arguments={ + "workflow_name": "github_org_search", + "tokens": [ + { + "access_token": access_token, + "server_name": "github", + } + ] + }) print(await server.call_tool("github_org_search", {"query": "lastmileai"})) except Exception as e: diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py index 18634378e..415803ba0 100644 --- a/examples/oauth/workflow_pre_auth/main.py +++ b/examples/oauth/workflow_pre_auth/main.py @@ -124,8 +124,8 @@ async def main(): agent_app.logger.info(f"MCP Server settings: {mcp_server.settings}") # Run the server - await mcp_server.run_stdio_async() - # await mcp_server.run_sse_async() + #await mcp_server.run_stdio_async() + await mcp_server.run_sse_async() if __name__ == "__main__": diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index 36e3577ea..7dbcb12eb 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -38,13 +38,13 @@ logger = get_logger(__name__) -def create_default_user_for_preconfigured_tokens() -> "OAuthUserIdentity": +def create_default_user_for_preconfigured_tokens(session_id: str | None = None) -> "OAuthUserIdentity": """Create a synthetic user identity for pre-configured tokens.""" from mcp_agent.oauth.identity import OAuthUserIdentity return OAuthUserIdentity( provider="mcp-agent", - subject="preconfigured-tokens", + subject=f"preconfigured-tokens-{session_id}" if session_id else "preconfigured-tokens", claims={"token_source": "preconfigured", "description": "Synthetic user for pre-configured OAuth tokens"} ) @@ -125,22 +125,28 @@ async def ensure_access_token( ) user = context.current_user - if not user: - # TODO: with a proper oauth flow, we should always have a user in the context; since we don't have a server - # yet, mock a user if necessary. In the future, should be replaced by: something like: - # raise MissingUserIdentityError("No authenticated MCP user available for OAuth flow (neither - # interactive nor pre-configured)") - - # Create synthetic user if none exists - user = create_default_user_for_preconfigured_tokens() - context.current_user = user - logger.info(f"Created synthetic user for token access: {user.cache_key}") # Use the same key construction logic as store_preconfigured_token to ensure consistency resource_str = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server else None scope_list = list(scopes) if scopes is not None else list(oauth_config.scopes or []) + # check for a globally configure token + key = TokenStoreKey( + user_key=create_default_user_for_preconfigured_tokens().cache_key, + resource=resource_str, + authorization_server=auth_server_str, + scope_fingerprint=scope_fingerprint(scope_list) + ) + + lock = self._locks[key] + + async with lock: + record = await self._token_store.get(key) + if record: + return record + + # there is no global token, look for a user specific one key = TokenStoreKey( user_key=user.cache_key, resource=resource_str, @@ -148,11 +154,9 @@ async def ensure_access_token( scope_fingerprint=scope_fingerprint(scope_list) ) - logger.debug(f"Looking for token with key: user_key={key.user_key}, resource={key.resource}, auth_server={key.authorization_server}, scope_fingerprint={key.scope_fingerprint}") lock = self._locks[key] async with lock: record = await self._token_store.get(key) - logger.debug(f"Found existing record: {record is not None}") leeway = ( self._settings.token_store.refresh_leeway_seconds if self._settings and self._settings.token_store diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index dd4027e93..9cede9d45 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -217,6 +217,14 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: except Exception: identity = None + if not identity: + # Try create identity from session id + try: + session_id = ctx.request_context.request.query_params.get("session_id") + identity = create_default_user_for_preconfigured_tokens(session_id) + except Exception: + identity = None + if session is not None: app: MCPApp | None = _get_attached_app(ctx.fastmcp) if app is not None and getattr(app, "context", None) is not None: @@ -1614,16 +1622,6 @@ async def workflow_pre_auth( ) continue - # Ensure we have a user context for token storage - # TODO: This is a temporary workaround until we have proper oauth service, so that we have a user - # in the context from the oauth token - if not app_context.current_user: - # Create synthetic user if none exists - synthetic_user = create_default_user_for_preconfigured_tokens() - app_context.current_user = synthetic_user - logger.info(f"Created synthetic user for workflow pre-auth: {synthetic_user.cache_key}") - logger.info(f"{id(app_context)}: {app_context}") - # Create TokenRecord from mcp_agent.oauth.records import TokenRecord from mcp_agent.oauth.store.base import ( @@ -1648,7 +1646,6 @@ async def workflow_pre_auth( metadata={"workflow_name": workflow_name}, ) - str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) # Create storage key using current user store_key = TokenStoreKey( @@ -1658,17 +1655,9 @@ async def workflow_pre_auth( scope_fingerprint=scope_fingerprint(scope_list), ) - logger.debug( - f"Storing token with key: user_key={store_key.user_key}, resource={store_key.resource}, auth_server={store_key.authorization_server}, scope_fingerprint={store_key.scope_fingerprint}") - # Store the token await app_context.token_store.set(store_key, token_record) stored_count += 1 - - logger.info( - f"Stored OAuth token for workflow '{workflow_name}' and server '{server_name}'" - ) - except Exception as e: errors.append(f"Token {i}: {str(e)}") logger.error( From 3aafad600e3eb3eb41ae0b469b5176ea562396cd Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 7 Oct 2025 20:36:51 -0400 Subject: [PATCH 11/25] all tests passing --- docs/configuration.mdx | 5 +- docs/oauth_support_design.md | 7 +- examples/oauth/README.md | 26 +- examples/oauth/dynamic_auth/client.py | 163 - examples/oauth/dynamic_auth/main.py | 165 - examples/oauth/dynamic_auth/worker.py | 31 - examples/oauth/interactive_tool/README.md | 45 + examples/oauth/interactive_tool/client.py | 97 + examples/oauth/interactive_tool/server.py | 131 + examples/oauth/preconfigured/README.md | 402 -- examples/oauth/preconfigured/main.py | 186 - .../oauth/preconfigured/mcp_agent.config.yaml | 115 - .../mcp_agent.secrets.yaml.example | 41 - examples/oauth/preconfigured/oauth_demo.py | 384 -- examples/oauth/preconfigured/requirements.txt | 37 - .../oauth/preconfigured/workflow_example.py | 426 -- examples/oauth/workflow_pre_auth/README.md | 51 + examples/oauth/workflow_pre_auth/client.py | 36 +- examples/oauth/workflow_pre_auth/main.py | 115 +- pyproject.toml | 3 + src/mcp_agent/app.py | 68 +- src/mcp_agent/core/context.py | 3 +- src/mcp_agent/executor/workflow.py | 1 + src/mcp_agent/oauth/flow.py | 33 +- src/mcp_agent/oauth/http/auth.py | 10 +- src/mcp_agent/oauth/identity.py | 5 + src/mcp_agent/oauth/manager.py | 612 +- src/mcp_agent/oauth/metadata.py | 26 +- src/mcp_agent/oauth/store/__init__.py | 7 + src/mcp_agent/oauth/store/redis.py | 65 + src/mcp_agent/server/app_server.py | 105 +- tests/test_app_session.py | 13 + tests/test_audience_validation.py | 16 +- tests/test_oauth_utils.py | 4 + tests/test_token_manager.py | 161 + uv.lock | 5049 +++++++++-------- 36 files changed, 3867 insertions(+), 4777 deletions(-) delete mode 100644 examples/oauth/dynamic_auth/client.py delete mode 100644 examples/oauth/dynamic_auth/main.py delete mode 100644 examples/oauth/dynamic_auth/worker.py create mode 100644 examples/oauth/interactive_tool/README.md create mode 100644 examples/oauth/interactive_tool/client.py create mode 100644 examples/oauth/interactive_tool/server.py delete mode 100644 examples/oauth/preconfigured/README.md delete mode 100644 examples/oauth/preconfigured/main.py delete mode 100644 examples/oauth/preconfigured/mcp_agent.config.yaml delete mode 100644 examples/oauth/preconfigured/mcp_agent.secrets.yaml.example delete mode 100644 examples/oauth/preconfigured/oauth_demo.py delete mode 100644 examples/oauth/preconfigured/requirements.txt delete mode 100644 examples/oauth/preconfigured/workflow_example.py create mode 100644 examples/oauth/workflow_pre_auth/README.md create mode 100644 src/mcp_agent/oauth/store/redis.py create mode 100644 tests/test_app_session.py create mode 100644 tests/test_token_manager.py diff --git a/docs/configuration.mdx b/docs/configuration.mdx index b3eacf702..11a9eb44b 100644 --- a/docs/configuration.mdx +++ b/docs/configuration.mdx @@ -144,8 +144,10 @@ oauth: callback_base_url: https://agent.example.com flow_timeout_seconds: 180 token_store: - backend: memory # use "redis" for multi-instance deployments + backend: memory # set to "redis" for multi-instance deployments refresh_leeway_seconds: 90 + redis_url: redis://localhost:6379 + redis_prefix: mcp_agent:oauth_tokens mcp: servers: @@ -164,6 +166,7 @@ mcp: - When `authorization.enabled` is true the MCP server advertises `/.well-known/oauth-protected-resource` and enforces bearer tokens using the provided introspection or JWKS configuration. - `oauth` enables delegated authorization flows; the default in-memory token store is ideal for local development while Redis is recommended for production clusters. +- To use Redis for token storage, configure `token_store.backend: redis` and supply `redis_url` (see optional dependency `mcp-agent[redis]`). - Downstream servers opt into OAuth via `mcp.servers..auth.oauth`. Supplying a `client_id`/`client_secret` allows immediate usage; support for dynamic client registration is planned as a follow-up. ## Configuration Reference diff --git a/docs/oauth_support_design.md b/docs/oauth_support_design.md index 5aea9b1f2..faeccce87 100644 --- a/docs/oauth_support_design.md +++ b/docs/oauth_support_design.md @@ -13,8 +13,8 @@ 2. **Protected Resource Metadata** – Serve `/.well-known/oauth-protected-resource` using FastMCP hooks so clients can discover the auth server. 3. **Access Token Validation** – Enforce bearer tokens on every inbound MCP request via `RequireAuthMiddleware`, populating the request context with the authenticated user. 4. **OAuth Token Service** – New `mcp_agent.oauth` package with: - - `TokenStore`/`TokenRecord` abstractions - - `InMemoryTokenStore` and Redis-backed implementation (second pass) + - `TokenStore`/`TokenRecord` abstractions + - `InMemoryTokenStore` and Redis-backed implementation (optional for multi-instance) - `TokenManager` orchestration (acquire, refresh, revoke) - `OAuthHttpxAuth` for attaching tokens to downstream HTTP transports - `AuthorizationFlowCoordinator` that interacts with the user via MCP `auth/request` @@ -95,7 +95,7 @@ Integration touchpoints: - Provide method to revoke tokens via authorization server when supported. ## Open Questions / Follow-ups -- Redis-backed `TokenStore` (requires deployment secrets) – planned second phase. +- Additional operational hardening (token rotation policies, rate limits). - How LastMile auth server exposes token introspection + JWKS; need concrete endpoint specs to finalize `MCPAgentTokenVerifier`. - MCP client adoption of `auth/request` SEP – need capability detection; until widely supported we rely on hosted callback fallback & manual instructions. - Access control DSL (include/exclude by email/domain) – to be evaluated once token identity payload finalized. @@ -105,4 +105,3 @@ Integration touchpoints: - Metadata discovery + PKCE generation (pure python tests). - Integration-style test for delegated flow using mocked HTTP server + fake MCP client (ensures `auth/request` plumbing works end-to-end). - Tests around server 401 enforcement + WWW-Authenticate header. - diff --git a/examples/oauth/README.md b/examples/oauth/README.md index dd966ba1f..5b66b1caa 100644 --- a/examples/oauth/README.md +++ b/examples/oauth/README.md @@ -1,19 +1,17 @@ -# OAUTH scenarios +# OAuth Examples -## preconfigured +Two complementary scenarios demonstrate how OAuth integrates with MCP: -In this case, a token is hard-coded into the configuration. -This is useful for testing or when the token is static. +## interactive_tool -## workflow_pre_auth - -In this case, the client can call a `workflows_pre_auth` tool before calling a workflow to seed the tokens. -This is useful when the client can do the auth step, but the workflow cannot (e.g. because it runs async). -There is a slight hack employed here: since we don't have oauth for the mcp app, we do not have a user. -Since we need a user to store the token against, we create a synthetic user and use that. +Shows the full authorization code flow for a synchronous tool. When the +client calls the tool, the server sends an `auth/request` message and the +client walks the user through the browser-based login. Subsequent tool calls +reuse the stored token. -## dynamic_auth +## workflow_pre_auth -In this case, no tokens are provided, and the calls comes back to the client to do the auth step. -Currently implemented as an elicitation request (to align with the future elicit URL scheme). -I have not achieved full end-to-end flow here. \ No newline at end of file +Demonstrates seeding tokens via the `workflows-pre-auth` tool before running +an asynchronous workflow. This is useful when workflows execute in the +background (e.g., Temporal) and cannot perform interactive authentication on +their own. diff --git a/examples/oauth/dynamic_auth/client.py b/examples/oauth/dynamic_auth/client.py deleted file mode 100644 index 4e7b67c3a..000000000 --- a/examples/oauth/dynamic_auth/client.py +++ /dev/null @@ -1,163 +0,0 @@ -import asyncio -import time - -from datetime import timedelta -from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream -from mcp import ClientSession -from mcp.types import CallToolResult, LoggingMessageNotificationParams -from mcp_agent.app import MCPApp -from mcp_agent.config import MCPServerSettings -from mcp_agent.core.context import Context -from mcp_agent.mcp.gen_client import gen_client -from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession -from mcp_agent.human_input.console_handler import console_input_callback -from mcp_agent.elicitation.handler import console_elicitation_callback - -from rich import print - -try: - from exceptiongroup import ExceptionGroup as _ExceptionGroup # Python 3.10 backport -except Exception: # pragma: no cover - _ExceptionGroup = None # type: ignore -try: - from anyio import BrokenResourceError as _BrokenResourceError -except Exception: # pragma: no cover - _BrokenResourceError = None # type: ignore - -async def main(): - # Create MCPApp to get the server registry - app = MCPApp( - name="workflow_mcp_client", - human_input_callback=console_input_callback, - elicitation_callback=console_elicitation_callback, - ) - async with app.run() as client_app: - logger = client_app.logger - context = client_app.context - - # Connect to the workflow server - logger.info("Connecting to workflow server...") - - # Override the server configuration to point to our local script - context.server_registry.registry["basic_agent_server"] = MCPServerSettings( - name="basic_agent_server", - description="Local workflow server running the basic agent example", - transport="sse", - url="http://127.0.0.1:8000/sse", - ) - - # Define a logging callback to receive server-side log notifications - async def on_server_log(params: LoggingMessageNotificationParams) -> None: - level = params.level.upper() - name = params.logger or "server" - print(f"[SERVER LOG] [{level}] [{name}] {params.data}") - - # Provide a client session factory that installs our logging callback - # and prints non-logging notifications to the console - class ConsolePrintingClientSession(MCPAgentClientSession): - async def _received_notification(self, notification): # type: ignore[override] - try: - method = getattr(notification.root, "method", None) - except Exception: - method = None - - # Avoid duplicating server log prints (handled by logging_callback) - if method and method != "notifications/message": - try: - data = notification.model_dump() - except Exception: - data = str(notification) - print(f"[SERVER NOTIFY] {method}: {data}") - - return await super()._received_notification(notification) - - def make_session( - read_stream: MemoryObjectReceiveStream, - write_stream: MemoryObjectSendStream, - read_timeout_seconds: timedelta | None, - context: Context | None = None, - ) -> ClientSession: - return ConsolePrintingClientSession( - read_stream=read_stream, - write_stream=write_stream, - read_timeout_seconds=read_timeout_seconds, - logging_callback=on_server_log, - context=context, - ) - - try: - async with gen_client( - "basic_agent_server", - context.server_registry, - client_session_factory=make_session, - ) as server: - try: - await server.set_logging_level("info") - except Exception: - # Older servers may not support logging capability - print("[client] Server does not support logging/setLevel") - - # List available tools - tools_result = await server.list_tools() - logger.info( - "Available tools:", - data={"tools": [tool.name for tool in tools_result.tools]}, - ) - - print(await server.call_tool("github_org_search", {"query": "lastmileai"})) - except Exception as e: - # Tolerate benign shutdown races from stdio client (BrokenResourceError within ExceptionGroup) - if _ExceptionGroup is not None and isinstance(e, _ExceptionGroup): - subs = getattr(e, "exceptions", []) or [] - if ( - _BrokenResourceError is not None - and subs - and all(isinstance(se, _BrokenResourceError) for se in subs) - ): - logger.debug("Ignored BrokenResourceError from stdio shutdown") - else: - raise - elif _BrokenResourceError is not None and isinstance( - e, _BrokenResourceError - ): - logger.debug("Ignored BrokenResourceError from stdio shutdown") - elif "BrokenResourceError" in str(e): - logger.debug( - "Ignored BrokenResourceError from stdio shutdown (string match)" - ) - else: - raise - # Nudge cleanup of subprocess transports before the loop closes to avoid - # 'Event loop is closed' from BaseSubprocessTransport.__del__ on GC. - try: - await asyncio.sleep(0) - except Exception: - pass - try: - import gc - - gc.collect() - except Exception: - pass - - -def _tool_result_to_json(tool_result: CallToolResult): - if tool_result.content and len(tool_result.content) > 0: - text = tool_result.content[0].text - try: - # Try to parse the response as JSON if it's a string - import json - - return json.loads(text) - except (json.JSONDecodeError, TypeError): - # If it's not valid JSON, just use the text - return None - - -if __name__ == "__main__": - start = time.time() - asyncio.run(main()) - end = time.time() - t = end - start - - print(f"Total run time: {t:.2f}s") diff --git a/examples/oauth/dynamic_auth/main.py b/examples/oauth/dynamic_auth/main.py deleted file mode 100644 index 3eb54728c..000000000 --- a/examples/oauth/dynamic_auth/main.py +++ /dev/null @@ -1,165 +0,0 @@ -""" -Workflow MCP Server Example - -This example demonstrates three approaches to creating agents and workflows: -1. Traditional workflow-based approach with manual agent creation -2. Programmatic agent configuration using AgentConfig -3. Declarative agent configuration using FastMCPApp decorators -""" - -import asyncio -import json -import os -from pydantic import AnyHttpUrl - -from mcp.server.fastmcp import FastMCP - -from mcp_agent.app import MCPApp -from mcp_agent.server.app_server import create_mcp_server_for_app - -from mcp_agent.config import MCPServerSettings, Settings, LoggerSettings, MCPSettings, MCPServerAuthSettings, \ - MCPOAuthClientSettings, OAuthSettings, OAuthTokenStoreSettings, TemporalSettings - -# Note: This is purely optional: -# if not provided, a default FastMCP server will be created by MCPApp using create_mcp_server_for_app() -mcp = FastMCP(name="basic_agent_server", instructions="My basic agent server example.") - - -# Get client id and secret from environment variables -client_id = os.getenv('GITHUB_CLIENT_ID') -client_secret = os.getenv('GITHUB_CLIENT_SECRET') - -if not client_id or not client_secret: - print("\nGitHub client id and/or secret not found in GITHUB_CLIENT_Id and GITHUB_CLIENT_SECRET " - "environment variables.") - print("\nTo create these:") - print("\n1. Open your profile on github.com and navigate to 'Developer Settings'") - print("\n2. Create a new OAuth app and create a client secret for it.") - print("\n3. Create environment variables:") - print("\nexport GITHUB_CLIENT_ID='your_client_id_here'") - print("\nexport GITHUB_CLIENT_SECRET='your_client_secret_here'") - - -settings = Settings( - execution_engine="temporal", - temporal=TemporalSettings( - host="localhost:7233", - namespace="default", - task_queue="mcp-agent", - max_concurrent_activities=10, - ), - logger=LoggerSettings(level="info"), - oauth=OAuthSettings( - callback_base_url=AnyHttpUrl("http://localhost:8000"), - flow_timeout_seconds=300, - token_store=OAuthTokenStoreSettings(refresh_leeway_seconds=60), - ), - mcp=MCPSettings( - servers={ - "github": MCPServerSettings( - name="github", - transport="streamable_http", - url="https://api.githubcopilot.com/mcp/", - auth=MCPServerAuthSettings( - oauth=MCPOAuthClientSettings( - client_id=client_id, - client_secret=client_secret, - use_internal_callback=True, - enabled=True, - scopes= [ - "read:org", # Required for search_orgs tool - "public_repo", # Access to public repositories - "user:email" # User information access - ], - authorization_server=AnyHttpUrl("https://github.com/login/oauth"), - resource=AnyHttpUrl("https://api.githubcopilot.com/mcp") - ) - ) - ) - } - ), - ) - -# Define the MCPApp instance. The server created for this app will advertise the -# MCP logging capability and forward structured logs upstream to connected clients. -app = MCPApp( - name="basic_agent_server", - description="Basic agent server example", - mcp=mcp, - settings=settings, -) - - -@app.workflow_task(name="github_org_search_activity") -async def github_org_search_activity(query: str) -> str: - from mcp_agent.mcp.gen_client import gen_client - - print("running activity)") - try: - async with gen_client( - "github", - server_registry=app.context.server_registry, - context=app.context - ) as github_client: - print("got client") - result = await github_client.call_tool( - "search_orgs", - { - "query": query, - "perPage": 10, - "sort": "best-match", - "order": "desc" - } - ) - - organizations = [] - if result.content: - for content_item in result.content: - if hasattr(content_item, 'text'): - try: - data = json.loads(content_item.text) - if isinstance(data, dict) and 'items' in data: - organizations.extend(data['items']) - elif isinstance(data, list): - organizations.extend(data) - except json.JSONDecodeError: - pass - - print(f"Organizations: {organizations}") - return str(organizations) - except Exception as e: - import traceback - traceback.print_exc() - return f"Error: {e}" - -@app.tool(name="github_org_search") -async def github_org_search(query: str) -> str: - if app._logger and hasattr(app._logger, "_bound_context"): - app._logger._bound_context = app.context - - result = await app.executor.execute(github_org_search_activity, query) - print(f"Result: {result}") - - return result - - -async def main(): - async with app.run() as agent_app: - # Log registered workflows and agent configurations - agent_app.logger.info(f"Creating MCP server for {agent_app.name}") - - agent_app.logger.info("Registered workflows:") - for workflow_id in agent_app.workflows: - agent_app.logger.info(f" - {workflow_id}") - - # Create the MCP server that exposes both workflows and agent configurations, - # optionally using custom FastMCP settings - mcp_server = create_mcp_server_for_app(agent_app) - agent_app.logger.info(f"MCP Server settings: {mcp_server.settings}") - - # Run the server - await mcp_server.run_sse_async() - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/oauth/dynamic_auth/worker.py b/examples/oauth/dynamic_auth/worker.py deleted file mode 100644 index 39b2a3c67..000000000 --- a/examples/oauth/dynamic_auth/worker.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -Worker script for the Temporal workflow example. -This script starts a Temporal worker that can execute workflows and activities. -Run this script in a separate terminal window before running the main.py script. - -This leverages the TemporalExecutor's start_worker method to handle the worker setup. -""" - -import asyncio -import logging - - -from mcp_agent.executor.temporal import create_temporal_worker_for_app - -from main import app - -# Initialize logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -async def main(): - """ - Start a Temporal worker for the example workflows using the app's executor. - """ - async with create_temporal_worker_for_app(app) as worker: - await worker.run() - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/oauth/interactive_tool/README.md b/examples/oauth/interactive_tool/README.md new file mode 100644 index 000000000..dd42ef07b --- /dev/null +++ b/examples/oauth/interactive_tool/README.md @@ -0,0 +1,45 @@ +# OAuth Interactive Tool Example + +This example shows the end-to-end OAuth **authorization code** flow for a +simple synchronous MCP tool. The MCP server exposes a `github_org_search` +tool that calls the GitHub MCP server. When the tool is invoked without a +cached token, the server issues an `auth/request` message and the client opens +the browser so you can complete the GitHub sign-in. + +## Prerequisites + +1. Create a GitHub OAuth App (Settings → Developer settings → OAuth Apps) + with callback URL `http://localhost:8000/internal/oauth/callback`. +2. Export the client credentials: + + ```bash + export GITHUB_CLIENT_ID="your_client_id" + export GITHUB_CLIENT_SECRET="your_client_secret" + ``` + +3. Install dependencies (from the repository root): + + ```bash + pip install -e . + ``` + +## Running + +Start the MCP server in one terminal: + +```bash +python examples/oauth/interactive_tool/server.py +``` + +In another terminal, run the client: + +```bash +python examples/oauth/interactive_tool/client.py +``` + +The client will display an authorization prompt. Approve it in the browser +and GitHub will redirect back to the local callback handler. Once completed, +the tool result is printed in the client terminal. + +Subsequent tool invocations reuse the stored token until it expires or is +revoked. diff --git a/examples/oauth/interactive_tool/client.py b/examples/oauth/interactive_tool/client.py new file mode 100644 index 000000000..6b8713313 --- /dev/null +++ b/examples/oauth/interactive_tool/client.py @@ -0,0 +1,97 @@ +""" +Minimal client for the OAuth interactive demo. It connects to the MCP server, +invokes the GitHub organization search tool, and responds to auth/request +messages by opening the browser and completing the OAuth flow. +""" + +from __future__ import annotations + +import asyncio +from datetime import timedelta + +from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream +from rich import print + +from mcp import ClientSession +from mcp.types import LoggingMessageNotificationParams + +from mcp_agent.app import MCPApp +from mcp_agent.config import MCPServerSettings +from mcp_agent.core.context import Context +from mcp_agent.elicitation.handler import console_elicitation_callback +from mcp_agent.human_input.console_handler import console_input_callback +from mcp_agent.mcp.gen_client import gen_client +from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession + + +class LoggingClientSession(MCPAgentClientSession): + async def _received_notification(self, notification): # type: ignore[override] + method = getattr(notification.root, "method", None) + if method and method != "notifications/message": + try: + payload = notification.model_dump() + except Exception: + payload = str(notification) + print(f"[SERVER NOTIFY] {method}: {payload}") + return await super()._received_notification(notification) + + +async def make_session( + read_stream: MemoryObjectReceiveStream, + write_stream: MemoryObjectSendStream, + read_timeout_seconds: timedelta | None, + context: Context | None = None, +) -> ClientSession: + async def on_server_log(params: LoggingMessageNotificationParams) -> None: + level = params.level.upper() + logger_name = params.logger or "server" + print(f"[SERVER LOG] [{level}] [{logger_name}] {params.data}") + + return LoggingClientSession( + read_stream=read_stream, + write_stream=write_stream, + read_timeout_seconds=read_timeout_seconds, + logging_callback=on_server_log, + context=context, + ) + + +async def main() -> None: + app = MCPApp( + name="github_oauth_client", + human_input_callback=console_input_callback, + elicitation_callback=console_elicitation_callback, + ) + + async with app.run() as client_app: + registry = client_app.context.server_registry + registry.registry["github_demo"] = MCPServerSettings( + name="github_demo", + description="Local GitHub OAuth demo server", + transport="sse", + url="http://127.0.0.1:8000/sse", + ) + + async with gen_client( + "github_demo", + registry, + client_session_factory=make_session, + context=client_app.context, + ) as connection: + try: + await connection.set_logging_level("info") + except Exception: + print("[client] Server does not support logging/setLevel") + + print("[client] Invoking github_org_search...") + result = await connection.call_tool( + "github_org_search", + {"query": "lastmileai"}, + ) + print("[client] Result:") + for item in result.content or []: + print(item) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/oauth/interactive_tool/server.py b/examples/oauth/interactive_tool/server.py new file mode 100644 index 000000000..ede6075fd --- /dev/null +++ b/examples/oauth/interactive_tool/server.py @@ -0,0 +1,131 @@ +""" +Simple MCP server that exposes a GitHub search tool and relies on the OAuth +authorization flow. When the tool is invoked without stored credentials, the +server will issue an auth/request so the client can complete the OAuth login +in a browser and return the authorization code. +""" + +from __future__ import annotations + +import asyncio +import json +import os +from typing import Optional + +from pydantic import AnyHttpUrl + +from mcp.server.fastmcp import FastMCP + +from mcp_agent.app import MCPApp +from mcp_agent.config import ( + LoggerSettings, + MCPOAuthClientSettings, + MCPServerAuthSettings, + MCPServerSettings, + MCPSettings, + OAuthSettings, + Settings, +) +from mcp_agent.core.context import Context as AppContext +from mcp_agent.mcp.gen_client import gen_client +from mcp_agent.server.app_server import create_mcp_server_for_app + +CLIENT_ID = os.getenv("GITHUB_CLIENT_ID") +CLIENT_SECRET = os.getenv("GITHUB_CLIENT_SECRET") + +if not CLIENT_ID or not CLIENT_SECRET: + raise SystemExit( + "Set GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET environment variables " + "with credentials for a GitHub OAuth App before running this example." + ) + +# Optional FastMCP instance (MCPApp can construct one automatically, +# but providing it makes the instructions clearer). +mcp = FastMCP( + name="github_demo", + instructions="Demo GitHub search tool that requires OAuth authentication.", +) + +settings = Settings( + execution_engine="asyncio", + logger=LoggerSettings(level="info"), + oauth=OAuthSettings( + callback_base_url=AnyHttpUrl("http://localhost:8000"), + flow_timeout_seconds=300, + ), + mcp=MCPSettings( + servers={ + "github": MCPServerSettings( + name="github", + transport="streamable_http", + url="https://api.githubcopilot.com/mcp/", + auth=MCPServerAuthSettings( + oauth=MCPOAuthClientSettings( + enabled=True, + client_id=CLIENT_ID, + client_secret=CLIENT_SECRET, + scopes=[ + "read:org", + "public_repo", + "user:email", + ], + authorization_server=AnyHttpUrl( + "https://github.com/login/oauth" + ), + resource=AnyHttpUrl("https://api.githubcopilot.com/mcp"), + use_internal_callback=True, + ) + ), + ) + } + ), +) + +app = MCPApp( + name="github_oauth_demo", + description="Example MCP server that performs GitHub organization searches.", + mcp=mcp, + settings=settings, +) + + +@app.tool(name="github_org_search") +async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: + """Search GitHub organizations using the remote MCP server.""" + context = app_ctx or app.context + async with gen_client( + "github", + server_registry=context.server_registry, + context=context, + ) as github_client: + result = await github_client.call_tool( + "search_orgs", + {"query": query, "perPage": 5, "sort": "best-match", "order": "desc"}, + ) + + orgs: list[dict] = [] + if result.content: + for item in result.content: + text = getattr(item, "text", None) + if not text: + continue + try: + payload = json.loads(text) + except json.JSONDecodeError: + continue + if isinstance(payload, dict) and "items" in payload: + orgs.extend(payload["items"]) + elif isinstance(payload, list): + orgs.extend(payload) + return json.dumps(orgs, indent=2) + + +async def main() -> None: + async with app.run() as running_app: + running_app.logger.info("Starting GitHub OAuth demo server") + server = create_mcp_server_for_app(running_app) + await server.run_sse_async() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/oauth/preconfigured/README.md b/examples/oauth/preconfigured/README.md deleted file mode 100644 index 846eded46..000000000 --- a/examples/oauth/preconfigured/README.md +++ /dev/null @@ -1,402 +0,0 @@ -# OAuth MCP Agent Example - -This example demonstrates how to build MCP agents that use OAuth authentication to access OAuth-protected MCP servers, specifically showing integration with the GitHub MCP server. - -## 📋 Overview - -This example includes: - -- **Basic OAuth Integration** - Connect to OAuth-protected MCP servers -- **GitHub Organization Search** - Use the `search_orgs` tool from GitHub MCP server -- **Workflow Pre-Authorization** - Demonstrate the new `workflow_pre_auth` endpoint -- **Interactive OAuth Flow** - Complete OAuth setup and token management -- **Production-Ready Configuration** - Comprehensive config with security best practices - -## 🚀 Quick Start - -### 1. Prerequisites - -```bash -# Install Python dependencies -pip install -r requirements.txt - -# Install GitHub MCP server -uvx install github-mcp-server - -# Optional: Install additional MCP servers -npm install -g @modelcontextprotocol/server-filesystem -uvx install mcp-server-fetch -``` - -### 2. Set Up GitHub OAuth App - -1. Go to [GitHub Settings → Developer settings → OAuth Apps](https://github.com/settings/applications/new) -2. Click **"New OAuth App"** -3. Fill in the details: - - **Application name**: `MCP Agent OAuth Example` - - **Homepage URL**: `https://github.com/yourusername/your-repo` - - **Authorization callback URL**: `http://localhost:8080/oauth/callback` -4. Click **"Register application"** -5. Copy the **Client ID** and generate a **Client Secret** - -### 3. Configure Secrets - -```bash -# Copy the secrets template -cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml - -# Edit with your credentials -nano mcp_agent.secrets.yaml -``` - -Add your GitHub OAuth app credentials: - -```yaml -mcp: - servers: - github: - auth: - oauth: - client_id: "your_github_oauth_app_client_id_here" - client_secret: "your_github_oauth_app_client_secret_here" - access_token: "your_github_access_token_here" # Optional: skip OAuth flow -``` - -### 4. Run the Examples - -#### Basic OAuth Example -```bash -python main.py -``` - -#### Interactive OAuth Setup -```bash -python oauth_demo.py -``` - -#### Workflow with Pre-Authorization -```bash -python workflow_example.py -``` - -## 📁 File Structure - -``` -examples/oauth/ -├── README.md # This file -├── main.py # Basic OAuth MCP agent -├── workflow_example.py # Workflow with pre-auth demo -├── oauth_demo.py # Interactive OAuth flow -├── mcp_agent.config.yaml # Agent configuration -├── mcp_agent.secrets.yaml.example # Secrets template -└── requirements.txt # Python dependencies -``` - -## 🔐 Authentication Methods - -### Method 1: OAuth Flow (Recommended) - -Full OAuth 2.0 flow with refresh tokens: - -1. **Run Interactive Setup**: - ```bash - GITHUB_CLIENT_ID=your_id GITHUB_CLIENT_SECRET=your_secret python oauth_demo.py - ``` - -2. **Follow Browser Flow**: Authorize the application in your browser - -3. **Token Storage**: Tokens are automatically stored for reuse - -### Method 2: Personal Access Token (Development) - -For development and testing, you can use a GitHub Personal Access Token: - -1. Go to [GitHub Settings → Developer settings → Personal access tokens](https://github.com/settings/tokens) -2. Generate a token with scopes: `read:org`, `public_repo`, `user:email` -3. Configure in `mcp_agent.secrets.yaml`: - -```yaml -mcp: - servers: - github: - auth: - api_key: "ghp_your_personal_access_token_here" -``` - -## 🔄 Workflow Pre-Authorization - -The `workflow_pre_auth` endpoint allows you to pre-store OAuth tokens for workflows: - -### 1. Start MCP Agent Server - -```bash -mcp-agent server --config mcp_agent.config.yaml -``` - -### 2. Pre-Authorize Tokens - -```bash -curl -X POST http://localhost:8080/tools/workflows-pre-auth \ - -H "Content-Type: application/json" \ - -d '{ - "workflow_name": "github_analysis_workflow", - "tokens": [ - { - "access_token": "your_github_access_token", - "refresh_token": "your_refresh_token", - "server_name": "github", - "scopes": ["read:org", "public_repo"], - "authorization_server": "https://github.com/login/oauth/authorize" - } - ] - }' -``` - -### 3. Run Workflow - -```bash -curl -X POST http://localhost:8080/tools/workflows-run \ - -H "Content-Type: application/json" \ - -d '{ - "workflow_name": "analyze_github_ecosystem", - "run_parameters": { - "focus_areas": ["AI/ML", "cloud", "security"], - "include_details": true - } - }' -``` - -## 🛠 Examples Explained - -### main.py - Basic OAuth Integration - -Demonstrates: -- Connecting to GitHub MCP server with OAuth -- Using the `search_orgs` tool -- Error handling and token management -- Both single-use and persistent connections - -Key features: -```python -async with gen_client("github", server_registry=context.server_registry) as github_client: - result = await github_client.call_tool("search_orgs", { - "query": "microsoft", - "perPage": 10, - "sort": "best-match" - }) -``` - -### workflow_example.py - Advanced Workflow - -Demonstrates: -- Custom agent (`GitHubOrganizationAnalyzer`) -- Workflow with `@app.async_tool` decorator -- Pre-authorization token usage -- Comprehensive GitHub ecosystem analysis - -Key features: -```python -@app.async_tool -async def analyze_github_ecosystem( - app_ctx: Context, - focus_areas: List[str], - include_details: bool = True -) -> Dict[str, Any]: - # Uses pre-authorized tokens automatically - analyzer = GitHubOrganizationAnalyzer(context=app_ctx) - return await analyzer.analyze_organizations(queries, include_details) -``` - -### oauth_demo.py - Interactive OAuth Setup - -Demonstrates: -- Complete OAuth 2.0 flow -- Local callback server -- Token testing and validation -- Token persistence - -Key features: -- Automatic browser opening -- CSRF protection with state parameter -- Token testing with GitHub API -- Export tokens for MCP agent use - -## ⚙ Configuration Details - -### OAuth Configuration - -```yaml -oauth: - token_store: - backend: memory # or 'redis' for production - refresh_leeway_seconds: 60 - flow_timeout_seconds: 300 - callback_base_url: http://localhost:8080 - -mcp: - servers: - github: - auth: - oauth: - enabled: true - scopes: ["read:org", "public_repo", "user:email"] - authorization_server: "https://github.com/login/oauth/authorize" - resource: "https://api.github.com" -``` - -### GitHub Scopes Required - -| Scope | Purpose | Required | -|-------|---------|----------| -| `read:org` | Search organizations | ✅ Yes | -| `public_repo` | Access public repositories | ✅ Yes | -| `user:email` | User information | ⚠ Recommended | -| `repo` | Private repositories | ❌ Optional | - -## 🔧 Production Deployment - -### Redis Token Storage - -For production with multiple processes: - -```yaml -oauth: - token_store: - backend: redis - redis_url: "redis://localhost:6379" - redis_prefix: "mcp_agent:oauth_tokens" -``` - -### Environment Variables - -```bash -export GITHUB_CLIENT_ID="your_client_id" -export GITHUB_CLIENT_SECRET="your_client_secret" -export REDIS_URL="redis://localhost:6379" -export OPENAI_API_KEY="your_openai_key" -``` - -### Security Best Practices - -1. **Never commit secrets** - Use `.gitignore` for `mcp_agent.secrets.yaml` -2. **Rotate tokens regularly** - Set up token refresh workflows -3. **Minimal scopes** - Only request necessary permissions -4. **Secure storage** - Use Redis or encrypted storage in production -5. **HTTPS callbacks** - Use HTTPS URLs for production OAuth callbacks - -## 🐛 Troubleshooting - -### Common Issues - -#### OAuth Flow Fails -``` -Error: OAuth error: access_denied -``` -**Solution**: Check callback URL matches OAuth app configuration - -#### Token Test Fails -``` -Error: Token test failed: 401 -``` -**Solution**: Verify token scopes and GitHub app permissions - -#### MCP Server Connection Fails -``` -Error: GitHub MCP server not found -``` -**Solution**: Install GitHub MCP server with `uvx install github-mcp-server` - -#### Import Errors -``` -ImportError: No module named 'mcp_agent' -``` -**Solution**: Install with `pip install mcp-agent[oauth]` - -### Debug Mode - -Enable detailed logging: - -```yaml -logger: - level: debug - debug_oauth: true -``` - -### Testing Tokens - -Test your GitHub token manually: - -```bash -curl -H "Authorization: Bearer YOUR_TOKEN" https://api.github.com/user -``` - -## 📚 Advanced Usage - -### Multiple OAuth Providers - -```yaml -mcp: - servers: - github: - auth: - oauth: - client_id: "github_client_id" - # ... GitHub config - - slack: - auth: - oauth: - client_id: "slack_client_id" - # ... Slack config -``` - -### Custom Token Refresh - -```python -async def refresh_github_token(old_token: str) -> str: - # Custom token refresh logic - async with aiohttp.ClientSession() as session: - # ... refresh implementation - return new_token -``` - -### Workflow Chaining - -```python -@app.async_tool -async def multi_step_analysis(app_ctx: Context, orgs: List[str]): - # Step 1: Search organizations - github_results = await search_organizations(orgs) - - # Step 2: Analyze with different service - analysis = await analyze_with_ai(github_results) - - # Step 3: Store results - await store_results(analysis) - - return analysis -``` - -## 🤝 Contributing - -1. Fork the repository -2. Create your feature branch -3. Add tests for new functionality -4. Ensure all examples work -5. Submit a pull request - -## 📄 License - -This example is part of the MCP Agent project and follows the same license terms. - -## 🔗 Related Resources - -- [MCP Agent Documentation](../../README.md) -- [GitHub MCP Server](https://github.com/github/github-mcp-server) -- [OAuth 2.0 Specification](https://tools.ietf.org/html/rfc6749) -- [GitHub OAuth Apps](https://docs.github.com/en/developers/apps/building-oauth-apps) -- [Model Context Protocol](https://modelcontextprotocol.io) - ---- - -For questions or issues with this example, please check the [main repository issues](../../issues) or create a new issue with the `oauth-example` label. \ No newline at end of file diff --git a/examples/oauth/preconfigured/main.py b/examples/oauth/preconfigured/main.py deleted file mode 100644 index c20e164e7..000000000 --- a/examples/oauth/preconfigured/main.py +++ /dev/null @@ -1,186 +0,0 @@ -""" -OAuth MCP Agent Example - -This example demonstrates how to use an MCP agent with OAuth authentication -to access the GitHub MCP server and search for organizations. - -Features demonstrated: -- OAuth flow setup and configuration -- Connecting to GitHub MCP server with OAuth -- Using the search_orgs tool -- Error handling and token refresh -""" - -import asyncio -import json -import logging -from typing import Any, Dict, List - -from mcp_agent.app import MCPApp -from mcp_agent.mcp.gen_client import gen_client - -# Create the MCP app with OAuth configuration -app = MCPApp(name="oauth_github_example") - -async def search_github_orgs(query: str, limit: int = 5) -> List[Dict[str, Any]]: - """ - Search for GitHub organizations using the GitHub MCP server with OAuth. - - Args: - query: Search query (e.g., 'microsoft', 'location:california') - limit: Maximum number of results to return - - Returns: - List of organization data from GitHub - """ - async with app.run() as github_app: - context = github_app.context - logger = github_app.logger - - logger.info(f"Searching GitHub organizations for: '{query}'") - - try: - # Connect to the GitHub MCP server with OAuth - async with gen_client( - "github", - server_registry=context.server_registry, - context=context - ) as github_client: - logger.info("Connected to GitHub MCP server with OAuth") - - # List available tools to verify connection - tools_result = await github_client.list_tools() - logger.info(f"Available tools: {len(tools_result.tools)} tools found") - - # Find the search_orgs tool - search_orgs_tool = None - for tool in tools_result.tools: - if tool.name == "search_orgs": - search_orgs_tool = tool - break - - if not search_orgs_tool: - logger.error("search_orgs tool not found") - return [] - - logger.info(f"Found search_orgs tool: {search_orgs_tool.description}") - - # Call the search_orgs tool - result = await github_client.call_tool( - "search_orgs", - { - "query": query, - "perPage": min(limit, 100), # GitHub API max is 100 - "sort": "best-match", - "order": "desc" - } - ) - - logger.info("Search completed, processing results...") - - # Parse and return the results - if result.content: - # The result content should contain the organization data - organizations = [] - for content_item in result.content: - if hasattr(content_item, 'text'): - try: - # Try to parse as JSON if it's structured data - data = json.loads(content_item.text) - if isinstance(data, dict) and 'items' in data: - organizations.extend(data['items'][:limit]) - elif isinstance(data, list): - organizations.extend(data[:limit]) - else: - organizations.append(data) - except json.JSONDecodeError: - # If not JSON, treat as text description - organizations.append({"description": content_item.text}) - - logger.info(f"Found {len(organizations)} organizations") - return organizations[:limit] - - return [] - - except Exception as e: - logger.error(f"Error searching GitHub organizations: {e}") - # Check if it's an OAuth-related error - if "authentication" in str(e).lower() or "oauth" in str(e).lower(): - logger.error( - "Authentication failed. Please check your OAuth configuration " - "and ensure your GitHub token is valid." - ) - raise - - -async def demonstrate_org_search(): - """ - Demonstrate searching for different types of organizations. - """ - search_queries = [ - "microsoft", - # "location:california", - # "created:>=2020-01-01", - # "language:python", - # "repositories:>100" - ] - - for query in search_queries: - print(f"\n{'='*50}") - print(f"Searching for: {query}") - print('='*50) - - try: - orgs = await search_github_orgs(query, limit=3) - - if orgs: - for i, org in enumerate(orgs, 1): - print(f"\n{i}. {org.get('login', 'Unknown')}") - if 'description' in org and org['description']: - print(f" Description: {org['description']}") - if 'html_url' in org: - print(f" URL: {org['html_url']}") - if 'public_repos' in org: - print(f" Public repos: {org['public_repos']}") - if 'location' in org and org['location']: - print(f" Location: {org['location']}") - else: - print("No organizations found.") - - except Exception as e: - print(f"Error: {e}") - continue - - - -async def main(): - """ - Main function demonstrating various OAuth MCP agent usage patterns. - """ - print("OAuth MCP Agent Example - GitHub Organization Search") - print("=" * 60) - - try: - # Demonstrate basic organization search - await demonstrate_org_search() - - except Exception as e: - print(f"\nExample failed with error: {e}") - print("\nPlease ensure:") - print("1. You have configured your GitHub OAuth app correctly") - print("2. Your mcp_agent.secrets.yaml file contains valid OAuth credentials") - print("3. The GitHub MCP server is properly installed and accessible") - print("4. Your OAuth token has the required scopes (read:org)") - - # Log the full error for debugging - logging.exception("Full error details:") - - -if __name__ == "__main__": - # Set up logging to show detailed information - logging.basicConfig( - level=logging.INFO, - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" - ) - - asyncio.run(main()) \ No newline at end of file diff --git a/examples/oauth/preconfigured/mcp_agent.config.yaml b/examples/oauth/preconfigured/mcp_agent.config.yaml deleted file mode 100644 index 61fa80456..000000000 --- a/examples/oauth/preconfigured/mcp_agent.config.yaml +++ /dev/null @@ -1,115 +0,0 @@ -$schema: ../../schema/mcp-agent.config.schema.json - -# OAuth MCP Agent Configuration -# This configuration demonstrates how to set up OAuth authentication -# for accessing OAuth-protected MCP servers like the GitHub MCP server - -execution_engine: asyncio - -# Logging configuration -logger: - type: console - level: debug - path: "./mcp-agent.log" - # Enable detailed OAuth and authentication logging - debug_oauth: true - -# OpenTelemetry tracing (optional) -tracing: - enabled: true - service_name: "OAuth-MCP-Agent-Example" - exporters: ["console"] - -# OAuth-specific configuration -oauth: - # Token store configuration - token_store: - backend: memory # Use 'redis' for production with multiple processes - refresh_leeway_seconds: 60 # Refresh tokens 60 seconds before expiry - - # OAuth flow timeout (5 minutes) - flow_timeout_seconds: 300 - - # Callback base URL for OAuth flows (adjust if running behind proxy) - callback_base_url: http://localhost:8080 - -# MCP server configurations -mcp: - servers: - # GitHub MCP Server with OAuth authentication - github: - # Use the remote GitHub MCP server - transport: "streamable_http" - url: "https://api.githubcopilot.com/mcp/" - - # OAuth authentication configuration - auth: - oauth: - enabled: true - # Required scopes for GitHub MCP server functionality - scopes: - - "read:org" # Required for search_orgs tool - - "public_repo" # Access to public repositories - - "user:email" # User information access - - # GitHub OAuth endpoints - authorization_server: "https://github.com/login/oauth" - resource: "https://api.githubcopilot.com/mcp" - - # Use internal callback handling (recommended) - use_internal_callback: true - - # Example: Additional MCP server (filesystem for local operations) - filesystem: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-filesystem", "."] - # No auth required for local filesystem server - - # Example: Fetch server (no auth required) - fetch: - command: "uvx" - args: ["mcp-server-fetch"] - -# Authorization server configuration (if exposing this agent as an MCP server) -authorization: - enabled: false # Set to true if you want to expose this agent with OAuth protection - # issuer_url: "https://your-oauth-provider.com" - # resource_server_url: "https://your-agent-server.com" - # required_scopes: ["agent:read", "agent:execute"] - -# Model configuration (for LLM-based agents) -openai: - # API keys are stored in mcp_agent.secrets.yaml - model: "gpt-4" - temperature: 0.1 - max_tokens: 2000 - -anthropic: - # API keys are stored in mcp_agent.secrets.yaml - model: "claude-3-sonnet-20240229" - max_tokens: 2000 - -# Agent-specific settings -agents: - # Configuration for the GitHubOrganizationAnalyzer agent - default_timeout: 30 - max_retries: 3 - - # GitHub-specific settings - github: - max_orgs_per_query: 10 - default_search_sort: "best-match" - include_detailed_analysis: true - -# Workflow configuration -workflows: - # Default workflow timeout (30 minutes) - default_timeout_minutes: 30 - - # Enable workflow pre-authorization - enable_pre_auth: true - - # Workflow-specific settings - github_analysis: - max_concurrent_searches: 5 - analysis_depth: "detailed" # "basic" or "detailed" diff --git a/examples/oauth/preconfigured/mcp_agent.secrets.yaml.example b/examples/oauth/preconfigured/mcp_agent.secrets.yaml.example deleted file mode 100644 index 1feea2c6f..000000000 --- a/examples/oauth/preconfigured/mcp_agent.secrets.yaml.example +++ /dev/null @@ -1,41 +0,0 @@ -$schema: ../../schema/mcp-agent.config.schema.json - -# OAuth MCP Agent Secrets Template -# -# This file contains sensitive configuration like API keys and OAuth credentials. -# Copy this file to mcp_agent.secrets.yaml and fill in your actual values. -# - -# OpenAI API configuration -openai: - api_key: "sk-your-openai-api-key-here" - -# Anthropic API configuration -anthropic: - api_key: "sk-ant-api03-your-anthropic-api-key-here" - -# GitHub OAuth App Configuration -# To set up a GitHub OAuth app: -# 1. Go to GitHub Settings > Developer settings > OAuth Apps -# 2. Click "New OAuth App" -# 3. Fill in the application details: -# - Application name: "MCP Agent OAuth Example" -# - Homepage URL: "https://github.com/your-username/your-repo" -# - Authorization callback URL: "http://localhost:8080/oauth/callback" -# 4. Click "Register application" -# 5. Copy the Client ID and generate a Client Secret -# 6. Fill in the values below - -mcp: - servers: - github: - auth: - oauth: - # GitHub OAuth App credentials - client_id: "your-github-client-id-here" - client_secret: "your-github-client-secret-here" - - # Optional: Pre-configured access token (from oauth_demo.py or manual setup) - # If you have a valid access token, you can specify it here to skip the OAuth flow - access_token: "your_github_access_token_here" - # refresh_token: "your_refresh_token_here" # If available diff --git a/examples/oauth/preconfigured/oauth_demo.py b/examples/oauth/preconfigured/oauth_demo.py deleted file mode 100644 index 913d6622b..000000000 --- a/examples/oauth/preconfigured/oauth_demo.py +++ /dev/null @@ -1,384 +0,0 @@ -""" -Standalone OAuth Flow Demonstration - -This script demonstrates the OAuth flow for authenticating with GitHub -and storing tokens for use with MCP agents. This is useful for: -- Understanding the OAuth process -- Testing token acquisition and storage -- Debugging authentication issues -- Setting up tokens for the first time - -Run this script interactively to authenticate with GitHub and store tokens. -""" - -import asyncio -import json -import os -import secrets -import time -import urllib.parse -import webbrowser -from typing import Any, Dict, Optional - -import aiohttp -from aiohttp import web - - -class GitHubOAuthDemo: - """ - Demonstration of GitHub OAuth flow for MCP agent authentication. - """ - - def __init__(self, client_id: str, client_secret: str, redirect_uri: str = None): - """ - Initialize OAuth demo. - - Args: - client_id: GitHub OAuth app client ID - client_secret: GitHub OAuth app client secret - redirect_uri: OAuth redirect URI (defaults to localhost) - """ - self.client_id = client_id - self.client_secret = client_secret - self.redirect_uri = redirect_uri or "http://localhost:8080/internal/oauth/callback" - self.state = secrets.token_urlsafe(32) # CSRF protection - self.access_token: Optional[str] = None - self.refresh_token: Optional[str] = None - self.token_expires_at: Optional[float] = None - - def get_authorization_url(self, scopes: list = None) -> str: - """ - Generate the GitHub authorization URL. - - Args: - scopes: List of OAuth scopes to request - - Returns: - Authorization URL for the user to visit - """ - if scopes is None: - scopes = ["read:org", "public_repo"] # Default scopes for GitHub MCP server - - params = { - "client_id": self.client_id, - "redirect_uri": self.redirect_uri, - "scope": " ".join(scopes), - "state": self.state, - "response_type": "code", - } - - base_url = "https://github.com/login/oauth/authorize" - return f"{base_url}?{urllib.parse.urlencode(params)}" - - async def exchange_code_for_token(self, code: str, state: str) -> Dict[str, Any]: - """ - Exchange authorization code for access token. - - Args: - code: Authorization code from GitHub - state: State parameter for CSRF protection - - Returns: - Token response data - - Raises: - ValueError: If state doesn't match or token exchange fails - """ - if state != self.state: - raise ValueError("State parameter mismatch - possible CSRF attack") - - token_url = "https://github.com/login/oauth/access_token" - data = { - "client_id": self.client_id, - "client_secret": self.client_secret, - "code": code, - "redirect_uri": self.redirect_uri, - } - - headers = { - "Accept": "application/json", - "User-Agent": "MCP-Agent-OAuth-Demo/1.0" - } - - async with aiohttp.ClientSession() as session: - async with session.post(token_url, data=data, headers=headers) as response: - if response.status != 200: - raise ValueError(f"Token exchange failed: {response.status}") - - token_data = await response.json() - - if "error" in token_data: - raise ValueError(f"Token error: {token_data['error_description']}") - - self.access_token = token_data.get("access_token") - self.refresh_token = token_data.get("refresh_token") - - # Calculate expiration time - expires_in = token_data.get("expires_in") - if expires_in: - self.token_expires_at = time.time() + expires_in - else: - # GitHub tokens typically don't expire, but set a far future date - self.token_expires_at = time.time() + (365 * 24 * 3600) # 1 year - - return token_data - - async def test_token(self) -> Dict[str, Any]: - """ - Test the access token by making a simple GitHub API call. - - Returns: - User information from GitHub API - """ - if not self.access_token: - raise ValueError("No access token available") - - headers = { - "Authorization": f"Bearer {self.access_token}", - "Accept": "application/vnd.github.v3+json", - "User-Agent": "MCP-Agent-OAuth-Demo/1.0" - } - - async with aiohttp.ClientSession() as session: - # Test with a simple user info call - async with session.get("https://api.github.com/user", headers=headers) as response: - if response.status != 200: - raise ValueError(f"Token test failed: {response.status}") - - user_data = await response.json() - return user_data - - def get_token_for_mcp_agent(self) -> Dict[str, Any]: - """ - Get token data in the format expected by MCP agent workflow_pre_auth. - - Returns: - Token data dictionary for MCP agent - """ - if not self.access_token: - raise ValueError("No access token available") - - return { - "access_token": self.access_token, - "refresh_token": self.refresh_token, - "server_name": "github", - "scopes": ["read:org", "public_repo"], - "expires_at": self.token_expires_at, - "authorization_server": "https://github.com/login/oauth/authorize", - "token_type": "Bearer" - } - - async def save_token_to_file(self, filename: str = "github_oauth_token.json"): - """ - Save the token to a JSON file for later use. - - Args: - filename: File to save token data - """ - token_data = self.get_token_for_mcp_agent() - - with open(filename, 'w') as f: - json.dump(token_data, f, indent=2) - - print(f"Token saved to {filename}") - print("You can now use this token with the MCP agent workflow_pre_auth endpoint.") - - async def run_oauth_flow(self, scopes: list = None) -> Dict[str, Any]: - """ - Run the complete OAuth flow interactively. - - Args: - scopes: OAuth scopes to request - - Returns: - Complete token data - """ - print("Starting GitHub OAuth flow...") - print("=" * 50) - - # Step 1: Generate authorization URL - auth_url = self.get_authorization_url(scopes) - print("\n1. Please visit this URL to authorize the application:") - print(f" {auth_url}") - print("\n2. After authorization, you'll be redirected to a callback URL.") - - # Step 2: Start local server to handle callback - callback_received = asyncio.Event() - callback_data = {} - - async def handle_callback(request): - nonlocal callback_data - try: - code = request.query.get('code') - state = request.query.get('state') - error = request.query.get('error') - - if error: - callback_data['error'] = error - callback_data['error_description'] = request.query.get('error_description', '') - else: - callback_data['code'] = code - callback_data['state'] = state - - callback_received.set() - - # Return a simple success page - html = """ - - -

OAuth Authorization Complete

-

You can close this window and return to the terminal.

- - - - """ - return web.Response(text=html, content_type='text/html') - - except Exception as e: - print(f"Error in callback handler: {e}") - return web.Response(text=f"Error: {e}", status=500) - - # Start local server - app = web.Application() - app.router.add_get('/internal/oauth/callback', handle_callback) - - runner = web.AppRunner(app) - await runner.setup() - site = web.TCPSite(runner, 'localhost', 8080) - await site.start() - - print("\n3. Local callback server started on http://localhost:8080") - print(" Opening browser to authorization URL...") - - # Open browser automatically - try: - webbrowser.open(auth_url) - except Exception: - print(" (Could not open browser automatically)") - - print("\n4. Waiting for authorization callback...") - - # Wait for callback with timeout - try: - await asyncio.wait_for(callback_received.wait(), timeout=300) # 5 minute timeout - except asyncio.TimeoutError: - print(" Timeout waiting for authorization callback") - await runner.cleanup() - raise ValueError("OAuth flow timeout") - - await runner.cleanup() - - # Step 3: Handle callback result - if 'error' in callback_data: - raise ValueError(f"OAuth error: {callback_data['error']} - {callback_data.get('error_description', '')}") - - code = callback_data.get('code') - state = callback_data.get('state') - - if not code: - raise ValueError("No authorization code received") - - print("5. Authorization code received, exchanging for access token...") - - # Step 4: Exchange code for token - await self.exchange_code_for_token(code, state) - print(" ✓ Access token obtained successfully") - - # Step 5: Test the token - print("6. Testing access token...") - try: - user_info = await self.test_token() - username = user_info.get('login', 'unknown') - print(f" ✓ Token test successful - authenticated as: {username}") - except Exception as e: - print(f" ⚠ Token test failed: {e}") - - return self.get_token_for_mcp_agent() - - -async def main(): - """ - Main interactive OAuth demonstration. - """ - print("GitHub OAuth Demo for MCP Agent") - print("=" * 40) - - # Check for environment variables - client_id = os.getenv('GITHUB_CLIENT_ID') - client_secret = os.getenv('GITHUB_CLIENT_SECRET') - - if not client_id or not client_secret: - print("\nTo use this demo, you need to set up a GitHub OAuth App:") - print("1. Go to GitHub Settings > Developer settings > OAuth Apps") - print("2. Click 'New OAuth App'") - print("3. Set Authorization callback URL to: http://localhost:8080/internal/oauth/callback") - print("4. Set environment variables:") - print(" export GITHUB_CLIENT_ID='your_client_id'") - print(" export GITHUB_CLIENT_SECRET='your_client_secret'") - print("\nAlternatively, you can pass them as command line arguments.") - return - - try: - # Create OAuth demo instance - oauth_demo = GitHubOAuthDemo(client_id, client_secret) - - # Run the OAuth flow - scopes = ["read:org", "public_repo", "user:email"] - token_data = await oauth_demo.run_oauth_flow(scopes) - - print(token_data) - - print("\n" + "=" * 50) - print("OAuth Flow Completed Successfully!") - print("=" * 50) - - print("\nToken Details:") - print(f" Access Token: {token_data['access_token'][:20]}...") - print(f" Expires At: {time.ctime(token_data['expires_at'])}") - print(f" Scopes: {', '.join(token_data['scopes'])}") - - # Save token to file - save_choice = input("\nSave token to file? (y/n): ").lower().strip() - if save_choice in ['y', 'yes']: - filename = input("Enter filename (default: github_oauth_token.json): ").strip() - if not filename: - filename = "github_oauth_token.json" - await oauth_demo.save_token_to_file(filename) - - # Show usage instructions - print("\n" + "=" * 50) - print("Next Steps:") - print("=" * 50) - print("1. Use this token with the MCP agent workflow_pre_auth endpoint:") - - example_usage = { - "workflow_name": "github_analysis_workflow", - "tokens": [token_data] - } - print(f" {json.dumps(example_usage, indent=2)}") - - print("\n2. Or configure it in your mcp_agent.secrets.yaml:") - secrets_example = { - "mcp": { - "servers": { - "github": { - "auth": { - "oauth": { - "access_token": token_data['access_token'], - "refresh_token": token_data.get('refresh_token'), - "scopes": token_data['scopes'] - } - } - } - } - } - } - print(f" {json.dumps(secrets_example, indent=2)}") - - except Exception as e: - print(f"\nOAuth flow failed: {e}") - print("Please check your GitHub OAuth app configuration and try again.") - - -if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file diff --git a/examples/oauth/preconfigured/requirements.txt b/examples/oauth/preconfigured/requirements.txt deleted file mode 100644 index 12966f2cf..000000000 --- a/examples/oauth/preconfigured/requirements.txt +++ /dev/null @@ -1,37 +0,0 @@ -# OAuth MCP Agent Example Requirements -# -# This file specifies the Python dependencies needed to run the OAuth examples. -# Install with: pip install -r requirements.txt - -# Core MCP Agent with OAuth support -mcp-agent[oauth,cli]>=0.1.27 - -# Additional dependencies for OAuth flow and HTTP handling -aiohttp>=3.11.13 -# For OAuth flow demonstration and token management -urllib3>=2.0.0 - -# GitHub MCP Server (install separately with uvx or npm) -# Note: The GitHub MCP server is installed via uvx, not pip -# Run: uvx install github-mcp-server - -# Optional: Enhanced JSON handling -ujson>=5.0.0 - -# Optional: Enhanced async support -trio>=0.30.0 - -# Optional: Redis for production token storage -redis>=4.0.0 - -# Development and testing dependencies (optional) -pytest>=7.4.0 -pytest-asyncio>=0.21.1 - -# For the interactive OAuth demo -webbrowser # Standard library - no explicit install needed - -# Note: Additional MCP servers can be installed as needed: -# - Filesystem server: npm install -g @modelcontextprotocol/server-filesystem -# - Fetch server: uvx install mcp-server-fetch -# - Other servers: See https://github.com/modelcontextprotocol/servers \ No newline at end of file diff --git a/examples/oauth/preconfigured/workflow_example.py b/examples/oauth/preconfigured/workflow_example.py deleted file mode 100644 index 59948bf7b..000000000 --- a/examples/oauth/preconfigured/workflow_example.py +++ /dev/null @@ -1,426 +0,0 @@ -""" -OAuth Workflow Pre-Authorization Example - -This example demonstrates how to use the workflow_pre_auth endpoint to -pre-store OAuth tokens for a workflow, then execute the workflow to -access GitHub MCP server tools. - -Features demonstrated: -- Using the workflow_pre_auth endpoint to store OAuth tokens -- Creating a workflow that uses pre-authorized tokens -- Accessing multiple MCP servers with different tokens -- Error handling for token expiration and OAuth issues -""" - -import asyncio -import json -import time -from typing import Any, Dict, List - -from mcp_agent.app import MCPApp -from mcp_agent.agents.agent import Agent -from mcp_agent.core.context import Context - - -class GitHubOrganizationAnalyzer(Agent): - """ - An agent that analyzes GitHub organizations using pre-authorized OAuth tokens. - """ - - def __init__(self, context: Context): - super().__init__(context=context) - self.name = "github_org_analyzer" - - async def analyze_organizations( - self, - queries: List[str], - detailed_analysis: bool = True - ) -> Dict[str, Any]: - """ - Analyze multiple organizations based on search queries. - - Args: - queries: List of search queries for organizations - detailed_analysis: Whether to fetch detailed information - - Returns: - Analysis results for all organizations - """ - logger = self.context.logger - results = {"organizations": [], "summary": {}, "errors": []} - - try: - # The OAuth tokens should be pre-authorized for this workflow - # and available through the context - logger.info(f"Starting analysis of {len(queries)} organization queries") - - for query in queries: - try: - orgs = await self._search_organizations(query) - - for org in orgs: - org_analysis = { - "query": query, - "organization": org.get("login", "unknown"), - "description": org.get("description", ""), - "url": org.get("html_url", ""), - "public_repos": org.get("public_repos", 0), - "followers": org.get("followers", 0), - "location": org.get("location", ""), - "created_at": org.get("created_at", ""), - } - - if detailed_analysis: - # Add more detailed analysis - org_analysis.update( - await self._analyze_organization_details(org) - ) - - results["organizations"].append(org_analysis) - - except Exception as e: - error_msg = f"Error processing query '{query}': {e}" - logger.error(error_msg) - results["errors"].append(error_msg) - - # Generate summary - results["summary"] = self._generate_summary(results["organizations"]) - - logger.info(f"Analysis completed: {len(results['organizations'])} organizations analyzed") - return results - - except Exception as e: - logger.error(f"Organization analysis failed: {e}") - raise - - async def _search_organizations(self, query: str) -> List[Dict[str, Any]]: - """Search for organizations using the GitHub MCP server.""" - from mcp_agent.mcp.gen_client import gen_client - - async with gen_client( - "github", - server_registry=self.context.server_registry, - context=self.context - ) as github_client: - result = await github_client.call_tool( - "search_orgs", - { - "query": query, - "perPage": 10, - "sort": "best-match", - "order": "desc" - } - ) - - organizations = [] - if result.content: - for content_item in result.content: - if hasattr(content_item, 'text'): - try: - data = json.loads(content_item.text) - if isinstance(data, dict) and 'items' in data: - organizations.extend(data['items']) - elif isinstance(data, list): - organizations.extend(data) - except json.JSONDecodeError: - pass - - return organizations - - async def _analyze_organization_details(self, org: Dict[str, Any]) -> Dict[str, Any]: - """Analyze detailed information about an organization.""" - details = { - "activity_score": self._calculate_activity_score(org), - "size_category": self._categorize_size(org.get("public_repos", 0)), - "age_years": self._calculate_age(org.get("created_at", "")), - } - - return details - - def _calculate_activity_score(self, org: Dict[str, Any]) -> float: - """Calculate a simple activity score based on available metrics.""" - repos = org.get("public_repos", 0) - followers = org.get("followers", 0) - - # Simple scoring algorithm - score = (repos * 0.1) + (followers * 0.01) - return min(score, 100.0) # Cap at 100 - - def _categorize_size(self, repo_count: int) -> str: - """Categorize organization size based on repository count.""" - if repo_count < 10: - return "small" - elif repo_count < 50: - return "medium" - elif repo_count < 200: - return "large" - else: - return "enterprise" - - def _calculate_age(self, created_at: str) -> float: - """Calculate organization age in years.""" - if not created_at: - return 0.0 - - try: - from datetime import datetime - created = datetime.fromisoformat(created_at.replace("Z", "+00:00")) - now = datetime.now(created.tzinfo) - return (now - created).days / 365.25 - except Exception: - return 0.0 - - def _generate_summary(self, organizations: List[Dict[str, Any]]) -> Dict[str, Any]: - """Generate summary statistics from organization analysis.""" - if not organizations: - return {"total": 0, "message": "No organizations analyzed"} - - total_repos = sum(org.get("public_repos", 0) for org in organizations) - total_followers = sum(org.get("followers", 0) for org in organizations) - - size_categories = {} - for org in organizations: - category = org.get("size_category", "unknown") - size_categories[category] = size_categories.get(category, 0) + 1 - - return { - "total_organizations": len(organizations), - "total_public_repos": total_repos, - "total_followers": total_followers, - "average_repos_per_org": total_repos / len(organizations), - "size_distribution": size_categories, - "top_organizations": sorted( - organizations, - key=lambda x: x.get("activity_score", 0), - reverse=True - )[:5] - } - - -# Create workflow using the @app.async_tool decorator -app = MCPApp(name="oauth_workflow_example") - - -@app.async_tool -async def analyze_github_ecosystem( - app_ctx: Context, - focus_areas: List[str], - include_details: bool = True -) -> Dict[str, Any]: - """ - Analyze the GitHub ecosystem based on focus areas. - - This workflow demonstrates using pre-authorized OAuth tokens - to analyze organizations across different domains. - - Args: - focus_areas: Areas to focus on (e.g., ["AI/ML", "cloud", "security"]) - include_details: Whether to include detailed analysis - - Returns: - Comprehensive analysis of the GitHub ecosystem - """ - logger = app_ctx.logger - logger.info(f"Starting GitHub ecosystem analysis for: {focus_areas}") - - # Create the analyzer agent - analyzer = GitHubOrganizationAnalyzer(context=app_ctx) - - # Map focus areas to search queries - query_mapping = { - "AI/ML": ["machine-learning", "artificial-intelligence", "deep-learning", "tensorflow", "pytorch"], - "cloud": ["cloud-computing", "aws", "azure", "kubernetes", "docker"], - "security": ["cybersecurity", "security", "encryption", "vulnerability"], - "web": ["web-development", "javascript", "react", "vue", "angular"], - "mobile": ["mobile-development", "android", "ios", "react-native", "flutter"], - "data": ["data-science", "analytics", "big-data", "database", "sql"], - "devtools": ["developer-tools", "ci-cd", "testing", "monitoring", "automation"] - } - - all_queries = [] - for area in focus_areas: - queries = query_mapping.get(area.lower(), [area.lower()]) - all_queries.extend(queries) - - # Remove duplicates while preserving order - unique_queries = list(dict.fromkeys(all_queries)) - - logger.info(f"Executing {len(unique_queries)} organization searches") - - try: - # Perform the analysis - analysis_results = await analyzer.analyze_organizations( - queries=unique_queries, - detailed_analysis=include_details - ) - - # Add ecosystem-level insights - ecosystem_analysis = { - "focus_areas": focus_areas, - "timestamp": time.time(), - "queries_executed": unique_queries, - "results": analysis_results, - "insights": _generate_ecosystem_insights(analysis_results) - } - - logger.info("GitHub ecosystem analysis completed successfully") - return ecosystem_analysis - - except Exception as e: - logger.error(f"Ecosystem analysis failed: {e}") - raise - - -def _generate_ecosystem_insights(results: Dict[str, Any]) -> Dict[str, Any]: - """Generate high-level insights from the ecosystem analysis.""" - organizations = results.get("organizations", []) - - if not organizations: - return {"message": "No data available for insights"} - - # Find trends and patterns - insights = { - "dominant_languages": _analyze_language_trends(organizations), - "geographic_distribution": _analyze_geographic_distribution(organizations), - "maturity_analysis": _analyze_organization_maturity(organizations), - "activity_patterns": _analyze_activity_patterns(organizations) - } - - return insights - - -def _analyze_language_trends(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: - """Analyze programming language trends from organization data.""" - # This is a simplified example - in a real implementation, - # you might use additional GitHub API calls to get language data - return { - "message": "Language trend analysis would require additional API calls", - "suggestion": "Use repository listing and language detection APIs" - } - - -def _analyze_geographic_distribution(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: - """Analyze geographic distribution of organizations.""" - locations = {} - for org in organizations: - location = org.get("location", "").strip() - if location: - locations[location] = locations.get(location, 0) + 1 - - return { - "total_with_location": len([org for org in organizations if org.get("location")]), - "top_locations": dict(sorted(locations.items(), key=lambda x: x[1], reverse=True)[:10]) - } - - -def _analyze_organization_maturity(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: - """Analyze the maturity of organizations.""" - mature_count = sum(1 for org in organizations if org.get("age_years", 0) > 5) - established_count = sum(1 for org in organizations if 2 <= org.get("age_years", 0) <= 5) - new_count = sum(1 for org in organizations if org.get("age_years", 0) < 2) - - return { - "mature_orgs": mature_count, # > 5 years - "established_orgs": established_count, # 2-5 years - "new_orgs": new_count, # < 2 years - "maturity_ratio": mature_count / len(organizations) if organizations else 0 - } - - -def _analyze_activity_patterns(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: - """Analyze activity patterns across organizations.""" - if not organizations: - return {} - - activity_scores = [org.get("activity_score", 0) for org in organizations] - - return { - "average_activity": sum(activity_scores) / len(activity_scores), - "high_activity_count": sum(1 for score in activity_scores if score > 75), - "low_activity_count": sum(1 for score in activity_scores if score < 25), - "activity_distribution": { - "high": sum(1 for score in activity_scores if score > 75), - "medium": sum(1 for score in activity_scores if 25 <= score <= 75), - "low": sum(1 for score in activity_scores if score < 25) - } - } - - -async def demonstrate_pre_auth_workflow(): - """ - Demonstrate the workflow with pre-authorization. - """ - print("OAuth Workflow Pre-Authorization Example") - print("=" * 50) - - # Note: In a real scenario, you would use the MCP agent server - # to call the workflow_pre_auth endpoint before running the workflow - print("\n1. Pre-authorization step:") - print(" Before running this workflow, you should pre-authorize OAuth tokens:") - print(" Use the workflow_pre_auth endpoint with the following structure:") - - example_tokens = [ - { - "access_token": "github_oauth_access_token_here", - "refresh_token": "github_oauth_refresh_token_here", - "server_name": "github", - "scopes": ["read:org", "public_repo"], - "authorization_server": "https://github.com/login/oauth/authorize" - } - ] - - print(f" Token structure: {json.dumps(example_tokens, indent=2)}") - - print("\n2. Running workflow with pre-authorized tokens:") - - try: - async with app.run() as workflow_app: - # Simulate workflow execution - # In practice, this would be called through the MCP agent server - context = workflow_app.context - - result = await analyze_github_ecosystem( - app_ctx=context, - focus_areas=["AI/ML", "cloud", "security"], - include_details=True - ) - - print("\n3. Workflow Results:") - print(f" - Focus areas analyzed: {result['focus_areas']}") - print(f" - Queries executed: {len(result['queries_executed'])}") - print(f" - Organizations found: {result['results']['summary'].get('total_organizations', 0)}") - - if result['results']['errors']: - print(f" - Errors encountered: {len(result['results']['errors'])}") - - print("\n4. Ecosystem Insights:") - insights = result['insights'] - if 'geographic_distribution' in insights: - top_locations = insights['geographic_distribution'].get('top_locations', {}) - if top_locations: - print(f" - Top locations: {list(top_locations.keys())[:3]}") - - if 'maturity_analysis' in insights: - maturity = insights['maturity_analysis'] - print(f" - Mature organizations: {maturity.get('mature_orgs', 0)}") - print(f" - Maturity ratio: {maturity.get('maturity_ratio', 0):.2%}") - - except Exception as e: - print(f" Workflow failed: {e}") - print("\n This is expected if OAuth tokens are not properly configured.") - print(" To run this example successfully:") - print(" 1. Set up a GitHub OAuth app") - print(" 2. Configure mcp_agent.config.yaml with OAuth settings") - print(" 3. Use workflow_pre_auth to store valid tokens") - print(" 4. Run the workflow through the MCP agent server") - - -async def main(): - """ - Main function demonstrating the workflow pre-authorization pattern. - """ - await demonstrate_pre_auth_workflow() - - -if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file diff --git a/examples/oauth/workflow_pre_auth/README.md b/examples/oauth/workflow_pre_auth/README.md new file mode 100644 index 000000000..d52b4fee4 --- /dev/null +++ b/examples/oauth/workflow_pre_auth/README.md @@ -0,0 +1,51 @@ +# Workflow Pre-Authorization Example + +This example shows how to preload OAuth tokens for asynchronous workflows. +The client calls the `workflows-pre-auth` tool to store a token for a +specific workflow before the workflow runs. Once the token is saved, the +workflow can access the downstream MCP server without further user +interaction. + +## Prerequisites + +1. Obtain a GitHub access token (e.g., via the interactive example) and + export it before running the client: + + ```bash + export GITHUB_ACCESS_TOKEN="github_pat_xxx" + ``` + +2. Install dependencies: + + ```bash + pip install -e . + # optional redis support + # pip install -e .[redis] + ``` + +3. (Optional) To persist tokens in Redis instead of memory, start a Redis + instance and set `OAUTH_REDIS_URL`, for example: + + ```bash + docker run --rm -p 6379:6379 redis:7-alpine + export OAUTH_REDIS_URL="redis://127.0.0.1:6379" + ``` + +## Running + +1. Start the workflow server: + + ```bash + python examples/oauth/workflow_pre_auth/main.py + ``` + +2. In another terminal, run the client to seed the token and execute the + workflow: + + ```bash + python examples/oauth/workflow_pre_auth/client.py + ``` + +The client first invokes `workflows-pre-auth` with the provided token and +then calls the `github_org_search` workflow, which uses the cached token to +query the GitHub MCP server. diff --git a/examples/oauth/workflow_pre_auth/client.py b/examples/oauth/workflow_pre_auth/client.py index cc8fd23bd..4d9ae1a7c 100644 --- a/examples/oauth/workflow_pre_auth/client.py +++ b/examples/oauth/workflow_pre_auth/client.py @@ -27,7 +27,7 @@ _BrokenResourceError = None # type: ignore # Get GitHub access token from environment or ask user -access_token = os.getenv('GITHUB_ACCESS_TOKEN') +access_token = os.getenv("GITHUB_ACCESS_TOKEN") if not access_token: print("\nGitHub access token not found in environment variable GITHUB_ACCESS_TOKEN") @@ -39,8 +39,10 @@ print("export GITHUB_ACCESS_TOKEN='your_token_here'") # Verify token format -if not access_token.startswith(('gho_', 'ghp_', 'github_pat_')): - print(f"Warning: Token doesn't look like a GitHub token (got: {access_token[:10]}...)") +if not access_token.startswith(("gho_", "ghp_", "github_pat_")): + print( + f"Warning: Token doesn't look like a GitHub token (got: {access_token[:10]}...)" + ) print("GitHub tokens usually start with 'gho_', 'ghp_', or 'github_pat_'") @@ -128,18 +130,22 @@ def make_session( if len(sys.argv) < 2 or sys.argv[1] != "--skip-pre-auth": print("Performing pre-auth") - await server.call_tool("workflows-pre-auth", - arguments={ - "workflow_name": "github_org_search", - "tokens": [ - { - "access_token": access_token, - "server_name": "github", - } - ] - }) - - print(await server.call_tool("github_org_search", {"query": "lastmileai"})) + await server.call_tool( + "workflows-pre-auth", + arguments={ + "workflow_name": "github_org_search", + "tokens": [ + { + "access_token": access_token, + "server_name": "github", + } + ], + }, + ) + + print( + await server.call_tool("github_org_search", {"query": "lastmileai"}) + ) except Exception as e: # Tolerate benign shutdown races from stdio client (BrokenResourceError within ExceptionGroup) if _ExceptionGroup is not None and isinstance(e, _ExceptionGroup): diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py index 415803ba0..6f3a7376e 100644 --- a/examples/oauth/workflow_pre_auth/main.py +++ b/examples/oauth/workflow_pre_auth/main.py @@ -1,60 +1,75 @@ -""" -Workflow MCP Server Example - -This example demonstrates three approaches to creating agents and workflows: -1. Traditional workflow-based approach with manual agent creation -2. Programmatic agent configuration using AgentConfig -3. Declarative agent configuration using FastMCPApp decorators -""" - import asyncio import json +import os from typing import Optional + from pydantic import AnyHttpUrl from mcp.server.fastmcp import FastMCP -from mcp_agent.core.context import Context as AppContext from mcp_agent.app import MCPApp -from mcp_agent.server.app_server import create_mcp_server_for_app +from mcp_agent.config import ( + LoggerSettings, + MCPOAuthClientSettings, + MCPServerAuthSettings, + MCPServerSettings, + MCPSettings, + OAuthSettings, + OAuthTokenStoreSettings, + Settings, +) +from mcp_agent.core.context import Context as AppContext from mcp_agent.mcp.gen_client import gen_client -from mcp_agent.config import MCPServerSettings, Settings, LoggerSettings, MCPSettings, MCPServerAuthSettings, \ - MCPOAuthClientSettings +from mcp_agent.server.app_server import create_mcp_server_for_app # Note: This is purely optional: # if not provided, a default FastMCP server will be created by MCPApp using create_mcp_server_for_app() mcp = FastMCP(name="basic_agent_server", instructions="My basic agent server example.") -class MCPServerOAuthSettings: - pass - +redis_url = os.getenv("OAUTH_REDIS_URL") +if redis_url: + token_store_settings = OAuthTokenStoreSettings( + backend="redis", + redis_url=redis_url, + redis_prefix="mcp_agent:oauth_tokens", + refresh_leeway_seconds=60, + ) +else: + token_store_settings = OAuthTokenStoreSettings(refresh_leeway_seconds=60) settings = Settings( - execution_engine="asyncio", - logger=LoggerSettings(level="info"), - mcp=MCPSettings( - servers={ - "github": MCPServerSettings( - name="github", - transport="streamable_http", - url="https://api.githubcopilot.com/mcp/", - auth=MCPServerAuthSettings( - oauth=MCPOAuthClientSettings( - enabled=True, - scopes= [ - "read:org", # Required for search_orgs tool - "public_repo", # Access to public repositories - "user:email" # User information access - ], - authorization_server=AnyHttpUrl("https://github.com/login/oauth"), - resource=AnyHttpUrl("https://api.githubcopilot.com/mcp") - ) + execution_engine="asyncio", + logger=LoggerSettings(level="info"), + oauth=OAuthSettings( + callback_base_url=AnyHttpUrl("http://localhost:8000"), + flow_timeout_seconds=300, + token_store=token_store_settings, + ), + mcp=MCPSettings( + servers={ + "github": MCPServerSettings( + name="github", + transport="streamable_http", + url="https://api.githubcopilot.com/mcp/", + auth=MCPServerAuthSettings( + oauth=MCPOAuthClientSettings( + enabled=True, + scopes=[ + "read:org", # Required for search_orgs tool + "public_repo", # Access to public repositories + "user:email", # User information access + ], + authorization_server=AnyHttpUrl( + "https://github.com/login/oauth" + ), + resource=AnyHttpUrl("https://api.githubcopilot.com/mcp"), ) - ) - } - ), - ) + ), + ) + } + ), +) # Define the MCPApp instance. The server created for this app will advertise the # MCP logging capability and forward structured logs upstream to connected clients. @@ -68,7 +83,6 @@ class MCPServerOAuthSettings: @app.tool(name="github_org_search") async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: - # Use the context's app if available for proper logging with upstream_session _app = app_ctx.app if app_ctx else app # Ensure the app's logger is bound to the current context with upstream_session @@ -77,28 +91,21 @@ async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> try: async with gen_client( - "github", - server_registry=app_ctx.server_registry, - context=app_ctx + "github", server_registry=app_ctx.server_registry, context=app_ctx ) as github_client: result = await github_client.call_tool( "search_orgs", - { - "query": query, - "perPage": 10, - "sort": "best-match", - "order": "desc" - } + {"query": query, "perPage": 10, "sort": "best-match", "order": "desc"}, ) organizations = [] if result.content: for content_item in result.content: - if hasattr(content_item, 'text'): + if hasattr(content_item, "text"): try: data = json.loads(content_item.text) - if isinstance(data, dict) and 'items' in data: - organizations.extend(data['items']) + if isinstance(data, dict) and "items" in data: + organizations.extend(data["items"]) elif isinstance(data, list): organizations.extend(data) except json.JSONDecodeError: @@ -107,8 +114,10 @@ async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> return str(organizations) except Exception: import traceback + return f"Error: {traceback.format_exc()}" + async def main(): async with app.run() as agent_app: # Log registered workflows and agent configurations @@ -124,7 +133,7 @@ async def main(): agent_app.logger.info(f"MCP Server settings: {mcp_server.settings}") # Run the server - #await mcp_server.run_stdio_async() + # await mcp_server.run_stdio_async() await mcp_server.run_sse_async() diff --git a/pyproject.toml b/pyproject.toml index 80ef42b26..0e321ba07 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,9 @@ cohere = [ langchain = [ "langchain-core>=0.3.64", ] +redis = [ + "redis[hiredis]>=5.0.4", +] crewai = [ "crewai>=0.126.0", ] diff --git a/src/mcp_agent/app.py b/src/mcp_agent/app.py index ada753935..968d56ff4 100644 --- a/src/mcp_agent/app.py +++ b/src/mcp_agent/app.py @@ -85,6 +85,7 @@ def __init__( signal_notification: SignalWaitCallback | None = None, upstream_session: Optional["ServerSession"] = None, model_selector: ModelSelector | None = None, + session_id: str | None = None, ): """ Initialize the application with a name and optional settings. @@ -135,6 +136,7 @@ def __init__( self._signal_notification = signal_notification self._upstream_session = upstream_session self._model_selector = model_selector + self._session_id_override = session_id self._workflows: Dict[str, Type["Workflow"]] = {} # id to workflow class # Deferred tool declarations to register with MCP server when available @@ -239,6 +241,7 @@ async def initialize(self): decorator_registry=self._decorator_registry, signal_registry=self._signal_registry, store_globally=True, + session_id=self._session_id_override, ) # Store the app-specific tracer provider @@ -265,7 +268,32 @@ async def initialize(self): if oauth_settings: self.logger.debug("Initializing OAuth token management") - token_store = InMemoryTokenStore() + backend = ( + oauth_settings.token_store.backend + if oauth_settings.token_store + else "memory" + ) + if backend == "redis": + from mcp_agent.oauth.store import RedisTokenStore + + if RedisTokenStore is None: + raise ImportError( + "Redis token store requires the 'redis' optional dependency. " + "Install with `pip install mcp-agent[redis]`." + ) + + redis_url = oauth_settings.token_store.redis_url + if not redis_url: + raise ValueError( + "redis_url must be configured when using the Redis token store" + ) + token_store = RedisTokenStore( + url=redis_url, + prefix=oauth_settings.token_store.redis_prefix, + ) + else: + token_store = InMemoryTokenStore() + token_manager = TokenManager( token_store=token_store, settings=oauth_settings, @@ -358,9 +386,11 @@ async def initialize(self): async def _initialize_preconfigured_tokens(self, token_manager): """Check for pre-configured OAuth tokens and store them with a single synthetic user.""" - mcp_config = getattr(self._context.config, 'mcp', None) - if not mcp_config or not getattr(mcp_config, 'servers', None): - self.logger.debug("No MCP servers found in config, skipping token initialization") + mcp_config = getattr(self._context.config, "mcp", None) + if not mcp_config or not getattr(mcp_config, "servers", None): + self.logger.debug( + "No MCP servers found in config, skipping token initialization" + ) return servers = mcp_config.servers @@ -370,28 +400,34 @@ async def _initialize_preconfigured_tokens(self, token_manager): # First pass: check which servers have pre-configured tokens for server_name, server_config in servers.items(): - if not hasattr(server_config, 'auth') or not server_config.auth: - self.logger.debug(f"Server '{server_name}' has no auth config, skipping") + if not hasattr(server_config, "auth") or not server_config.auth: + self.logger.debug( + f"Server '{server_name}' has no auth config, skipping" + ) continue - oauth_config = getattr(server_config.auth, 'oauth', None) + oauth_config = getattr(server_config.auth, "oauth", None) - if not oauth_config or not oauth_config.enabled or not oauth_config.access_token: + if ( + not oauth_config + or not oauth_config.enabled + or not oauth_config.access_token + ): continue self.logger.debug(f"Server '{server_name}' has pre-configured OAuth token") servers_with_tokens.append((server_name, server_config)) - # If we have any servers with pre-configured tokens, create a single synthetic user if servers_with_tokens: - synthetic_user = token_manager.create_default_user_for_preconfigured_tokens() - self._context.current_user = synthetic_user - self.logger.info(f"Created synthetic user for pre-configured OAuth tokens: {synthetic_user.cache_key}") - - # Second pass: store all tokens using the same synthetic user for server_name, server_config in servers_with_tokens: - self.logger.info(f"Storing pre-configured OAuth token for server: {server_name}") - await token_manager.store_preconfigured_token(server_name, server_config, synthetic_user) + self.logger.info( + "Storing pre-configured OAuth token for server: %s", server_name + ) + await token_manager.store_preconfigured_token( + context=self._context, + server_name=server_name, + server_config=server_config, + ) async def get_token_node(self): """Return the root app token node, if available.""" diff --git a/src/mcp_agent/core/context.py b/src/mcp_agent/core/context.py index cc7bee78e..24d4071a6 100644 --- a/src/mcp_agent/core/context.py +++ b/src/mcp_agent/core/context.py @@ -204,6 +204,7 @@ async def initialize_context( decorator_registry: Optional[DecoratorRegistry] = None, signal_registry: Optional[SignalRegistry] = None, store_globally: bool = False, + session_id: str | None = None, ): """ Initialize the global application context. @@ -221,7 +222,7 @@ async def initialize_context( config, context.executor ) - context.session_id = str(context.executor.uuid()) + context.session_id = session_id or str(context.executor.uuid()) # Initialize token counter with engine hint for fast path checks context.token_counter = TokenCounter(execution_engine=config.execution_engine) diff --git a/src/mcp_agent/executor/workflow.py b/src/mcp_agent/executor/workflow.py index 3362208f2..2721fac2c 100644 --- a/src/mcp_agent/executor/workflow.py +++ b/src/mcp_agent/executor/workflow.py @@ -431,6 +431,7 @@ async def cancel(self) -> bool: return False if temporal_workflow is not None: + @temporal_workflow.signal(dynamic=True) async def _signal_receiver(self, name: str, args: Sequence[RawValue]): """Dynamic signal handler for Temporal workflows.""" diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index a93dd69ea..b2f0523b7 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -85,14 +85,14 @@ async def authorize( scope_param = " ".join(scopes) params = { - "response_type":"code", - "client_id":client_id, - "redirect_uri":redirect_uri, - "scope":scope_param, - "state":state, - "code_challenge":code_challenge, - "code_challenge_method":"S256", - "resource":resource, + "response_type": "code", + "client_id": client_id, + "redirect_uri": redirect_uri, + "scope": scope_param, + "state": state, + "code_challenge": code_challenge, + "code_challenge_method": "S256", + "resource": resource, } # add extra params if any @@ -100,8 +100,11 @@ async def authorize( params.update(oauth_config.extra_authorize_params) import urllib.parse + authorize_url = httpx.URL( - str(auth_metadata.authorization_endpoint) +"?" + urllib.parse.urlencode(params) + str(auth_metadata.authorization_endpoint) + + "?" + + urllib.parse.urlencode(params) ) callback_future = None @@ -112,7 +115,7 @@ async def authorize( "url": str(authorize_url), "message": f"Authorization required for {server_name}", "redirect_uri_options": redirect_options, - "flow_id": flow_id + "flow_id": flow_id, } result = await _send_auth_request(context, request_payload) @@ -200,6 +203,9 @@ async def authorize( else: effective_scopes = tuple(scopes) + issuer = getattr(auth_metadata, "issuer", None) + issuer_str = str(issuer) if issuer else authorization_server_url + return TokenRecord( access_token=access_token, refresh_token=refresh_token, @@ -207,8 +213,11 @@ async def authorize( scopes=effective_scopes, token_type=str(callback_data.get("token_type", "Bearer")), resource=resource, - authorization_server=authorization_server_url, - metadata={"raw": token_response.text}, + authorization_server=issuer_str, + metadata={ + "raw": token_response.text, + "authorization_server_url": authorization_server_url, + }, ) diff --git a/src/mcp_agent/oauth/http/auth.py b/src/mcp_agent/oauth/http/auth.py index a061e02ff..11f32ff29 100644 --- a/src/mcp_agent/oauth/http/auth.py +++ b/src/mcp_agent/oauth/http/auth.py @@ -56,6 +56,7 @@ async def async_auth_flow(self, request: httpx.Request): resource=token_record.resource or "", authorization_server=token_record.authorization_server, scopes=token_record.scopes, + session_id=self._context.session_id, ) refreshed_record = await self._token_manager.ensure_access_token( @@ -65,13 +66,8 @@ async def async_auth_flow(self, request: httpx.Request): scopes=self._scopes, ) - # Create a new request with the refreshed token - retry_request = httpx.Request( - method=request.method, - url=request.url, - headers=request.headers.copy(), - content=request.content, - ) + # Create a new request with the refreshed token. Using copy() preserves the original body. + retry_request = request.copy() retry_request.headers["Authorization"] = ( f"{refreshed_record.token_type} {refreshed_record.access_token}" ) diff --git a/src/mcp_agent/oauth/identity.py b/src/mcp_agent/oauth/identity.py index 54c6d6fed..65eb22dd6 100644 --- a/src/mcp_agent/oauth/identity.py +++ b/src/mcp_agent/oauth/identity.py @@ -44,3 +44,8 @@ def _claim(token: MCPAccessToken, key: str) -> Any | None: if not token.claims: return None return token.claims.get(key) + + +DEFAULT_PRECONFIGURED_IDENTITY = OAuthUserIdentity( + provider="mcp-agent", subject="preconfigured-tokens" +) diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index 7dbcb12eb..9c87d8a68 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -5,7 +5,8 @@ import asyncio import time from collections import defaultdict -from typing import Dict, Iterable, Sequence, TYPE_CHECKING +from dataclasses import dataclass +from typing import Dict, Iterable, Sequence, Tuple, TYPE_CHECKING import httpx from httpx import URL @@ -13,11 +14,15 @@ from mcp_agent.config import MCPOAuthClientSettings, OAuthSettings from mcp_agent.logging.logger import get_logger from mcp_agent.oauth.errors import ( + MissingUserIdentityError, OAuthFlowError, TokenRefreshError, ) from mcp_agent.oauth.flow import AuthorizationFlowCoordinator -from mcp_agent.oauth.identity import OAuthUserIdentity +from mcp_agent.oauth.identity import ( + DEFAULT_PRECONFIGURED_IDENTITY, + OAuthUserIdentity, +) from mcp_agent.oauth.metadata import ( fetch_authorization_server_metadata, fetch_resource_metadata, @@ -35,18 +40,94 @@ if TYPE_CHECKING: from mcp_agent.core.context import Context +from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata + logger = get_logger(__name__) -def create_default_user_for_preconfigured_tokens(session_id: str | None = None) -> "OAuthUserIdentity": - """Create a synthetic user identity for pre-configured tokens.""" - from mcp_agent.oauth.identity import OAuthUserIdentity +@dataclass(frozen=True) +class ResolvedOAuthContext: + """Resolved metadata for interacting with an OAuth authorization server.""" + + resource: str + resource_metadata: ProtectedResourceMetadata + authorization_server_url: str + authorization_metadata: OAuthMetadata + issuer: str + scopes: Tuple[str, ...] + + +def _dedupe(sequence: Iterable[OAuthUserIdentity]) -> list[OAuthUserIdentity]: + seen = set() + result: list[OAuthUserIdentity] = [] + for identity in sequence: + if identity is None: + continue + key = identity.cache_key + if key in seen: + continue + seen.add(key) + result.append(identity) + return result + + +def _canonicalize_url(url: str) -> str: + parsed = URL(url) + if parsed.scheme not in ("http", "https"): + raise OAuthFlowError(f"Unsupported URL scheme for canonicalization: {url}") + host = parsed.host.lower() if parsed.host else parsed.host + path = parsed.path.rstrip("/") + if path == "/": + path = "" + canonical = parsed.copy_with( + scheme=parsed.scheme, + host=host, + path=path, + query=None, + fragment=None, + ) + return str(canonical) + - return OAuthUserIdentity( - provider="mcp-agent", - subject=f"preconfigured-tokens-{session_id}" if session_id else "preconfigured-tokens", - claims={"token_source": "preconfigured", "description": "Synthetic user for pre-configured OAuth tokens"} +def _candidate_resource_metadata_urls(parsed_resource: URL) -> list[str]: + base = parsed_resource.copy_with(path="", query=None, fragment=None) + path = parsed_resource.path.lstrip("/") + candidates = [] + if path: + candidates.append( + str(base.copy_with(path=f"/.well-known/oauth-protected-resource/{path}")) + ) + candidates.append(str(base.copy_with(path="/.well-known/oauth-protected-resource"))) + # remove duplicates while preserving order + seen = set() + ordered: list[str] = [] + for candidate in candidates: + if candidate not in seen: + seen.add(candidate) + ordered.append(candidate) + return ordered + + +def _candidate_authorization_metadata_urls( + parsed_authorization_server: URL, +) -> list[str]: + base = parsed_authorization_server.copy_with(path="", query=None, fragment=None) + path = parsed_authorization_server.path.lstrip("/") + candidates = [] + if path: + candidates.append( + str(base.copy_with(path=f"/.well-known/oauth-authorization-server/{path}")) + ) + candidates.append( + str(base.copy_with(path="/.well-known/oauth-authorization-server")) ) + seen = set() + ordered: list[str] = [] + for candidate in candidates: + if candidate not in seen: + seen.add(candidate) + ordered.append(candidate) + return ordered class TokenManager: @@ -67,45 +148,152 @@ def __init__( http_client=self._http_client, settings=self._settings ) self._locks: Dict[TokenStoreKey, asyncio.Lock] = defaultdict(asyncio.Lock) - self._resource_metadata_cache: Dict[str, tuple[float, object]] = {} - self._auth_metadata_cache: Dict[str, tuple[float, object]] = {} + # Cache resource metadata by canonical resource string + self._resource_metadata_cache: Dict[ + str, tuple[float, ProtectedResourceMetadata] + ] = {} + # Cache authorization metadata by canonical issuer + self._auth_metadata_cache: Dict[str, tuple[float, OAuthMetadata]] = {} + self._default_identity = DEFAULT_PRECONFIGURED_IDENTITY async def store_preconfigured_token( self, + *, + context: "Context", server_name: str, server_config, - synthetic_user: "OAuthUserIdentity" ) -> None: - """Store a pre-configured token in the token store.""" - oauth_config = server_config.auth.oauth - - # Create token record - resource_str = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) - auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server else None + """Store a pre-configured token defined in the MCP configuration.""" + oauth_config: MCPOAuthClientSettings | None = None + if server_config and server_config.auth: + oauth_config = getattr(server_config.auth, "oauth", None) + if not oauth_config or not oauth_config.enabled: + return + if not oauth_config.access_token: + logger.debug( + "No preconfigured access token provided for server '%s'; skipping", + server_name, + ) + return + + resolved = await self._resolve_oauth_context( + context=context, + server_name=server_name, + server_config=server_config, + oauth_config=oauth_config, + requested_scopes=oauth_config.scopes or [], + ) from datetime import datetime, timezone + record = TokenRecord( access_token=oauth_config.access_token, refresh_token=oauth_config.refresh_token, - scopes=tuple(oauth_config.scopes or []), + scopes=tuple(oauth_config.scopes or resolved.scopes), expires_at=oauth_config.expires_at, token_type=oauth_config.token_type, - resource=resource_str, - authorization_server=auth_server_str, + resource=resolved.resource, + authorization_server=resolved.issuer, obtained_at=datetime.now(tz=timezone.utc).timestamp(), - metadata={"server_name": server_name, "pre_configured": True} + metadata={ + "server_name": server_name, + "pre_configured": True, + "authorization_server_url": resolved.authorization_server_url, + }, + ) + + key = self._build_store_key( + self._default_identity, + resolved.resource, + resolved.issuer, + record.scopes, + ) + logger.debug( + f"Caching preconfigured token for server '{server_name}' under identity " + f"'{self._default_identity.cache_key}'" + ) + await self._token_store.set(key, record) + + async def store_user_token( + self, + *, + context: "Context", + user: OAuthUserIdentity, + server_name: str, + server_config, + token_data: Dict[str, object], + workflow_name: str | None = None, + ) -> None: + """Persist a token supplied through the workflow pre-auth endpoint.""" + if not token_data.get("access_token"): + raise OAuthFlowError("Missing access_token in token payload") + + oauth_config: MCPOAuthClientSettings | None = None + if server_config and server_config.auth: + oauth_config = getattr(server_config.auth, "oauth", None) + if not oauth_config or not oauth_config.enabled: + raise OAuthFlowError( + f"Server '{server_name}' is not configured for OAuth authentication" + ) + + provided_scopes = tuple(token_data.get("scopes") or []) + resolved = await self._resolve_oauth_context( + context=context, + server_name=server_name, + server_config=server_config, + oauth_config=oauth_config, + requested_scopes=provided_scopes or oauth_config.scopes or [], ) - # Create storage key - key = TokenStoreKey( - user_key=synthetic_user.cache_key, - resource=resource_str or "", - authorization_server=auth_server_str, - scope_fingerprint=scope_fingerprint(oauth_config.scopes or []) + # Verify authorization server alignment if the caller provided one. + provided_auth_server = token_data.get("authorization_server") + if provided_auth_server: + provided_canonical = _canonicalize_url(str(provided_auth_server)) + if provided_canonical != resolved.issuer: + raise OAuthFlowError( + "authorization_server does not match configured authorization server" + ) + + from datetime import datetime, timezone + + scopes_tuple = ( + tuple(provided_scopes) + if provided_scopes + else tuple(oauth_config.scopes or resolved.scopes) + ) + if resolved.scopes and scopes_tuple: + missing = set(resolved.scopes) - set(scopes_tuple) + if missing: + logger.warning( + "Stored token for server '%s' missing expected scopes: %s", + server_name, + sorted(missing), + ) + + record = TokenRecord( + access_token=str(token_data["access_token"]), + refresh_token=token_data.get("refresh_token"), + scopes=scopes_tuple, + expires_at=token_data.get("expires_at"), + token_type=str(token_data.get("token_type", "Bearer")), + resource=resolved.resource, + authorization_server=resolved.issuer, + obtained_at=datetime.now(tz=timezone.utc).timestamp(), + metadata={ + "server_name": server_name, + "authorization_server_url": resolved.authorization_server_url, + "pre_configured": False, + "workflow_name": workflow_name, + "session_id": getattr(context, "session_id", None), + }, ) - # Store the token - logger.debug(f"Storing token with key: user_key={key.user_key}, resource={key.resource}, auth_server={key.authorization_server}, scope_fingerprint={key.scope_fingerprint}") + key = self._build_store_key( + user, + resolved.resource, + resolved.issuer, + record.scopes, + ) await self._token_store.set(key, record) async def ensure_access_token( @@ -124,110 +312,122 @@ async def ensure_access_token( f"Server '{server_name}' is not configured for OAuth authentication" ) - user = context.current_user - - # Use the same key construction logic as store_preconfigured_token to ensure consistency - resource_str = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) - auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server else None - scope_list = list(scopes) if scopes is not None else list(oauth_config.scopes or []) - - # check for a globally configure token - key = TokenStoreKey( - user_key=create_default_user_for_preconfigured_tokens().cache_key, - resource=resource_str, - authorization_server=auth_server_str, - scope_fingerprint=scope_fingerprint(scope_list) + requested_scopes = ( + list(scopes) if scopes is not None else list(oauth_config.scopes or []) + ) + resolved = await self._resolve_oauth_context( + context=context, + server_name=server_name, + server_config=server_config, + oauth_config=oauth_config, + requested_scopes=requested_scopes, ) - lock = self._locks[key] + session_identity = self._session_identity(context) + identities = _dedupe( + [ + context.current_user, + session_identity, + self._default_identity, + ] + ) + if not identities: + raise MissingUserIdentityError( + "No authenticated user available for OAuth authorization" + ) - async with lock: - record = await self._token_store.get(key) - if record: - return record - - # there is no global token, look for a user specific one - key = TokenStoreKey( - user_key=user.cache_key, - resource=resource_str, - authorization_server=auth_server_str, - scope_fingerprint=scope_fingerprint(scope_list) + leeway = ( + self._settings.token_store.refresh_leeway_seconds + if self._settings.token_store + else 60 ) - lock = self._locks[key] - async with lock: - record = await self._token_store.get(key) - leeway = ( - self._settings.token_store.refresh_leeway_seconds - if self._settings and self._settings.token_store - else 60 + last_error: Exception | None = None + for identity in identities: + key = self._build_store_key( + identity, + resolved.resource, + resolved.issuer, + resolved.scopes, ) - if record and not record.is_expired(leeway_seconds=leeway): - return record - - # If token exists but expired, try to refresh it - if record and record.refresh_token: - # For refresh, we need OAuth metadata - resource_hint = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) - server_url = getattr(server_config, "url", None) - resource = normalize_resource(resource_hint, server_url) - - # Get OAuth metadata for token refresh - parsed_resource = URL(resource) - metadata_url = str(parsed_resource.copy_with(path="/.well-known/oauth-protected-resource" + parsed_resource.path)) - resource_metadata = await self._get_resource_metadata(metadata_url) - auth_server_url = select_authorization_server( - resource_metadata, str(oauth_config.authorization_server) - ) - auth_metadata = await self._get_authorization_metadata(auth_server_url) - - try: - refreshed = await self._refresh_token( - record, - oauth_config=oauth_config, - auth_metadata=auth_metadata, - resource=resource, - scopes=scope_list, - ) - except TokenRefreshError: - await self._token_store.delete(key) - else: + lock = self._locks[key] + async with lock: + record = await self._token_store.get(key) + if record and not record.is_expired(leeway_seconds=leeway): + return record + + if record and record.refresh_token: + try: + refreshed = await self._refresh_token( + record, + oauth_config=oauth_config, + auth_metadata=resolved.authorization_metadata, + resource=resolved.resource, + scopes=resolved.scopes, + ) + except TokenRefreshError as exc: + logger.warning( + "Failed to refresh token for identity '%s': %s", + identity.cache_key, + exc, + ) + await self._token_store.delete(key) + last_error = exc + continue + if refreshed: + refreshed = refreshed.model_copy( + update={ + "resource": resolved.resource, + "authorization_server": resolved.issuer, + } + ) await self._token_store.set(key, refreshed) return refreshed + await self._token_store.delete(key) - # Need to run full authorization flow - only if no token found or refresh failed - if not record: - resource_hint = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) - server_url = getattr(server_config, "url", None) - resource = normalize_resource(resource_hint, server_url) - - # Get OAuth metadata for full authorization flow - parsed_resource = URL(resource) - metadata_url = str(parsed_resource.copy_with(path="/.well-known/oauth-protected-resource" + parsed_resource.path)) - resource_metadata = await self._get_resource_metadata(metadata_url) - auth_server_url = select_authorization_server( - resource_metadata, str(oauth_config.authorization_server) - ) - auth_metadata = await self._get_authorization_metadata(auth_server_url) - - record = await self._flow.authorize( - context=context, - user=user, - server_name=server_name, - oauth_config=oauth_config, - resource=resource, - authorization_server_url=auth_server_url, - resource_metadata=resource_metadata, - auth_metadata=auth_metadata, - scopes=scope_list, - ) - await self._token_store.set(key, record) - return record + # Only authenticated users (non-default identity) can initiate new flows. + user_identity = context.current_user + if user_identity is None: + if last_error: + raise last_error + raise MissingUserIdentityError( + "No authenticated user available to initiate OAuth authorization flow" + ) + + user_key = self._build_store_key( + user_identity, + resolved.resource, + resolved.issuer, + resolved.scopes, + ) - # If we reach here, we have an expired token with no refresh token - # Return it anyway - the caller will handle 401s + lock = self._locks[user_key] + async with lock: + # Double-check to avoid duplicate authorization while we awaited the lock. + existing = await self._token_store.get(user_key) + if existing and not existing.is_expired(leeway_seconds=leeway): + return existing + + record = await self._flow.authorize( + context=context, + user=user_identity, + server_name=server_name, + oauth_config=oauth_config, + resource=resolved.resource, + authorization_server_url=resolved.authorization_server_url, + resource_metadata=resolved.resource_metadata, + auth_metadata=resolved.authorization_metadata, + scopes=resolved.scopes, + ) + record = record.model_copy( + update={ + "resource": resolved.resource, + "authorization_server": resolved.issuer, + } + ) + await self._token_store.set(user_key, record) return record async def invalidate( @@ -237,14 +437,40 @@ async def invalidate( resource: str, authorization_server: str | None, scopes: Iterable[str], + session_id: str | None = None, ) -> None: - key = TokenStoreKey( - user_key=user.cache_key, - resource=resource, - authorization_server=authorization_server, - scope_fingerprint=scope_fingerprint(scopes), + canonical_resource = normalize_resource(resource, resource) + canonical_auth_server = ( + _canonicalize_url(authorization_server) + if authorization_server + else authorization_server + ) + key = self._build_store_key( + user, + canonical_resource, + canonical_auth_server or "", + tuple(scopes), ) await self._token_store.delete(key) + if user.cache_key != self._default_identity.cache_key and canonical_auth_server: + default_key = self._build_store_key( + self._default_identity, + canonical_resource, + canonical_auth_server, + tuple(scopes), + ) + await self._token_store.delete(default_key) + if session_id: + session_identity = OAuthUserIdentity( + provider="mcp-session", subject=str(session_id) + ) + session_key = self._build_store_key( + session_identity, + canonical_resource, + canonical_auth_server or "", + tuple(scopes), + ) + await self._token_store.delete(session_key) async def _refresh_token( self, @@ -299,7 +525,7 @@ async def _refresh_token( if isinstance(scope_from_payload, str) and scope_from_payload.strip(): scopes_tuple = tuple(scope_from_payload.split()) else: - scopes_tuple = record.scopes + scopes_tuple = tuple(scopes) if scopes else record.scopes return TokenRecord( access_token=new_access, @@ -312,26 +538,128 @@ async def _refresh_token( metadata={"raw": payload}, ) - async def _get_resource_metadata(self, url: str): - cached = self._resource_metadata_cache.get(url) + async def _resolve_oauth_context( + self, + *, + context: "Context", + server_name: str, + server_config, + oauth_config: MCPOAuthClientSettings, + requested_scopes: Iterable[str], + ) -> ResolvedOAuthContext: + resource_hint = ( + str(oauth_config.resource) + if oauth_config.resource + else getattr(server_config, "url", None) + ) + server_url = getattr(server_config, "url", None) + resource = normalize_resource(resource_hint, server_url) + parsed_resource = URL(resource) + + resource_metadata = await self._get_resource_metadata(resource, parsed_resource) + + preferred_auth_server = ( + str(oauth_config.authorization_server) + if oauth_config.authorization_server + else None + ) + authorization_server_url = select_authorization_server( + resource_metadata, preferred_auth_server + ) + parsed_auth_server = URL(authorization_server_url) + authorization_metadata = await self._get_authorization_metadata( + authorization_server_url, parsed_auth_server + ) + + issuer = getattr(authorization_metadata, "issuer", None) + issuer_str = _canonicalize_url(str(issuer or authorization_server_url)) + + scopes_tuple = tuple(requested_scopes or oauth_config.scopes or []) + + return ResolvedOAuthContext( + resource=resource, + resource_metadata=resource_metadata, + authorization_server_url=authorization_server_url, + authorization_metadata=authorization_metadata, + issuer=issuer_str, + scopes=scopes_tuple, + ) + + async def _get_resource_metadata( + self, canonical_resource: str, parsed_resource: URL + ) -> ProtectedResourceMetadata: + cached = self._resource_metadata_cache.get(canonical_resource) if cached and time.time() - cached[0] < 300: return cached[1] - metadata = await fetch_resource_metadata(self._http_client, url) - self._resource_metadata_cache[url] = (time.time(), metadata) - return metadata - async def _get_authorization_metadata(self, url: str): - cached = self._auth_metadata_cache.get(url) + last_exception: Exception | None = None + for url in _candidate_resource_metadata_urls(parsed_resource): + try: + metadata = await fetch_resource_metadata(self._http_client, url) + except httpx.HTTPError as exc: + last_exception = exc + continue + else: + self._resource_metadata_cache[canonical_resource] = ( + time.time(), + metadata, + ) + return metadata + + raise OAuthFlowError( + f"Failed to fetch resource metadata for '{canonical_resource}'" + ) from last_exception + + async def _get_authorization_metadata( + self, authorization_server_url: str, parsed_authorization_server: URL + ) -> OAuthMetadata: + canonical_base = _canonicalize_url(authorization_server_url) + cached = self._auth_metadata_cache.get(canonical_base) if cached and time.time() - cached[0] < 300: return cached[1] - # Construct OAuth authorization server metadata URL - parsed_url = URL(url) - metadata_url = str( - parsed_url.copy_with(path="/.well-known/oauth-authorization-server" + parsed_url.path)) - metadata = await fetch_authorization_server_metadata(self._http_client, metadata_url) - self._auth_metadata_cache[url] = (time.time(), metadata) - return metadata + + last_exception: Exception | None = None + for url in _candidate_authorization_metadata_urls(parsed_authorization_server): + try: + metadata = await fetch_authorization_server_metadata( + self._http_client, url + ) + except httpx.HTTPError as exc: + last_exception = exc + continue + else: + issuer = getattr(metadata, "issuer", None) + cache_key = _canonicalize_url(str(issuer)) if issuer else canonical_base + self._auth_metadata_cache[cache_key] = (time.time(), metadata) + return metadata + + raise OAuthFlowError( + f"Failed to fetch authorization server metadata from '{authorization_server_url}'" + ) from last_exception + + def _build_store_key( + self, + identity: OAuthUserIdentity, + resource: str, + authorization_server: str, + scopes: Sequence[str], + ) -> TokenStoreKey: + return TokenStoreKey( + user_key=identity.cache_key, + resource=resource, + authorization_server=authorization_server, + scope_fingerprint=scope_fingerprint(scopes), + ) async def aclose(self) -> None: if self._own_http_client: await self._http_client.aclose() + close = getattr(self._token_store, "aclose", None) + if callable(close): + await close() + + def _session_identity(self, context: "Context") -> OAuthUserIdentity | None: + session_id = getattr(context, "session_id", None) + if not session_id: + return None + return OAuthUserIdentity(provider="mcp-session", subject=str(session_id)) diff --git a/src/mcp_agent/oauth/metadata.py b/src/mcp_agent/oauth/metadata.py index c4986b011..9c230ca94 100644 --- a/src/mcp_agent/oauth/metadata.py +++ b/src/mcp_agent/oauth/metadata.py @@ -5,6 +5,7 @@ from typing import List import httpx +from httpx import URL from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata from mcp_agent.logging.logger import get_logger @@ -53,8 +54,23 @@ def select_authorization_server( def normalize_resource(resource: str | None, fallback: str | None) -> str: - if resource: - return resource.rstrip("/") - if fallback: - return fallback.rstrip("/") - raise ValueError("Unable to determine resource identifier for OAuth flow") + candidate = resource or fallback + if not candidate: + raise ValueError("Unable to determine resource identifier for OAuth flow") + + parsed = URL(candidate) + if parsed.scheme not in ("http", "https"): + raise ValueError(f"Unsupported resource scheme: {parsed.scheme}") + + host = parsed.host.lower() if parsed.host else parsed.host + path = parsed.path.rstrip("/") + if path == "/": + path = "" + canonical = parsed.copy_with( + scheme=parsed.scheme, + host=host, + path=path, + query=None, + fragment=None, + ) + return str(canonical) diff --git a/src/mcp_agent/oauth/store/__init__.py b/src/mcp_agent/oauth/store/__init__.py index 226953f43..95a9843e1 100644 --- a/src/mcp_agent/oauth/store/__init__.py +++ b/src/mcp_agent/oauth/store/__init__.py @@ -9,3 +9,10 @@ "scope_fingerprint", "InMemoryTokenStore", ] + +try: # Optional dependency + from .redis import RedisTokenStore +except ImportError: # pragma: no cover - redis extra not installed + RedisTokenStore = None # type: ignore[assignment] +else: + __all__.append("RedisTokenStore") diff --git a/src/mcp_agent/oauth/store/redis.py b/src/mcp_agent/oauth/store/redis.py new file mode 100644 index 000000000..742780487 --- /dev/null +++ b/src/mcp_agent/oauth/store/redis.py @@ -0,0 +1,65 @@ +from __future__ import annotations + +import asyncio +import json +from urllib.parse import quote + +from ..records import TokenRecord +from .base import TokenStore, TokenStoreKey + + +class RedisTokenStore(TokenStore): + """Redis-backed token store for multi-instance deployments.""" + + def __init__( + self, + *, + url: str, + prefix: str = "mcp_agent:oauth_tokens", + ) -> None: + try: + import redis.asyncio as redis # type: ignore[import-not-found] + except ImportError as exc: # pragma: no cover - import guard + raise ImportError( + "RedisTokenStore requires the 'redis' optional dependency. " + "Install with `pip install mcp-agent[redis]`." + ) from exc + + if not url: + raise ValueError( + "Redis token store requires a redis_url configuration value" + ) + + self._client = redis.from_url(url, decode_responses=True) + self._prefix = prefix.rstrip(":") + self._lock = asyncio.Lock() + + def _make_key(self, key: TokenStoreKey) -> str: + parts = [ + self._prefix, + quote(key.user_key, safe=""), + quote(key.resource or "", safe=""), + quote(key.authorization_server or "", safe=""), + quote(key.scope_fingerprint or "", safe=""), + ] + return ":".join(parts) + + async def get(self, key: TokenStoreKey) -> TokenRecord | None: + redis_key = self._make_key(key) + payload = await self._client.get(redis_key) + if not payload: + return None + data = json.loads(payload) + return TokenRecord.model_validate(data) + + async def set(self, key: TokenStoreKey, record: TokenRecord) -> None: + async with self._lock: + redis_key = self._make_key(key) + await self._client.set(redis_key, json.dumps(record.model_dump())) + + async def delete(self, key: TokenStoreKey) -> None: + redis_key = self._make_key(key) + await self._client.delete(redis_key) + + async def aclose(self) -> None: + await self._client.close() diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index 9cede9d45..eb7bd3110 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -25,7 +25,6 @@ from mcp_agent.app import MCPApp from mcp_agent.agents.agent import Agent -from mcp_agent.config import MCPOAuthClientSettings from mcp_agent.core.context_dependent import ContextDependent from mcp_agent.executor.workflow import Workflow from mcp_agent.executor.workflow_registry import ( @@ -42,8 +41,8 @@ from mcp_agent.oauth.errors import ( CallbackTimeoutError, ) -from mcp_agent.oauth.manager import create_default_user_for_preconfigured_tokens from mcp_agent.server.token_verifier import MCPAgentTokenVerifier + if TYPE_CHECKING: from mcp_agent.core.context import Context @@ -217,30 +216,12 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: except Exception: identity = None - if not identity: - # Try create identity from session id - try: - session_id = ctx.request_context.request.query_params.get("session_id") - identity = create_default_user_for_preconfigured_tokens(session_id) - except Exception: - identity = None - - if session is not None: - app: MCPApp | None = _get_attached_app(ctx.fastmcp) - if app is not None and getattr(app, "context", None) is not None: - # Set on global app context so the logger can access it - # Previously captured; no need to keep old value - # Use direct assignment for Pydantic model + app: MCPApp | None = _get_attached_app(ctx.fastmcp) + if app is not None and getattr(app, "context", None) is not None: + if session is not None: app.context.upstream_session = session - app.context.current_user = identity - return - else: - return - else: - # Update identity even if we failed to resolve a session - app: MCPApp | None = _get_attached_app(ctx.fastmcp) - if app is not None and getattr(app, "context", None) is not None: - app.context.current_user = identity + # Always overwrite the current user to avoid leaking identities between requests. + app.context.current_user = identity def _resolve_workflows_and_context( @@ -732,7 +713,9 @@ async def _handle_specific_request( elif method == "auth/request": # TODO: special handling of auth request, should be replaced by future URL elicitation class AuthToken(BaseModel): - confirmation: str = Field(description="Please press enter to confirm this message has been received") + confirmation: str = Field( + description="Please press enter to confirm this message has been received" + ) flow_id = params["flow_id"] callback_future = await callback_registry.create_handle(flow_id) @@ -1574,8 +1557,20 @@ async def workflow_pre_auth( if workflow_name not in workflows_dict: raise ToolError(f"Workflow '{workflow_name}' not found.") - if not app_context.token_store: - raise ToolError("Token storage not available.") + if not app_context.token_manager: + raise ToolError("OAuth token manager not available.") + + current_user = app_context.current_user + if current_user is None: + session_id = getattr(app_context, "session_id", None) + if session_id: + current_user = OAuthUserIdentity( + provider="mcp-session", subject=str(session_id) + ) + else: + raise ToolError( + "Authenticated user required for workflow pre-authorization." + ) if not tokens: raise ToolError("At least one token must be provided.") @@ -1606,57 +1601,23 @@ async def workflow_pre_auth( ) continue - server_config = app_context.server_registry.get_server_config(server_name) + server_config = app_context.server_registry.get_server_config( + server_name + ) if not server_config: errors.append( f"Token {i}: server '{server_name}' not recognized" ) continue - oauth_config: MCPOAuthClientSettings | None = None - if server_config and server_config.auth: - oauth_config = getattr(server_config.auth, "oauth", None) - if not oauth_config or not oauth_config.enabled: - errors.append( - f"Token {i}: Server '{server_name}' is not configured for OAuth authentication" - ) - continue - - # Create TokenRecord - from mcp_agent.oauth.records import TokenRecord - from mcp_agent.oauth.store.base import ( - TokenStoreKey, - scope_fingerprint, + await app_context.token_manager.store_user_token( + context=app_context, + user=current_user, + server_name=server_name, + server_config=server_config, + token_data=token_data, + workflow_name=workflow_name, ) - - resource_str = str(oauth_config.resource) if oauth_config.resource \ - else getattr(server_config, "url", None) - auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server \ - else None - scope_list = list(oauth_config.scopes or []) - - token_record = TokenRecord( - access_token=access_token, - refresh_token=token_data.get("refresh_token"), - scopes=tuple(scope_list), - expires_at=token_data.get("expires_at"), - token_type=token_data.get("token_type", "Bearer"), - resource=server_name, - authorization_server=auth_server_str, - metadata={"workflow_name": workflow_name}, - ) - - str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) - # Create storage key using current user - store_key = TokenStoreKey( - user_key=app_context.current_user.cache_key, - resource=resource_str, - authorization_server=auth_server_str, - scope_fingerprint=scope_fingerprint(scope_list), - ) - - # Store the token - await app_context.token_store.set(store_key, token_record) stored_count += 1 except Exception as e: errors.append(f"Token {i}: {str(e)}") diff --git a/tests/test_app_session.py b/tests/test_app_session.py new file mode 100644 index 000000000..5eaec1c30 --- /dev/null +++ b/tests/test_app_session.py @@ -0,0 +1,13 @@ +import pytest + +from mcp_agent.app import MCPApp + + +@pytest.mark.asyncio +async def test_mcp_app_respects_session_id_override(): + app = MCPApp(session_id="resume-session-123") + try: + await app.initialize() + assert app.session_id == "resume-session-123" + finally: + await app.cleanup() diff --git a/tests/test_audience_validation.py b/tests/test_audience_validation.py index 058774fe1..392cf4e18 100644 --- a/tests/test_audience_validation.py +++ b/tests/test_audience_validation.py @@ -88,7 +88,11 @@ async def test_multiple_audiences_extraction(): } audiences = _extract_all_audiences(payload) - expected = {"https://api1.example.com", "https://api2.example.com", "https://api3.example.com"} + expected = { + "https://api1.example.com", + "https://api2.example.com", + "https://api3.example.com", + } assert set(audiences) == expected @@ -141,8 +145,6 @@ def test_configuration_validation(): assert "https://api.example.com" in settings.expected_audiences - - @pytest.mark.asyncio async def test_token_verifier_audience_validation_integration(): """Test full integration of audience validation in token verifier.""" @@ -196,8 +198,6 @@ async def test_token_verifier_audience_validation_integration(): assert token is None - - def test_audience_extraction_edge_cases(): """Test audience extraction handles edge cases properly.""" # Empty payload @@ -209,7 +209,7 @@ def test_audience_extraction_edge_cases(): # Mixed empty and valid values payload = { "aud": ["", "https://valid.com", None], - "resource": ["https://another.com", ""] + "resource": ["https://another.com", ""], } audiences = _extract_all_audiences(payload) expected = {"https://valid.com", "https://another.com"} @@ -218,7 +218,7 @@ def test_audience_extraction_edge_cases(): # Duplicate values should be removed payload = { "aud": ["https://api.com", "https://api.com"], - "resource": "https://api.com" + "resource": "https://api.com", } audiences = _extract_all_audiences(payload) assert audiences == ["https://api.com"] @@ -247,4 +247,4 @@ async def test_partial_audience_match(): token = MCPAccessToken.from_introspection("test_token", payload) # Should succeed because at least one audience matches - assert token.validate_audience(settings.expected_audiences) is True \ No newline at end of file + assert token.validate_audience(settings.expected_audiences) is True diff --git a/tests/test_oauth_utils.py b/tests/test_oauth_utils.py index cd3de139f..36c052318 100644 --- a/tests/test_oauth_utils.py +++ b/tests/test_oauth_utils.py @@ -84,3 +84,7 @@ def test_normalize_resource_with_fallback(): ) with pytest.raises(ValueError): normalize_resource(None, None) + + +def test_normalize_resource_canonicalizes_case(): + assert normalize_resource("https://Example.COM/", None) == "https://example.com" diff --git a/tests/test_token_manager.py b/tests/test_token_manager.py new file mode 100644 index 000000000..422dc37aa --- /dev/null +++ b/tests/test_token_manager.py @@ -0,0 +1,161 @@ +from types import SimpleNamespace +from unittest.mock import AsyncMock + +import pytest +from httpx import URL + +from mcp_agent.config import MCPOAuthClientSettings, OAuthSettings +from mcp_agent.oauth.identity import OAuthUserIdentity, DEFAULT_PRECONFIGURED_IDENTITY +from mcp_agent.oauth.manager import ( + ResolvedOAuthContext, + TokenManager, + _candidate_authorization_metadata_urls, + _candidate_resource_metadata_urls, +) +from mcp_agent.oauth.store import InMemoryTokenStore + + +class DummyServerConfig: + def __init__(self, oauth_config, url="https://api.example.com/mcp"): + self.url = url + self.auth = SimpleNamespace(oauth=oauth_config) + + +class DummyContext: + def __init__( + self, + session_id: str | None, + current_user: OAuthUserIdentity | None, + config=None, + ): + self.session_id = session_id + self.current_user = current_user + self.config = config + + +@pytest.mark.asyncio +async def test_preconfigured_token_lookup_and_invalidation(): + oauth_settings = OAuthSettings( + callback_base_url="http://localhost:8000", + flow_timeout_seconds=300, + ) + store = InMemoryTokenStore() + manager = TokenManager(token_store=store, settings=oauth_settings) + + oauth_config = MCPOAuthClientSettings( + enabled=True, + access_token="preconfigured-token", + authorization_server="https://auth.example.com", + resource="https://api.example.com/mcp", + ) + server_config = DummyServerConfig(oauth_config) + + resolved = ResolvedOAuthContext( + resource="https://api.example.com/mcp", + resource_metadata=SimpleNamespace(), + authorization_server_url="https://auth.example.com", + authorization_metadata=SimpleNamespace(issuer="https://auth.example.com"), + issuer="https://auth.example.com", + scopes=("read",), + ) + + manager._resolve_oauth_context = AsyncMock(return_value=resolved) # type: ignore[attr-defined] + + await manager.store_preconfigured_token( + context=DummyContext(session_id=None, current_user=None), + server_name="github", + server_config=server_config, + ) + + context = DummyContext(session_id="session-1", current_user=None) + token = await manager.ensure_access_token( + context=context, + server_name="github", + server_config=server_config, + ) + assert token.access_token == "preconfigured-token" + + key = manager._build_store_key( + DEFAULT_PRECONFIGURED_IDENTITY, + resolved.resource, + resolved.issuer, + resolved.scopes, + ) + await manager.invalidate( + user=DEFAULT_PRECONFIGURED_IDENTITY, + resource=resolved.resource, + authorization_server=resolved.issuer, + scopes=resolved.scopes, + session_id=context.session_id, + ) + assert await store.get(key) is None + + +@pytest.mark.asyncio +async def test_store_user_token_uses_workflow_and_session_metadata(): + oauth_settings = OAuthSettings( + callback_base_url="http://localhost:8000", + flow_timeout_seconds=300, + ) + store = InMemoryTokenStore() + manager = TokenManager(token_store=store, settings=oauth_settings) + + oauth_config = MCPOAuthClientSettings( + enabled=True, + authorization_server="https://auth.example.com", + resource="https://api.example.com/mcp", + ) + server_config = DummyServerConfig(oauth_config) + + resolved = ResolvedOAuthContext( + resource="https://api.example.com/mcp", + resource_metadata=SimpleNamespace(), + authorization_server_url="https://auth.example.com", + authorization_metadata=SimpleNamespace(issuer="https://auth.example.com"), + issuer="https://auth.example.com", + scopes=("repo",), + ) + manager._resolve_oauth_context = AsyncMock(return_value=resolved) # type: ignore[attr-defined] + + user_identity = OAuthUserIdentity(provider="test", subject="user-123") + token_data = { + "access_token": "token-123", + "scopes": ["repo"], + "expires_at": 0, + } + + context = DummyContext(session_id="session-xyz", current_user=user_identity) + await manager.store_user_token( + context=context, + user=user_identity, + server_name="github", + server_config=server_config, + token_data=token_data, + workflow_name="example_workflow", + ) + + key = manager._build_store_key( + user_identity, + resolved.resource, + resolved.issuer, + resolved.scopes, + ) + stored = await store.get(key) + assert stored is not None + assert stored.access_token == "token-123" + assert stored.metadata.get("workflow_name") == "example_workflow" + assert stored.metadata.get("session_id") == "session-xyz" + + +def test_candidate_resource_metadata_urls(): + parsed = URL("https://api.example.com/mcp") + urls = _candidate_resource_metadata_urls(parsed) + assert urls[0].endswith("/.well-known/oauth-protected-resource/mcp") + assert urls[1].endswith("/.well-known/oauth-protected-resource") + + +def test_candidate_authorization_metadata_urls(): + parsed = URL("https://auth.example.com/tenant") + urls = _candidate_authorization_metadata_urls(parsed) + assert urls[0].endswith("/.well-known/oauth-authorization-server/tenant") + assert urls[1].endswith("/.well-known/oauth-authorization-server") diff --git a/uv.lock b/uv.lock index bdd5be1a8..888ade5a3 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 1 +revision = 3 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.13'", @@ -13,9 +13,9 @@ resolution-markers = [ name = "aiohappyeyeballs" version = "2.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760 } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265 }, + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, ] [[package]] @@ -32,76 +32,76 @@ dependencies = [ { name = "propcache" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/61/d37b33a074ad867d1ecec9f03183e2b9fee067745cae17e73c264f556d57/aiohttp-3.12.0.tar.gz", hash = "sha256:e3f0a2b4d7fb16c0d584d9b8860f1e46d39f7d93372b25a6f80c10015a7acdab", size = 7762804 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/6d/687b42743088d86de83653153d4ef2ddf77372ce46b9d404c8340b9fec00/aiohttp-3.12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91fca62b1a454a72c48345ad3af0327c87a7352598049fd9fd02b5c96deca456", size = 690021 }, - { url = "https://files.pythonhosted.org/packages/66/6d/19bac9bdbaf0893005d61a25898147c781fa78c337d09d989a5216e6422e/aiohttp-3.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4cd2ffa8cefce24305e573780d3d4a1bc8904bb76bc208509108bac04bc85c71", size = 466392 }, - { url = "https://files.pythonhosted.org/packages/1c/0b/3c6327efc64d509b5de1fc9157aa4da555d22154ba21893dee9a169c70dd/aiohttp-3.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b011907c9f024d9b2017a2c12ca8abea571b919ebd85d42f16bd91a716dc7de2", size = 454164 }, - { url = "https://files.pythonhosted.org/packages/97/eb/d536fb2e07d497d6d1c489ed39918d14a444c4fd00557b1d86cf6816dc07/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9c8db3b45fb114739bc3daae85ceb03b2bcb11f11f2d1eae25b00b989cd306a", size = 1636208 }, - { url = "https://files.pythonhosted.org/packages/6d/d7/26760f0596731227cfa3db4f8dc76bda7283de9b6401a5584fcde30e0661/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:976607ee1790d2e6d1666f89f64afd9397af2647b5a99a84dc664a3ac715754f", size = 1610265 }, - { url = "https://files.pythonhosted.org/packages/1a/bd/25a3189e2bacfffbf1099646856ffc1fe4479a2c98c90f3d7bc2c7161130/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e76898841d4e655ac5e7e2f1e146d9e56ee1ffd2ce2dd31b41ab23bcfb29b209", size = 1682672 }, - { url = "https://files.pythonhosted.org/packages/69/00/7ef9722e9d4442ce155c6e6a08f6824f041384b04d92baa60096acb9b1df/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ad61b28652898b25e7c8d42970b9f27f7eff068623704aad4424e2ee9409a80", size = 1724983 }, - { url = "https://files.pythonhosted.org/packages/6b/c3/c6fa242e13281b06acf0a00b6b8a77f44fc28ba78924405508c7f9086ffc/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba8d85d36edc6698ef94cf8f7fcf5992cc2d9b639de67a1112799d5020c91a63", size = 1629649 }, - { url = "https://files.pythonhosted.org/packages/9a/97/bed6b780aa8c7aa14d6676521634e81895e87fb2da1bbf2ae54772478d16/aiohttp-3.12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5123488226a61df4a515dc3d5c3c0b578660ec3c22d2579599ce2e45335655db", size = 1569772 }, - { url = "https://files.pythonhosted.org/packages/c8/df/b34c6b94aee4395268bf7d76ee18f9e45fd652a8bad2cfc5f9f0dc757b26/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a03fb47a954df7fb0d587053e2feafdd5306828fc8a764b456775fc00d2d82a9", size = 1613621 }, - { url = "https://files.pythonhosted.org/packages/97/df/3ce40545a00b2614a33ee1a99d12d4b06cfa090cfa1d06a7e0818309124f/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bf9acc3914c921ea8fb0bcda3d07ece85d09eff035bd7c11cea826aa5dd827a5", size = 1624408 }, - { url = "https://files.pythonhosted.org/packages/4c/9f/25bc921e20901787977e634ce0718637a3cc81e91c5776420c7673328f7c/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c7cfb0b19e775143982e34a472f9da66067c22b66ce7a56e88f851752a467f15", size = 1599861 }, - { url = "https://files.pythonhosted.org/packages/10/97/a656de02fb70db5819f2ab2bc9b7831b774220ed4c4098b5cdb87fcb78d9/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:2eba07f1de9a02920f34761c8b8e375f91fd98304a80ff0287f8e9e2804decf7", size = 1679447 }, - { url = "https://files.pythonhosted.org/packages/ec/79/d77fe1eac6be73c8826cb3ddde134a5b2309b157e6e48875c3665b31242b/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d46d99d028ad4a566f980bc8790099288824212c0f21a275d546be403cbcb7bc", size = 1702687 }, - { url = "https://files.pythonhosted.org/packages/ac/18/29b1ec691bb172244b7619e72ac30814b6b5f6a07ec4b933ee9896bf9659/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0bd190e4c418c1072563dd998ae118dfb588101f60c1af396e5cd42023f29259", size = 1631026 }, - { url = "https://files.pythonhosted.org/packages/13/bc/299a2dbb9f92b6bd4c025ba39704c947e3b406ea65626aa817f9ff8bd087/aiohttp-3.12.0-cp310-cp310-win32.whl", hash = "sha256:709d823cc86d0c3ab4e9b449fefba47a1a8586fe65a00d5fbce393458be9da1c", size = 415301 }, - { url = "https://files.pythonhosted.org/packages/0f/42/88b1162432dbb3e7a8776828d6a096d520f4046f836a2bbfdaa28cfffb1b/aiohttp-3.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:a44b25ade659f8736b0f2c32cfd2b59449defad41c5f1e514b94a338c777226f", size = 438506 }, - { url = "https://files.pythonhosted.org/packages/d9/8c/f2d1c0cb4b859185bb38369180785342ef0ba56328c8cb2a0b7c9ddf8651/aiohttp-3.12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:38ab87bc3c2f2c3861438e537cbd6732d72b73f2b82ea9ba4b214b6aca170ad9", size = 697333 }, - { url = "https://files.pythonhosted.org/packages/6e/d7/65d1de0140b952cc88683cf4f52fe0c29d5c617ee1c5a4b9b40ad43d67c8/aiohttp-3.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8862c9b190854c0ff3f5a3f25abee9ed7641aee6eccdc81aed2c3d427623d3dc", size = 469618 }, - { url = "https://files.pythonhosted.org/packages/35/49/4aaefdfa5aa74bc6276660175664eb6e1e654ae3befe5342abfcbf596ec7/aiohttp-3.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8cd1eb1d5498cc541ce40946e148371e23efefcf48afdaa68f49328d2849f393", size = 457881 }, - { url = "https://files.pythonhosted.org/packages/c2/c5/8eea63458cbf37e8b917cff62a0d5606c5df58b502cd00b03aaf57db6383/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07b7e64a7c325e2d87523e1f8210bdba0e2e159703ad00f75bff336134d8490a", size = 1728063 }, - { url = "https://files.pythonhosted.org/packages/9c/32/70b637ee15e3e72b6b028748a2a46bb555ae91311bf9c266db2e248922b2/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1accf0a2270e1e05b453d1dd0f51f176148eec81306c39da39b7af5b29e1d56b", size = 1676733 }, - { url = "https://files.pythonhosted.org/packages/ba/b0/146f27c6d1565d692c3c9d7ba20af6b794ad43984260ec733f024c26da5a/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c3aaae0180d804b4fe95cee7fe03c2ff362828c5ebb7a8370132957104b6311", size = 1775525 }, - { url = "https://files.pythonhosted.org/packages/10/1b/29707acfc556b9acb2471702623e3c2962569ae5df58e977b356825b65cd/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0ab714799a6fd698715d9fc1d1a546a99288288939506fede60d133dc53328b", size = 1814571 }, - { url = "https://files.pythonhosted.org/packages/da/96/ced0a23a2898aa97facc8aa7dc92e207541811de1c34f30cb4338f57dda1/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b33c67d7db1a4b2df28e5c1e4d8c025db8e4432b3d054db3ea695063cbfc52", size = 1717031 }, - { url = "https://files.pythonhosted.org/packages/5f/8f/25760fca550eaaa8c3759f854eda95e3c3e373d942434939da823211c39e/aiohttp-3.12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3718948668ae986d53bd2c443ffc82e6559de2bec1d66a215c1c5e059d80ff37", size = 1654106 }, - { url = "https://files.pythonhosted.org/packages/ef/26/d81ed27b520c25b5b84102bd6ddbf16154d7b07d12097b3fdad7c5e5df3b/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc9f188d2b864f65b17cee23d7a1923285df0c7b978058b0e2006426700d4c93", size = 1702381 }, - { url = "https://files.pythonhosted.org/packages/3d/51/c0e7dc789cdc7105803099c89e57d8dcfe4671600e3ec0f05ce1fb6954be/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:0851359eeb146690c19d368a1c86acf33dc17535ac8123e25a0eff5f5fa110e1", size = 1697542 }, - { url = "https://files.pythonhosted.org/packages/8a/f4/83d9fff93bbb4b26aeb319bd007c63e87e37655bc63fdfb7b561c663b631/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3fcc1ccd74c932ce6b6fad61e054baa23e6624db8f5a9ec462af023abe5c600d", size = 1677726 }, - { url = "https://files.pythonhosted.org/packages/f7/54/7878850b0d764f82ac9629ca8dc4b44c21e2f771dd1aff51d9c336dd6a64/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:062eaf38763c6b22fcbd47a97ba06952ad7751ed7b054a690cddeed4f50547fe", size = 1771326 }, - { url = "https://files.pythonhosted.org/packages/64/3c/f07536f9f5c9572d91260463e4d132ad225b07a34552a0d0b3f01b3988df/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b19f964b9130d572f0fed752417446ff6622fd1288e8c7860824a0dd57cd8dd5", size = 1791787 }, - { url = "https://files.pythonhosted.org/packages/7e/41/ac33993993b2b0b1e9082b99a72c2a18ab595d53f258aa33d8cdf6ee98cf/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b210c1cdc7f1a45714d17510b7e049ca7b15766b66f8c278a2c73a6021bbc389", size = 1704843 }, - { url = "https://files.pythonhosted.org/packages/6b/3c/b8396363eae9e77a2c605d826e549f2f5d1d79f77b12f17c655e7e3b6a2f/aiohttp-3.12.0-cp311-cp311-win32.whl", hash = "sha256:6859c7ecd01cbcc839476c7d9504a19bf334bbe45715df611d351103945a9d23", size = 414813 }, - { url = "https://files.pythonhosted.org/packages/72/9f/d7bd0442c1af0efd9af493399db1eccafce8c5e47f1600b565e069eaaf99/aiohttp-3.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:0159620f09dd338bab29e7136efd51c971462a5bb69dcdace39a2c581e87c4af", size = 439203 }, - { url = "https://files.pythonhosted.org/packages/a4/83/5cf89e601d565ca18fa8792f5b7393f6f3d80fa26447ee4649232f83a6aa/aiohttp-3.12.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:71fe01ddea2673973f1958c3776da990106e33a02a4a5c708d4bb34717cae712", size = 688428 }, - { url = "https://files.pythonhosted.org/packages/fc/f4/034d086f5dacd94063a6926d17c63094ba32dd4938954beb704a6f90d2a6/aiohttp-3.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9ce499a7ea20925572d52f86cd42e16690f4db2ff56933710bf759cf1ec68212", size = 463055 }, - { url = "https://files.pythonhosted.org/packages/9d/e4/47fccf8b5e6a174228a3e1df7f5c723c3f120e2da6f06cac8df05cac2aa2/aiohttp-3.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:75a7d00e20221b1bb8a04e14dba850596cdafeac10fb112ce7b6ef0ad1f9bd42", size = 455888 }, - { url = "https://files.pythonhosted.org/packages/43/34/8b94b13b80f1a83fef87a4e324067f72e73a9713dae497de9eff0e5754ce/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f9cb8f69371d50ba61f061065d440edcbebf00cb4ef2141465a9e753a00ecb9", size = 1702681 }, - { url = "https://files.pythonhosted.org/packages/f5/aa/1e8b90fbe2bfb1684f4461dc70f05d4235bc7e962d39e0febe6bbeec68f3/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:037a53da5016e8fa33840ecddb2bdc20091d731e0fe866f4f9d9364a94504856", size = 1685327 }, - { url = "https://files.pythonhosted.org/packages/4e/74/f9b801c9b250b9501d3ce28ce3e499cedf77035dfc4d74c7e5488a9980d7/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:851543bb8dd5db048c0b6a7454cae3fd0f618a592cbb70844ec0d548767b5763", size = 1740423 }, - { url = "https://files.pythonhosted.org/packages/b4/24/e848b8493c5597cfd7814e3952e182cb91b3193adcea5967513844e99051/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2688fb204b07c2bffcb12795b6384ec051d927147e0ec542ba3518dd60a86f2f", size = 1786578 }, - { url = "https://files.pythonhosted.org/packages/29/4e/63044dfa4176be5c795db24fdae7233acc1895794c544de9689438923acd/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cbc8604c21a163ee492542b344a4f02797d48d38d335af47490d77c0e15d2ed", size = 1706017 }, - { url = "https://files.pythonhosted.org/packages/aa/0e/2d7f4a0e6f22578b536fd1a22f3b1cf19b8f0f05a6feffcb6fd26ac97ddd/aiohttp-3.12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:754d5fd1a47656592d3b11488652fba567d00c6492e9304ba59255dfee8b856f", size = 1621819 }, - { url = "https://files.pythonhosted.org/packages/70/7e/8d2f3ed654b7a4d7c5c57eec88e2e01a610e16f4a851f033e37115a5c860/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2a613da41e577256d13929bbb4a95cadb570aebeab3914a24fc0056ae843d3c7", size = 1682881 }, - { url = "https://files.pythonhosted.org/packages/e1/a6/bffbecc2e53b63081a958b98291ef11e005c03bc8e353934c7e5ba2e3002/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9c8f9e1de28529751345f1e55cb405f22ff09fb251a1bce7fc7e915d0ee49d1f", size = 1704334 }, - { url = "https://files.pythonhosted.org/packages/36/78/4c420fbda62f50585b9537fca612b4c09af5c0f85419e87082f31440b8d5/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:32c1977f5354fef6b43b98ac830c87bddaafcfb6516c520e3241fef8f3e299e7", size = 1644986 }, - { url = "https://files.pythonhosted.org/packages/b3/88/616f05549e083f7985fa5ca39f7b7ec2bb6921330f31891e164346ce415d/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4ac3e360ab9c1b7893ae5c254a222986162bafa9f981fa85f09bad7b1527fed4", size = 1724548 }, - { url = "https://files.pythonhosted.org/packages/44/a7/bbfc67803bbd7cc3b8b36e98dfabbf0cf3eedd66583a735a1d1ecba182b4/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b3e62337e0a24925fefe638f8dd91be4324ac7f2bbbe9d8d0ae992bd35b2dc45", size = 1752523 }, - { url = "https://files.pythonhosted.org/packages/86/69/b85b4a531669d20b5effcb7ff00dd515cd0530a51db5749de14b1fbc8a34/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7285a756ba23e99f1a24cf41e8440f06a1d2cba595ee2cc1acb854e4262e2075", size = 1712132 }, - { url = "https://files.pythonhosted.org/packages/0e/07/ae3b5ab96caadfa7f2d1e1718ececf9c0dcd05cd2338eb02a9a8de4c772a/aiohttp-3.12.0-cp312-cp312-win32.whl", hash = "sha256:b53cd833233a09d5a22481a7e936bfdce46845e3b09f1b936d383d5c14d39ba6", size = 409548 }, - { url = "https://files.pythonhosted.org/packages/71/bc/e8ce9d8c298f6e5d8517a684eb616089c01c4c8185fec5376b19ac7b72c8/aiohttp-3.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:68e4a94c3bf80e93340d4c9108f57b46b019ca88eddec18bf5c8e1ded463cbef", size = 435645 }, - { url = "https://files.pythonhosted.org/packages/fd/7e/9d27424fadc63f89d9165e7865ecdcf49bd4ce03ed5f453e8fb1300c3ede/aiohttp-3.12.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ab223f5d0bd30f1b419addc4aef37f8d7723027e3d92393281cba97f8529209", size = 682843 }, - { url = "https://files.pythonhosted.org/packages/9d/7e/d8f3b2efbd359138f81121d849c334b6df4bb91805a4e7380f175ea822cf/aiohttp-3.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c5beab804eeff85cfae5c053e0d3bb7a7cdc2756ced50a586c56deb8b8ce16b9", size = 460508 }, - { url = "https://files.pythonhosted.org/packages/90/a2/019f0e33b5d3f201f400075841a31db7014a175d6e805fb13c26d8ff85e2/aiohttp-3.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bb157df65c18f4c84dd2a3b989975076d228866e6c4872220139c385bb0fea3b", size = 452808 }, - { url = "https://files.pythonhosted.org/packages/01/29/54e623c3854326e54744996917919a033ce00313888aa5e5fe2348c8968c/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9dff812b540fd31e08678fb1caed2498c294e0f75262829259588992ca59372", size = 1691620 }, - { url = "https://files.pythonhosted.org/packages/f7/db/eef9360855d3d2218bc38c0a94781324fbb7361b168bc6ccba29d703bb7c/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f4f06d93c08670b8deb6e965578c804eecd85450319f403ed5695e7105ca4f38", size = 1672885 }, - { url = "https://files.pythonhosted.org/packages/a1/c7/ff6153b07cd03358eb0faa7fb5ecc319ec2cdccd9789bf25d2a6c580b653/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc77ef0cd57e669f4835ccced3e374c14a9890ef5b99427c5712d965b1a3dca3", size = 1724952 }, - { url = "https://files.pythonhosted.org/packages/b0/38/b6e7ac5234f0eda7763737460793cb478f0270f73adcf2037f0913c9bf9c/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16acea48107e36eb672530b155be727d701658c8e0132f5c38919431063df1aa", size = 1774327 }, - { url = "https://files.pythonhosted.org/packages/29/ec/a51e3fffd7538e7cc6376b2693c5f15365a542d42045c9345f8571962c3a/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8314272c09dfb3424a3015222b950ca4a0845165fa43528f079a67dd0d98bd56", size = 1696655 }, - { url = "https://files.pythonhosted.org/packages/cd/f8/701e3869d04c6d1b908fcbcb6f41013a3400750c289a494500ed68fe5f5d/aiohttp-3.12.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9b51e1f1fe9ef73e3dc23908586d7ea3aa928da1b44a38f0cb0c3f60cfcfa76", size = 1610360 }, - { url = "https://files.pythonhosted.org/packages/5e/bc/1e36156c126ff0f1cd9af55a2e3bdd71842e4c76006fd6f16adec92f7c50/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:471858b4cb972205fbc46b9485d8d532092df0189dd681869616bbbc7192ead3", size = 1663384 }, - { url = "https://files.pythonhosted.org/packages/71/b2/e79603df4a9916ecca3ef6605d66bc8dc9d1cf94be12b5b948e19eba4a7b/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47d30f5fc30bd9dfe8875374aa05f566719d82e9026839dd5c59f281fb94d302", size = 1695049 }, - { url = "https://files.pythonhosted.org/packages/31/26/6c91957dc52eb47845b5f03901e1162b412c77ac3c0e082b10cf6be7b3ba/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c4ae2aced91b2e879f16d4f0225c7733e007367403a195c2f72d9c01dac4b68", size = 1637644 }, - { url = "https://files.pythonhosted.org/packages/da/9e/ee4b95390cf73ff3875d74e7661378115f763ff445e2d7a0c02f1916db3e/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c2d61673e3eec7f703419ae430417ac84305095220af11524f9496f7c0b81dc6", size = 1713775 }, - { url = "https://files.pythonhosted.org/packages/dd/83/69b8a5a32e48210ce3830ee11044245e283c89adb8e797414145ab1d1a4a/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a08d1c18b588ddfd049f4ac082b9935ee68a3796dc7ad70c8317605a8bd7e298", size = 1747247 }, - { url = "https://files.pythonhosted.org/packages/54/df/4c23861c97384a18a03233629ba423b2cdee450a0fb76354095fdd30cfe5/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33bb4ab2c7b86bf0ef19d426afcc3e60f08415b8e46b9cdb67b632c1d48931a3", size = 1696137 }, - { url = "https://files.pythonhosted.org/packages/92/27/e19dfbcfdbe5f000b2959c4cb1a93c32e8632a36b29b7a01d59251e14b5b/aiohttp-3.12.0-cp313-cp313-win32.whl", hash = "sha256:199bfe20aebba88c94113def5c5f7eb8abeca55caf4dab8060fa25f573f062e5", size = 408567 }, - { url = "https://files.pythonhosted.org/packages/30/88/70f19c1c1714d2b4920a4e675fd5b92ff5162b55d20d04b5ba188f0d623b/aiohttp-3.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:9c24ce9ccfe2c24e391bdd72f3d5ff9c42ed1f8b15f813cb4b4c22e0d5930433", size = 434504 }, +sdist = { url = "https://files.pythonhosted.org/packages/6a/61/d37b33a074ad867d1ecec9f03183e2b9fee067745cae17e73c264f556d57/aiohttp-3.12.0.tar.gz", hash = "sha256:e3f0a2b4d7fb16c0d584d9b8860f1e46d39f7d93372b25a6f80c10015a7acdab", size = 7762804, upload-time = "2025-05-24T22:33:33.318Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/6d/687b42743088d86de83653153d4ef2ddf77372ce46b9d404c8340b9fec00/aiohttp-3.12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91fca62b1a454a72c48345ad3af0327c87a7352598049fd9fd02b5c96deca456", size = 690021, upload-time = "2025-05-24T22:30:13.027Z" }, + { url = "https://files.pythonhosted.org/packages/66/6d/19bac9bdbaf0893005d61a25898147c781fa78c337d09d989a5216e6422e/aiohttp-3.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4cd2ffa8cefce24305e573780d3d4a1bc8904bb76bc208509108bac04bc85c71", size = 466392, upload-time = "2025-05-24T22:30:15.44Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0b/3c6327efc64d509b5de1fc9157aa4da555d22154ba21893dee9a169c70dd/aiohttp-3.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b011907c9f024d9b2017a2c12ca8abea571b919ebd85d42f16bd91a716dc7de2", size = 454164, upload-time = "2025-05-24T22:30:17.852Z" }, + { url = "https://files.pythonhosted.org/packages/97/eb/d536fb2e07d497d6d1c489ed39918d14a444c4fd00557b1d86cf6816dc07/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9c8db3b45fb114739bc3daae85ceb03b2bcb11f11f2d1eae25b00b989cd306a", size = 1636208, upload-time = "2025-05-24T22:30:19.838Z" }, + { url = "https://files.pythonhosted.org/packages/6d/d7/26760f0596731227cfa3db4f8dc76bda7283de9b6401a5584fcde30e0661/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:976607ee1790d2e6d1666f89f64afd9397af2647b5a99a84dc664a3ac715754f", size = 1610265, upload-time = "2025-05-24T22:30:21.704Z" }, + { url = "https://files.pythonhosted.org/packages/1a/bd/25a3189e2bacfffbf1099646856ffc1fe4479a2c98c90f3d7bc2c7161130/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e76898841d4e655ac5e7e2f1e146d9e56ee1ffd2ce2dd31b41ab23bcfb29b209", size = 1682672, upload-time = "2025-05-24T22:30:24.015Z" }, + { url = "https://files.pythonhosted.org/packages/69/00/7ef9722e9d4442ce155c6e6a08f6824f041384b04d92baa60096acb9b1df/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ad61b28652898b25e7c8d42970b9f27f7eff068623704aad4424e2ee9409a80", size = 1724983, upload-time = "2025-05-24T22:30:25.997Z" }, + { url = "https://files.pythonhosted.org/packages/6b/c3/c6fa242e13281b06acf0a00b6b8a77f44fc28ba78924405508c7f9086ffc/aiohttp-3.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba8d85d36edc6698ef94cf8f7fcf5992cc2d9b639de67a1112799d5020c91a63", size = 1629649, upload-time = "2025-05-24T22:30:28.588Z" }, + { url = "https://files.pythonhosted.org/packages/9a/97/bed6b780aa8c7aa14d6676521634e81895e87fb2da1bbf2ae54772478d16/aiohttp-3.12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5123488226a61df4a515dc3d5c3c0b578660ec3c22d2579599ce2e45335655db", size = 1569772, upload-time = "2025-05-24T22:30:31.084Z" }, + { url = "https://files.pythonhosted.org/packages/c8/df/b34c6b94aee4395268bf7d76ee18f9e45fd652a8bad2cfc5f9f0dc757b26/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a03fb47a954df7fb0d587053e2feafdd5306828fc8a764b456775fc00d2d82a9", size = 1613621, upload-time = "2025-05-24T22:30:33.286Z" }, + { url = "https://files.pythonhosted.org/packages/97/df/3ce40545a00b2614a33ee1a99d12d4b06cfa090cfa1d06a7e0818309124f/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bf9acc3914c921ea8fb0bcda3d07ece85d09eff035bd7c11cea826aa5dd827a5", size = 1624408, upload-time = "2025-05-24T22:30:35.703Z" }, + { url = "https://files.pythonhosted.org/packages/4c/9f/25bc921e20901787977e634ce0718637a3cc81e91c5776420c7673328f7c/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c7cfb0b19e775143982e34a472f9da66067c22b66ce7a56e88f851752a467f15", size = 1599861, upload-time = "2025-05-24T22:30:38.179Z" }, + { url = "https://files.pythonhosted.org/packages/10/97/a656de02fb70db5819f2ab2bc9b7831b774220ed4c4098b5cdb87fcb78d9/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:2eba07f1de9a02920f34761c8b8e375f91fd98304a80ff0287f8e9e2804decf7", size = 1679447, upload-time = "2025-05-24T22:30:40.215Z" }, + { url = "https://files.pythonhosted.org/packages/ec/79/d77fe1eac6be73c8826cb3ddde134a5b2309b157e6e48875c3665b31242b/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d46d99d028ad4a566f980bc8790099288824212c0f21a275d546be403cbcb7bc", size = 1702687, upload-time = "2025-05-24T22:30:42.584Z" }, + { url = "https://files.pythonhosted.org/packages/ac/18/29b1ec691bb172244b7619e72ac30814b6b5f6a07ec4b933ee9896bf9659/aiohttp-3.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0bd190e4c418c1072563dd998ae118dfb588101f60c1af396e5cd42023f29259", size = 1631026, upload-time = "2025-05-24T22:30:44.982Z" }, + { url = "https://files.pythonhosted.org/packages/13/bc/299a2dbb9f92b6bd4c025ba39704c947e3b406ea65626aa817f9ff8bd087/aiohttp-3.12.0-cp310-cp310-win32.whl", hash = "sha256:709d823cc86d0c3ab4e9b449fefba47a1a8586fe65a00d5fbce393458be9da1c", size = 415301, upload-time = "2025-05-24T22:30:47.663Z" }, + { url = "https://files.pythonhosted.org/packages/0f/42/88b1162432dbb3e7a8776828d6a096d520f4046f836a2bbfdaa28cfffb1b/aiohttp-3.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:a44b25ade659f8736b0f2c32cfd2b59449defad41c5f1e514b94a338c777226f", size = 438506, upload-time = "2025-05-24T22:30:49.554Z" }, + { url = "https://files.pythonhosted.org/packages/d9/8c/f2d1c0cb4b859185bb38369180785342ef0ba56328c8cb2a0b7c9ddf8651/aiohttp-3.12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:38ab87bc3c2f2c3861438e537cbd6732d72b73f2b82ea9ba4b214b6aca170ad9", size = 697333, upload-time = "2025-05-24T22:30:51.888Z" }, + { url = "https://files.pythonhosted.org/packages/6e/d7/65d1de0140b952cc88683cf4f52fe0c29d5c617ee1c5a4b9b40ad43d67c8/aiohttp-3.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8862c9b190854c0ff3f5a3f25abee9ed7641aee6eccdc81aed2c3d427623d3dc", size = 469618, upload-time = "2025-05-24T22:30:54.168Z" }, + { url = "https://files.pythonhosted.org/packages/35/49/4aaefdfa5aa74bc6276660175664eb6e1e654ae3befe5342abfcbf596ec7/aiohttp-3.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8cd1eb1d5498cc541ce40946e148371e23efefcf48afdaa68f49328d2849f393", size = 457881, upload-time = "2025-05-24T22:30:56.616Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c5/8eea63458cbf37e8b917cff62a0d5606c5df58b502cd00b03aaf57db6383/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07b7e64a7c325e2d87523e1f8210bdba0e2e159703ad00f75bff336134d8490a", size = 1728063, upload-time = "2025-05-24T22:30:58.707Z" }, + { url = "https://files.pythonhosted.org/packages/9c/32/70b637ee15e3e72b6b028748a2a46bb555ae91311bf9c266db2e248922b2/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1accf0a2270e1e05b453d1dd0f51f176148eec81306c39da39b7af5b29e1d56b", size = 1676733, upload-time = "2025-05-24T22:31:01.632Z" }, + { url = "https://files.pythonhosted.org/packages/ba/b0/146f27c6d1565d692c3c9d7ba20af6b794ad43984260ec733f024c26da5a/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c3aaae0180d804b4fe95cee7fe03c2ff362828c5ebb7a8370132957104b6311", size = 1775525, upload-time = "2025-05-24T22:31:03.68Z" }, + { url = "https://files.pythonhosted.org/packages/10/1b/29707acfc556b9acb2471702623e3c2962569ae5df58e977b356825b65cd/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0ab714799a6fd698715d9fc1d1a546a99288288939506fede60d133dc53328b", size = 1814571, upload-time = "2025-05-24T22:31:05.675Z" }, + { url = "https://files.pythonhosted.org/packages/da/96/ced0a23a2898aa97facc8aa7dc92e207541811de1c34f30cb4338f57dda1/aiohttp-3.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b33c67d7db1a4b2df28e5c1e4d8c025db8e4432b3d054db3ea695063cbfc52", size = 1717031, upload-time = "2025-05-24T22:31:07.761Z" }, + { url = "https://files.pythonhosted.org/packages/5f/8f/25760fca550eaaa8c3759f854eda95e3c3e373d942434939da823211c39e/aiohttp-3.12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3718948668ae986d53bd2c443ffc82e6559de2bec1d66a215c1c5e059d80ff37", size = 1654106, upload-time = "2025-05-24T22:31:09.717Z" }, + { url = "https://files.pythonhosted.org/packages/ef/26/d81ed27b520c25b5b84102bd6ddbf16154d7b07d12097b3fdad7c5e5df3b/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc9f188d2b864f65b17cee23d7a1923285df0c7b978058b0e2006426700d4c93", size = 1702381, upload-time = "2025-05-24T22:31:11.812Z" }, + { url = "https://files.pythonhosted.org/packages/3d/51/c0e7dc789cdc7105803099c89e57d8dcfe4671600e3ec0f05ce1fb6954be/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:0851359eeb146690c19d368a1c86acf33dc17535ac8123e25a0eff5f5fa110e1", size = 1697542, upload-time = "2025-05-24T22:31:13.822Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f4/83d9fff93bbb4b26aeb319bd007c63e87e37655bc63fdfb7b561c663b631/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3fcc1ccd74c932ce6b6fad61e054baa23e6624db8f5a9ec462af023abe5c600d", size = 1677726, upload-time = "2025-05-24T22:31:15.865Z" }, + { url = "https://files.pythonhosted.org/packages/f7/54/7878850b0d764f82ac9629ca8dc4b44c21e2f771dd1aff51d9c336dd6a64/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:062eaf38763c6b22fcbd47a97ba06952ad7751ed7b054a690cddeed4f50547fe", size = 1771326, upload-time = "2025-05-24T22:31:17.989Z" }, + { url = "https://files.pythonhosted.org/packages/64/3c/f07536f9f5c9572d91260463e4d132ad225b07a34552a0d0b3f01b3988df/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b19f964b9130d572f0fed752417446ff6622fd1288e8c7860824a0dd57cd8dd5", size = 1791787, upload-time = "2025-05-24T22:31:20.706Z" }, + { url = "https://files.pythonhosted.org/packages/7e/41/ac33993993b2b0b1e9082b99a72c2a18ab595d53f258aa33d8cdf6ee98cf/aiohttp-3.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b210c1cdc7f1a45714d17510b7e049ca7b15766b66f8c278a2c73a6021bbc389", size = 1704843, upload-time = "2025-05-24T22:31:22.947Z" }, + { url = "https://files.pythonhosted.org/packages/6b/3c/b8396363eae9e77a2c605d826e549f2f5d1d79f77b12f17c655e7e3b6a2f/aiohttp-3.12.0-cp311-cp311-win32.whl", hash = "sha256:6859c7ecd01cbcc839476c7d9504a19bf334bbe45715df611d351103945a9d23", size = 414813, upload-time = "2025-05-24T22:31:25.03Z" }, + { url = "https://files.pythonhosted.org/packages/72/9f/d7bd0442c1af0efd9af493399db1eccafce8c5e47f1600b565e069eaaf99/aiohttp-3.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:0159620f09dd338bab29e7136efd51c971462a5bb69dcdace39a2c581e87c4af", size = 439203, upload-time = "2025-05-24T22:31:27.047Z" }, + { url = "https://files.pythonhosted.org/packages/a4/83/5cf89e601d565ca18fa8792f5b7393f6f3d80fa26447ee4649232f83a6aa/aiohttp-3.12.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:71fe01ddea2673973f1958c3776da990106e33a02a4a5c708d4bb34717cae712", size = 688428, upload-time = "2025-05-24T22:31:29.505Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f4/034d086f5dacd94063a6926d17c63094ba32dd4938954beb704a6f90d2a6/aiohttp-3.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9ce499a7ea20925572d52f86cd42e16690f4db2ff56933710bf759cf1ec68212", size = 463055, upload-time = "2025-05-24T22:31:31.314Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e4/47fccf8b5e6a174228a3e1df7f5c723c3f120e2da6f06cac8df05cac2aa2/aiohttp-3.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:75a7d00e20221b1bb8a04e14dba850596cdafeac10fb112ce7b6ef0ad1f9bd42", size = 455888, upload-time = "2025-05-24T22:31:33.238Z" }, + { url = "https://files.pythonhosted.org/packages/43/34/8b94b13b80f1a83fef87a4e324067f72e73a9713dae497de9eff0e5754ce/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f9cb8f69371d50ba61f061065d440edcbebf00cb4ef2141465a9e753a00ecb9", size = 1702681, upload-time = "2025-05-24T22:31:35.724Z" }, + { url = "https://files.pythonhosted.org/packages/f5/aa/1e8b90fbe2bfb1684f4461dc70f05d4235bc7e962d39e0febe6bbeec68f3/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:037a53da5016e8fa33840ecddb2bdc20091d731e0fe866f4f9d9364a94504856", size = 1685327, upload-time = "2025-05-24T22:31:37.849Z" }, + { url = "https://files.pythonhosted.org/packages/4e/74/f9b801c9b250b9501d3ce28ce3e499cedf77035dfc4d74c7e5488a9980d7/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:851543bb8dd5db048c0b6a7454cae3fd0f618a592cbb70844ec0d548767b5763", size = 1740423, upload-time = "2025-05-24T22:31:40.189Z" }, + { url = "https://files.pythonhosted.org/packages/b4/24/e848b8493c5597cfd7814e3952e182cb91b3193adcea5967513844e99051/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2688fb204b07c2bffcb12795b6384ec051d927147e0ec542ba3518dd60a86f2f", size = 1786578, upload-time = "2025-05-24T22:31:43.006Z" }, + { url = "https://files.pythonhosted.org/packages/29/4e/63044dfa4176be5c795db24fdae7233acc1895794c544de9689438923acd/aiohttp-3.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cbc8604c21a163ee492542b344a4f02797d48d38d335af47490d77c0e15d2ed", size = 1706017, upload-time = "2025-05-24T22:31:45.605Z" }, + { url = "https://files.pythonhosted.org/packages/aa/0e/2d7f4a0e6f22578b536fd1a22f3b1cf19b8f0f05a6feffcb6fd26ac97ddd/aiohttp-3.12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:754d5fd1a47656592d3b11488652fba567d00c6492e9304ba59255dfee8b856f", size = 1621819, upload-time = "2025-05-24T22:31:47.752Z" }, + { url = "https://files.pythonhosted.org/packages/70/7e/8d2f3ed654b7a4d7c5c57eec88e2e01a610e16f4a851f033e37115a5c860/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2a613da41e577256d13929bbb4a95cadb570aebeab3914a24fc0056ae843d3c7", size = 1682881, upload-time = "2025-05-24T22:31:49.947Z" }, + { url = "https://files.pythonhosted.org/packages/e1/a6/bffbecc2e53b63081a958b98291ef11e005c03bc8e353934c7e5ba2e3002/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9c8f9e1de28529751345f1e55cb405f22ff09fb251a1bce7fc7e915d0ee49d1f", size = 1704334, upload-time = "2025-05-24T22:31:52.136Z" }, + { url = "https://files.pythonhosted.org/packages/36/78/4c420fbda62f50585b9537fca612b4c09af5c0f85419e87082f31440b8d5/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:32c1977f5354fef6b43b98ac830c87bddaafcfb6516c520e3241fef8f3e299e7", size = 1644986, upload-time = "2025-05-24T22:31:54.787Z" }, + { url = "https://files.pythonhosted.org/packages/b3/88/616f05549e083f7985fa5ca39f7b7ec2bb6921330f31891e164346ce415d/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4ac3e360ab9c1b7893ae5c254a222986162bafa9f981fa85f09bad7b1527fed4", size = 1724548, upload-time = "2025-05-24T22:31:57.369Z" }, + { url = "https://files.pythonhosted.org/packages/44/a7/bbfc67803bbd7cc3b8b36e98dfabbf0cf3eedd66583a735a1d1ecba182b4/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b3e62337e0a24925fefe638f8dd91be4324ac7f2bbbe9d8d0ae992bd35b2dc45", size = 1752523, upload-time = "2025-05-24T22:31:59.552Z" }, + { url = "https://files.pythonhosted.org/packages/86/69/b85b4a531669d20b5effcb7ff00dd515cd0530a51db5749de14b1fbc8a34/aiohttp-3.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7285a756ba23e99f1a24cf41e8440f06a1d2cba595ee2cc1acb854e4262e2075", size = 1712132, upload-time = "2025-05-24T22:32:01.799Z" }, + { url = "https://files.pythonhosted.org/packages/0e/07/ae3b5ab96caadfa7f2d1e1718ececf9c0dcd05cd2338eb02a9a8de4c772a/aiohttp-3.12.0-cp312-cp312-win32.whl", hash = "sha256:b53cd833233a09d5a22481a7e936bfdce46845e3b09f1b936d383d5c14d39ba6", size = 409548, upload-time = "2025-05-24T22:32:03.957Z" }, + { url = "https://files.pythonhosted.org/packages/71/bc/e8ce9d8c298f6e5d8517a684eb616089c01c4c8185fec5376b19ac7b72c8/aiohttp-3.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:68e4a94c3bf80e93340d4c9108f57b46b019ca88eddec18bf5c8e1ded463cbef", size = 435645, upload-time = "2025-05-24T22:32:05.88Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7e/9d27424fadc63f89d9165e7865ecdcf49bd4ce03ed5f453e8fb1300c3ede/aiohttp-3.12.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ab223f5d0bd30f1b419addc4aef37f8d7723027e3d92393281cba97f8529209", size = 682843, upload-time = "2025-05-24T22:32:08.441Z" }, + { url = "https://files.pythonhosted.org/packages/9d/7e/d8f3b2efbd359138f81121d849c334b6df4bb91805a4e7380f175ea822cf/aiohttp-3.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c5beab804eeff85cfae5c053e0d3bb7a7cdc2756ced50a586c56deb8b8ce16b9", size = 460508, upload-time = "2025-05-24T22:32:10.476Z" }, + { url = "https://files.pythonhosted.org/packages/90/a2/019f0e33b5d3f201f400075841a31db7014a175d6e805fb13c26d8ff85e2/aiohttp-3.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bb157df65c18f4c84dd2a3b989975076d228866e6c4872220139c385bb0fea3b", size = 452808, upload-time = "2025-05-24T22:32:12.519Z" }, + { url = "https://files.pythonhosted.org/packages/01/29/54e623c3854326e54744996917919a033ce00313888aa5e5fe2348c8968c/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9dff812b540fd31e08678fb1caed2498c294e0f75262829259588992ca59372", size = 1691620, upload-time = "2025-05-24T22:32:14.635Z" }, + { url = "https://files.pythonhosted.org/packages/f7/db/eef9360855d3d2218bc38c0a94781324fbb7361b168bc6ccba29d703bb7c/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f4f06d93c08670b8deb6e965578c804eecd85450319f403ed5695e7105ca4f38", size = 1672885, upload-time = "2025-05-24T22:32:16.884Z" }, + { url = "https://files.pythonhosted.org/packages/a1/c7/ff6153b07cd03358eb0faa7fb5ecc319ec2cdccd9789bf25d2a6c580b653/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc77ef0cd57e669f4835ccced3e374c14a9890ef5b99427c5712d965b1a3dca3", size = 1724952, upload-time = "2025-05-24T22:32:19.119Z" }, + { url = "https://files.pythonhosted.org/packages/b0/38/b6e7ac5234f0eda7763737460793cb478f0270f73adcf2037f0913c9bf9c/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16acea48107e36eb672530b155be727d701658c8e0132f5c38919431063df1aa", size = 1774327, upload-time = "2025-05-24T22:32:21.884Z" }, + { url = "https://files.pythonhosted.org/packages/29/ec/a51e3fffd7538e7cc6376b2693c5f15365a542d42045c9345f8571962c3a/aiohttp-3.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8314272c09dfb3424a3015222b950ca4a0845165fa43528f079a67dd0d98bd56", size = 1696655, upload-time = "2025-05-24T22:32:24.46Z" }, + { url = "https://files.pythonhosted.org/packages/cd/f8/701e3869d04c6d1b908fcbcb6f41013a3400750c289a494500ed68fe5f5d/aiohttp-3.12.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9b51e1f1fe9ef73e3dc23908586d7ea3aa928da1b44a38f0cb0c3f60cfcfa76", size = 1610360, upload-time = "2025-05-24T22:32:27.204Z" }, + { url = "https://files.pythonhosted.org/packages/5e/bc/1e36156c126ff0f1cd9af55a2e3bdd71842e4c76006fd6f16adec92f7c50/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:471858b4cb972205fbc46b9485d8d532092df0189dd681869616bbbc7192ead3", size = 1663384, upload-time = "2025-05-24T22:32:29.383Z" }, + { url = "https://files.pythonhosted.org/packages/71/b2/e79603df4a9916ecca3ef6605d66bc8dc9d1cf94be12b5b948e19eba4a7b/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47d30f5fc30bd9dfe8875374aa05f566719d82e9026839dd5c59f281fb94d302", size = 1695049, upload-time = "2025-05-24T22:32:31.655Z" }, + { url = "https://files.pythonhosted.org/packages/31/26/6c91957dc52eb47845b5f03901e1162b412c77ac3c0e082b10cf6be7b3ba/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c4ae2aced91b2e879f16d4f0225c7733e007367403a195c2f72d9c01dac4b68", size = 1637644, upload-time = "2025-05-24T22:32:34.419Z" }, + { url = "https://files.pythonhosted.org/packages/da/9e/ee4b95390cf73ff3875d74e7661378115f763ff445e2d7a0c02f1916db3e/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c2d61673e3eec7f703419ae430417ac84305095220af11524f9496f7c0b81dc6", size = 1713775, upload-time = "2025-05-24T22:32:36.718Z" }, + { url = "https://files.pythonhosted.org/packages/dd/83/69b8a5a32e48210ce3830ee11044245e283c89adb8e797414145ab1d1a4a/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a08d1c18b588ddfd049f4ac082b9935ee68a3796dc7ad70c8317605a8bd7e298", size = 1747247, upload-time = "2025-05-24T22:32:39.115Z" }, + { url = "https://files.pythonhosted.org/packages/54/df/4c23861c97384a18a03233629ba423b2cdee450a0fb76354095fdd30cfe5/aiohttp-3.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33bb4ab2c7b86bf0ef19d426afcc3e60f08415b8e46b9cdb67b632c1d48931a3", size = 1696137, upload-time = "2025-05-24T22:32:41.392Z" }, + { url = "https://files.pythonhosted.org/packages/92/27/e19dfbcfdbe5f000b2959c4cb1a93c32e8632a36b29b7a01d59251e14b5b/aiohttp-3.12.0-cp313-cp313-win32.whl", hash = "sha256:199bfe20aebba88c94113def5c5f7eb8abeca55caf4dab8060fa25f573f062e5", size = 408567, upload-time = "2025-05-24T22:32:44.132Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/70f19c1c1714d2b4920a4e675fd5b92ff5162b55d20d04b5ba188f0d623b/aiohttp-3.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:9c24ce9ccfe2c24e391bdd72f3d5ff9c42ed1f8b15f813cb4b4c22e0d5930433", size = 434504, upload-time = "2025-05-24T22:32:46.274Z" }, ] [[package]] @@ -111,18 +111,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "frozenlist" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/b5/6d55e80f6d8a08ce22b982eafa278d823b541c925f11ee774b0b9c43473d/aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54", size = 19424 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/b5/6d55e80f6d8a08ce22b982eafa278d823b541c925f11ee774b0b9c43473d/aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54", size = 19424, upload-time = "2024-12-13T17:10:40.86Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597 }, + { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597, upload-time = "2024-12-13T17:10:38.469Z" }, ] [[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]] @@ -138,9 +138,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/57/fd/8a9332f5baf352c272494a9d359863a53385a208954c1a7251a524071930/anthropic-0.52.0.tar.gz", hash = "sha256:f06bc924d7eb85f8a43fe587b875ff58b410d60251b7dc5f1387b322a35bd67b", size = 229372 } +sdist = { url = "https://files.pythonhosted.org/packages/57/fd/8a9332f5baf352c272494a9d359863a53385a208954c1a7251a524071930/anthropic-0.52.0.tar.gz", hash = "sha256:f06bc924d7eb85f8a43fe587b875ff58b410d60251b7dc5f1387b322a35bd67b", size = 229372, upload-time = "2025-05-22T16:42:22.044Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/43/172c0031654908bbac2a87d356fff4de1b4947a9b14b9658540b69416417/anthropic-0.52.0-py3-none-any.whl", hash = "sha256:c026daa164f0e3bde36ce9cbdd27f5f1419fff03306be1e138726f42e6a7810f", size = 286076 }, + { url = "https://files.pythonhosted.org/packages/a0/43/172c0031654908bbac2a87d356fff4de1b4947a9b14b9658540b69416417/anthropic-0.52.0-py3-none-any.whl", hash = "sha256:c026daa164f0e3bde36ce9cbdd27f5f1419fff03306be1e138726f42e6a7810f", size = 286076, upload-time = "2025-05-22T16:42:20Z" }, ] [package.optional-dependencies] @@ -162,18 +162,18 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949 } +sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 }, + { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" }, ] [[package]] name = "appdirs" version = "1.4.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/d8/05696357e0311f5b5c316d7b95f46c669dd9c15aaeecbb48c7d0aeb88c40/appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", size = 13470 } +sdist = { url = "https://files.pythonhosted.org/packages/d7/d8/05696357e0311f5b5c316d7b95f46c669dd9c15aaeecbb48c7d0aeb88c40/appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", size = 13470, upload-time = "2020-05-11T07:59:51.037Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128", size = 9566 }, + { url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128", size = 9566, upload-time = "2020-05-11T07:59:49.499Z" }, ] [[package]] @@ -183,36 +183,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/29/38/b3395cc9ad1b56d2ddac9970bc8f4141312dbaec28bc7c218b0dfafd0f42/asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590", size = 35186 } +sdist = { url = "https://files.pythonhosted.org/packages/29/38/b3395cc9ad1b56d2ddac9970bc8f4141312dbaec28bc7c218b0dfafd0f42/asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590", size = 35186, upload-time = "2024-03-22T14:39:36.863Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828 }, + { url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828, upload-time = "2024-03-22T14:39:34.521Z" }, ] [[package]] name = "asttokens" version = "3.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978 } +sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918 }, + { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" }, ] [[package]] name = "async-timeout" version = "4.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345 } +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/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721 }, + { 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 = "attrs" version = "25.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032 } +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/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815 }, + { 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]] @@ -226,9 +226,9 @@ dependencies = [ { name = "requests" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e8/46/1071f1a190b2397874cb4bf6be4daddc2aa3f83618d27e1e83df89a32c29/auth0_python-4.9.0.tar.gz", hash = "sha256:f9b31ea9c906d0a123b9cdc6ccd7bbbb8156123f44789b08571c45947fb21238", size = 75870 } +sdist = { url = "https://files.pythonhosted.org/packages/e8/46/1071f1a190b2397874cb4bf6be4daddc2aa3f83618d27e1e83df89a32c29/auth0_python-4.9.0.tar.gz", hash = "sha256:f9b31ea9c906d0a123b9cdc6ccd7bbbb8156123f44789b08571c45947fb21238", size = 75870, upload-time = "2025-04-01T09:31:37.403Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/d1/800ab8dfe15f00836b8d1ea41f68f5e4731a96e8fc19548993996f3b5728/auth0_python-4.9.0-py3-none-any.whl", hash = "sha256:6440c7f74dfd669d9f5cdfe9bb44c4c3b230ce98a82353f55a387e90241fbf5b", size = 135349 }, + { url = "https://files.pythonhosted.org/packages/ac/d1/800ab8dfe15f00836b8d1ea41f68f5e4731a96e8fc19548993996f3b5728/auth0_python-4.9.0-py3-none-any.whl", hash = "sha256:6440c7f74dfd669d9f5cdfe9bb44c4c3b230ce98a82353f55a387e90241fbf5b", size = 135349, upload-time = "2025-04-01T09:31:35.538Z" }, ] [[package]] @@ -240,9 +240,9 @@ dependencies = [ { name = "isodate" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/6a/ed85592e5c64e08c291992f58b1a94dab6869f28fb0f40fd753dced73ba6/azure_ai_inference-1.0.0b9.tar.gz", hash = "sha256:1feb496bd84b01ee2691befc04358fa25d7c344d8288e99364438859ad7cd5a4", size = 182408 } +sdist = { url = "https://files.pythonhosted.org/packages/4e/6a/ed85592e5c64e08c291992f58b1a94dab6869f28fb0f40fd753dced73ba6/azure_ai_inference-1.0.0b9.tar.gz", hash = "sha256:1feb496bd84b01ee2691befc04358fa25d7c344d8288e99364438859ad7cd5a4", size = 182408, upload-time = "2025-02-15T00:37:28.464Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4f/0f/27520da74769db6e58327d96c98e7b9a07ce686dff582c9a5ec60b03f9dd/azure_ai_inference-1.0.0b9-py3-none-any.whl", hash = "sha256:49823732e674092dad83bb8b0d1b65aa73111fab924d61349eb2a8cdc0493990", size = 124885 }, + { url = "https://files.pythonhosted.org/packages/4f/0f/27520da74769db6e58327d96c98e7b9a07ce686dff582c9a5ec60b03f9dd/azure_ai_inference-1.0.0b9-py3-none-any.whl", hash = "sha256:49823732e674092dad83bb8b0d1b65aa73111fab924d61349eb2a8cdc0493990", size = 124885, upload-time = "2025-02-15T00:37:29.964Z" }, ] [[package]] @@ -254,9 +254,9 @@ dependencies = [ { name = "six" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/29/ff7a519a315e41c85bab92a7478c6acd1cf0b14353139a08caee4c691f77/azure_core-1.34.0.tar.gz", hash = "sha256:bdb544989f246a0ad1c85d72eeb45f2f835afdcbc5b45e43f0dbde7461c81ece", size = 297999 } +sdist = { url = "https://files.pythonhosted.org/packages/c9/29/ff7a519a315e41c85bab92a7478c6acd1cf0b14353139a08caee4c691f77/azure_core-1.34.0.tar.gz", hash = "sha256:bdb544989f246a0ad1c85d72eeb45f2f835afdcbc5b45e43f0dbde7461c81ece", size = 297999, upload-time = "2025-05-01T23:17:27.59Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/9e/5c87b49f65bb16571599bc789857d0ded2f53014d3392bc88a5d1f3ad779/azure_core-1.34.0-py3-none-any.whl", hash = "sha256:0615d3b756beccdb6624d1c0ae97284f38b78fb59a2a9839bf927c66fbbdddd6", size = 207409 }, + { url = "https://files.pythonhosted.org/packages/84/9e/5c87b49f65bb16571599bc789857d0ded2f53014d3392bc88a5d1f3ad779/azure_core-1.34.0-py3-none-any.whl", hash = "sha256:0615d3b756beccdb6624d1c0ae97284f38b78fb59a2a9839bf927c66fbbdddd6", size = 207409, upload-time = "2025-05-01T23:17:29.818Z" }, ] [[package]] @@ -270,85 +270,85 @@ dependencies = [ { name = "msal-extensions" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/41/52/458c1be17a5d3796570ae2ed3c6b7b55b134b22d5ef8132b4f97046a9051/azure_identity-1.23.0.tar.gz", hash = "sha256:d9cdcad39adb49d4bb2953a217f62aec1f65bbb3c63c9076da2be2a47e53dde4", size = 265280 } +sdist = { url = "https://files.pythonhosted.org/packages/41/52/458c1be17a5d3796570ae2ed3c6b7b55b134b22d5ef8132b4f97046a9051/azure_identity-1.23.0.tar.gz", hash = "sha256:d9cdcad39adb49d4bb2953a217f62aec1f65bbb3c63c9076da2be2a47e53dde4", size = 265280, upload-time = "2025-05-14T00:18:30.408Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/16/a51d47780f41e4b87bb2d454df6aea90a44a346e918ac189d3700f3d728d/azure_identity-1.23.0-py3-none-any.whl", hash = "sha256:dbbeb64b8e5eaa81c44c565f264b519ff2de7ff0e02271c49f3cb492762a50b0", size = 186097 }, + { url = "https://files.pythonhosted.org/packages/07/16/a51d47780f41e4b87bb2d454df6aea90a44a346e918ac189d3700f3d728d/azure_identity-1.23.0-py3-none-any.whl", hash = "sha256:dbbeb64b8e5eaa81c44c565f264b519ff2de7ff0e02271c49f3cb492762a50b0", size = 186097, upload-time = "2025-05-14T00:18:32.734Z" }, ] [[package]] name = "backoff" version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/47/d7/5bbeb12c44d7c4f2fb5b56abce497eb5ed9f34d85701de869acedd602619/backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", size = 17001 } +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/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148 }, + { 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 = "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 }, +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/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 = "blinker" version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460 } +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460, upload-time = "2024-11-08T17:25:47.436Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458 }, + { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, ] [[package]] @@ -360,9 +360,9 @@ dependencies = [ { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/40/73/3f67417985007b385adab61dd9d251cf82d409ce5397ec7d067274b09492/boto3-1.38.23.tar.gz", hash = "sha256:bcf73aca469add09e165b8793be18e7578db8d2604d82505ab13dc2495bad982", size = 111806 } +sdist = { url = "https://files.pythonhosted.org/packages/40/73/3f67417985007b385adab61dd9d251cf82d409ce5397ec7d067274b09492/boto3-1.38.23.tar.gz", hash = "sha256:bcf73aca469add09e165b8793be18e7578db8d2604d82505ab13dc2495bad982", size = 111806, upload-time = "2025-05-23T19:25:26.212Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/f5/9114596c6a4f5e4dade83fbdd271b9572367abdce73b9c7d27142e9e66c3/boto3-1.38.23-py3-none-any.whl", hash = "sha256:70ab8364f1f6f0a7e0eaf97f62fbdacf9c1e4cc1de330faf1c146ef9ab01e7d0", size = 139938 }, + { url = "https://files.pythonhosted.org/packages/e4/f5/9114596c6a4f5e4dade83fbdd271b9572367abdce73b9c7d27142e9e66c3/boto3-1.38.23-py3-none-any.whl", hash = "sha256:70ab8364f1f6f0a7e0eaf97f62fbdacf9c1e4cc1de330faf1c146ef9ab01e7d0", size = 139938, upload-time = "2025-05-23T19:25:24.158Z" }, ] [[package]] @@ -374,9 +374,9 @@ dependencies = [ { name = "types-s3transfer" }, { name = "typing-extensions", marker = "python_full_version < '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/e6/ef30f5f599501ecc1ba0dd157e0a5060ca31767d071872b4f4eee07f5d93/boto3_stubs-1.38.23.tar.gz", hash = "sha256:f7632c193f06828b984d7e2bcfbc8c5eca8066ed390a235ad9f35f72307512bc", size = 99083 } +sdist = { url = "https://files.pythonhosted.org/packages/2f/e6/ef30f5f599501ecc1ba0dd157e0a5060ca31767d071872b4f4eee07f5d93/boto3_stubs-1.38.23.tar.gz", hash = "sha256:f7632c193f06828b984d7e2bcfbc8c5eca8066ed390a235ad9f35f72307512bc", size = 99083, upload-time = "2025-05-23T19:26:36.907Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/9c/e6ca48614f64b70e314a34b8c4a6309ac28f6dbb27492e3b20aad18f7aa6/boto3_stubs-1.38.23-py3-none-any.whl", hash = "sha256:fb6f97862fa67f8c3052a936ef4e012880a6c0719fce5b94b24e205c300c24dd", size = 68665 }, + { url = "https://files.pythonhosted.org/packages/86/9c/e6ca48614f64b70e314a34b8c4a6309ac28f6dbb27492e3b20aad18f7aa6/boto3_stubs-1.38.23-py3-none-any.whl", hash = "sha256:fb6f97862fa67f8c3052a936ef4e012880a6c0719fce5b94b24e205c300c24dd", size = 68665, upload-time = "2025-05-23T19:26:28.486Z" }, ] [package.optional-dependencies] @@ -393,9 +393,9 @@ dependencies = [ { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4d/d5/134a28a30cb1b0c9aa08ceb5d1a3e7afe956f7fa7abad2adda7c5c01d6a1/botocore-1.38.23.tar.gz", hash = "sha256:29685c91050a870c3809238dc5da1ac65a48a3a20b4bca46b6057dcb6b39c72a", size = 13908529 } +sdist = { url = "https://files.pythonhosted.org/packages/4d/d5/134a28a30cb1b0c9aa08ceb5d1a3e7afe956f7fa7abad2adda7c5c01d6a1/botocore-1.38.23.tar.gz", hash = "sha256:29685c91050a870c3809238dc5da1ac65a48a3a20b4bca46b6057dcb6b39c72a", size = 13908529, upload-time = "2025-05-23T19:25:15.199Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/dd/e047894efa3a39509f8fcc103dd096999aa52907c969d195af6b0d8e282f/botocore-1.38.23-py3-none-any.whl", hash = "sha256:a7f818672f10d7a080c2c4558428011c3e0abc1039a047d27ac76ec846158457", size = 13567446 }, + { url = "https://files.pythonhosted.org/packages/ab/dd/e047894efa3a39509f8fcc103dd096999aa52907c969d195af6b0d8e282f/botocore-1.38.23-py3-none-any.whl", hash = "sha256:a7f818672f10d7a080c2c4558428011c3e0abc1039a047d27ac76ec846158457", size = 13567446, upload-time = "2025-05-23T19:25:10.795Z" }, ] [[package]] @@ -405,9 +405,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "types-awscrt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/43/70/6204c97f8d8362364f11c16085566abdcaa114c264d3a4d709ff697b203b/botocore_stubs-1.38.19.tar.gz", hash = "sha256:84f67a42bb240a8ea0c5fe4f05d497cc411177db600bc7012182e499ac24bf19", size = 42269 } +sdist = { url = "https://files.pythonhosted.org/packages/43/70/6204c97f8d8362364f11c16085566abdcaa114c264d3a4d709ff697b203b/botocore_stubs-1.38.19.tar.gz", hash = "sha256:84f67a42bb240a8ea0c5fe4f05d497cc411177db600bc7012182e499ac24bf19", size = 42269, upload-time = "2025-05-19T20:18:13.556Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/ce/28b143452c22b678678d832bf8b41218e3d319bf94062b48c28fe5d81163/botocore_stubs-1.38.19-py3-none-any.whl", hash = "sha256:66fd7d231c21134a12acbe313ef7a6b152cbf9bfd7bfa12a62f8c33e94737e26", size = 65603 }, + { url = "https://files.pythonhosted.org/packages/b4/ce/28b143452c22b678678d832bf8b41218e3d319bf94062b48c28fe5d81163/botocore_stubs-1.38.19-py3-none-any.whl", hash = "sha256:66fd7d231c21134a12acbe313ef7a6b152cbf9bfd7bfa12a62f8c33e94737e26", size = 65603, upload-time = "2025-05-19T20:18:10.445Z" }, ] [[package]] @@ -421,27 +421,27 @@ dependencies = [ { 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 } +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/84/c2/80633736cd183ee4a62107413def345f7e6e3c01563dbca1417363cf957e/build-1.2.2.post1-py3-none-any.whl", hash = "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", size = 22950 }, + { 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 = "cachetools" version = "5.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380 } +sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380, upload-time = "2025-02-20T21:01:19.524Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080 }, + { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080, upload-time = "2025-02-20T21:01:16.647Z" }, ] [[package]] name = "certifi" version = "2025.4.26" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705 } +sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618 }, + { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, ] [[package]] @@ -451,124 +451,124 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } -wheels = [ - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, - { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, - { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, +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/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 = "cfgv" version = "3.4.0" 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/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/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, + { 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 = "charset-normalizer" version = "3.4.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/95/28/9901804da60055b406e1a1c5ba7aac1276fb77f1dde635aabfc7fd84b8ab/charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941", size = 201818 }, - { url = "https://files.pythonhosted.org/packages/d9/9b/892a8c8af9110935e5adcbb06d9c6fe741b6bb02608c6513983048ba1a18/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd", size = 144649 }, - { url = "https://files.pythonhosted.org/packages/7b/a5/4179abd063ff6414223575e008593861d62abfc22455b5d1a44995b7c101/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6", size = 155045 }, - { url = "https://files.pythonhosted.org/packages/3b/95/bc08c7dfeddd26b4be8c8287b9bb055716f31077c8b0ea1cd09553794665/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d", size = 147356 }, - { url = "https://files.pythonhosted.org/packages/a8/2d/7a5b635aa65284bf3eab7653e8b4151ab420ecbae918d3e359d1947b4d61/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86", size = 149471 }, - { url = "https://files.pythonhosted.org/packages/ae/38/51fc6ac74251fd331a8cfdb7ec57beba8c23fd5493f1050f71c87ef77ed0/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c", size = 151317 }, - { url = "https://files.pythonhosted.org/packages/b7/17/edee1e32215ee6e9e46c3e482645b46575a44a2d72c7dfd49e49f60ce6bf/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0", size = 146368 }, - { url = "https://files.pythonhosted.org/packages/26/2c/ea3e66f2b5f21fd00b2825c94cafb8c326ea6240cd80a91eb09e4a285830/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef", size = 154491 }, - { url = "https://files.pythonhosted.org/packages/52/47/7be7fa972422ad062e909fd62460d45c3ef4c141805b7078dbab15904ff7/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6", size = 157695 }, - { url = "https://files.pythonhosted.org/packages/2f/42/9f02c194da282b2b340f28e5fb60762de1151387a36842a92b533685c61e/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366", size = 154849 }, - { url = "https://files.pythonhosted.org/packages/67/44/89cacd6628f31fb0b63201a618049be4be2a7435a31b55b5eb1c3674547a/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db", size = 150091 }, - { url = "https://files.pythonhosted.org/packages/1f/79/4b8da9f712bc079c0f16b6d67b099b0b8d808c2292c937f267d816ec5ecc/charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a", size = 98445 }, - { url = "https://files.pythonhosted.org/packages/7d/d7/96970afb4fb66497a40761cdf7bd4f6fca0fc7bafde3a84f836c1f57a926/charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509", size = 105782 }, - { url = "https://files.pythonhosted.org/packages/05/85/4c40d00dcc6284a1c1ad5de5e0996b06f39d8232f1031cd23c2f5c07ee86/charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2", size = 198794 }, - { url = "https://files.pythonhosted.org/packages/41/d9/7a6c0b9db952598e97e93cbdfcb91bacd89b9b88c7c983250a77c008703c/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645", size = 142846 }, - { url = "https://files.pythonhosted.org/packages/66/82/a37989cda2ace7e37f36c1a8ed16c58cf48965a79c2142713244bf945c89/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd", size = 153350 }, - { url = "https://files.pythonhosted.org/packages/df/68/a576b31b694d07b53807269d05ec3f6f1093e9545e8607121995ba7a8313/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8", size = 145657 }, - { url = "https://files.pythonhosted.org/packages/92/9b/ad67f03d74554bed3aefd56fe836e1623a50780f7c998d00ca128924a499/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f", size = 147260 }, - { url = "https://files.pythonhosted.org/packages/a6/e6/8aebae25e328160b20e31a7e9929b1578bbdc7f42e66f46595a432f8539e/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7", size = 149164 }, - { url = "https://files.pythonhosted.org/packages/8b/f2/b3c2f07dbcc248805f10e67a0262c93308cfa149a4cd3d1fe01f593e5fd2/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9", size = 144571 }, - { url = "https://files.pythonhosted.org/packages/60/5b/c3f3a94bc345bc211622ea59b4bed9ae63c00920e2e8f11824aa5708e8b7/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544", size = 151952 }, - { url = "https://files.pythonhosted.org/packages/e2/4d/ff460c8b474122334c2fa394a3f99a04cf11c646da895f81402ae54f5c42/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82", size = 155959 }, - { url = "https://files.pythonhosted.org/packages/a2/2b/b964c6a2fda88611a1fe3d4c400d39c66a42d6c169c924818c848f922415/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0", size = 153030 }, - { url = "https://files.pythonhosted.org/packages/59/2e/d3b9811db26a5ebf444bc0fa4f4be5aa6d76fc6e1c0fd537b16c14e849b6/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5", size = 148015 }, - { url = "https://files.pythonhosted.org/packages/90/07/c5fd7c11eafd561bb51220d600a788f1c8d77c5eef37ee49454cc5c35575/charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a", size = 98106 }, - { url = "https://files.pythonhosted.org/packages/a8/05/5e33dbef7e2f773d672b6d79f10ec633d4a71cd96db6673625838a4fd532/charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28", size = 105402 }, - { url = "https://files.pythonhosted.org/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", size = 199936 }, - { url = "https://files.pythonhosted.org/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", size = 143790 }, - { url = "https://files.pythonhosted.org/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", size = 153924 }, - { url = "https://files.pythonhosted.org/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", size = 146626 }, - { url = "https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", size = 148567 }, - { url = "https://files.pythonhosted.org/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", size = 150957 }, - { url = "https://files.pythonhosted.org/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", size = 145408 }, - { url = "https://files.pythonhosted.org/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", size = 153399 }, - { url = "https://files.pythonhosted.org/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", size = 156815 }, - { url = "https://files.pythonhosted.org/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", size = 154537 }, - { url = "https://files.pythonhosted.org/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", size = 149565 }, - { url = "https://files.pythonhosted.org/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", size = 98357 }, - { url = "https://files.pythonhosted.org/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", size = 105776 }, - { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622 }, - { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435 }, - { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653 }, - { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231 }, - { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243 }, - { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442 }, - { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147 }, - { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057 }, - { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454 }, - { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174 }, - { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166 }, - { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064 }, - { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641 }, - { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626 }, +sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367, upload-time = "2025-05-02T08:34:42.01Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/28/9901804da60055b406e1a1c5ba7aac1276fb77f1dde635aabfc7fd84b8ab/charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941", size = 201818, upload-time = "2025-05-02T08:31:46.725Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9b/892a8c8af9110935e5adcbb06d9c6fe741b6bb02608c6513983048ba1a18/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd", size = 144649, upload-time = "2025-05-02T08:31:48.889Z" }, + { url = "https://files.pythonhosted.org/packages/7b/a5/4179abd063ff6414223575e008593861d62abfc22455b5d1a44995b7c101/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6", size = 155045, upload-time = "2025-05-02T08:31:50.757Z" }, + { url = "https://files.pythonhosted.org/packages/3b/95/bc08c7dfeddd26b4be8c8287b9bb055716f31077c8b0ea1cd09553794665/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d", size = 147356, upload-time = "2025-05-02T08:31:52.634Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2d/7a5b635aa65284bf3eab7653e8b4151ab420ecbae918d3e359d1947b4d61/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86", size = 149471, upload-time = "2025-05-02T08:31:56.207Z" }, + { url = "https://files.pythonhosted.org/packages/ae/38/51fc6ac74251fd331a8cfdb7ec57beba8c23fd5493f1050f71c87ef77ed0/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c", size = 151317, upload-time = "2025-05-02T08:31:57.613Z" }, + { url = "https://files.pythonhosted.org/packages/b7/17/edee1e32215ee6e9e46c3e482645b46575a44a2d72c7dfd49e49f60ce6bf/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0", size = 146368, upload-time = "2025-05-02T08:31:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/26/2c/ea3e66f2b5f21fd00b2825c94cafb8c326ea6240cd80a91eb09e4a285830/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef", size = 154491, upload-time = "2025-05-02T08:32:01.219Z" }, + { url = "https://files.pythonhosted.org/packages/52/47/7be7fa972422ad062e909fd62460d45c3ef4c141805b7078dbab15904ff7/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6", size = 157695, upload-time = "2025-05-02T08:32:03.045Z" }, + { url = "https://files.pythonhosted.org/packages/2f/42/9f02c194da282b2b340f28e5fb60762de1151387a36842a92b533685c61e/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366", size = 154849, upload-time = "2025-05-02T08:32:04.651Z" }, + { url = "https://files.pythonhosted.org/packages/67/44/89cacd6628f31fb0b63201a618049be4be2a7435a31b55b5eb1c3674547a/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db", size = 150091, upload-time = "2025-05-02T08:32:06.719Z" }, + { url = "https://files.pythonhosted.org/packages/1f/79/4b8da9f712bc079c0f16b6d67b099b0b8d808c2292c937f267d816ec5ecc/charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a", size = 98445, upload-time = "2025-05-02T08:32:08.66Z" }, + { url = "https://files.pythonhosted.org/packages/7d/d7/96970afb4fb66497a40761cdf7bd4f6fca0fc7bafde3a84f836c1f57a926/charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509", size = 105782, upload-time = "2025-05-02T08:32:10.46Z" }, + { url = "https://files.pythonhosted.org/packages/05/85/4c40d00dcc6284a1c1ad5de5e0996b06f39d8232f1031cd23c2f5c07ee86/charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2", size = 198794, upload-time = "2025-05-02T08:32:11.945Z" }, + { url = "https://files.pythonhosted.org/packages/41/d9/7a6c0b9db952598e97e93cbdfcb91bacd89b9b88c7c983250a77c008703c/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645", size = 142846, upload-time = "2025-05-02T08:32:13.946Z" }, + { url = "https://files.pythonhosted.org/packages/66/82/a37989cda2ace7e37f36c1a8ed16c58cf48965a79c2142713244bf945c89/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd", size = 153350, upload-time = "2025-05-02T08:32:15.873Z" }, + { url = "https://files.pythonhosted.org/packages/df/68/a576b31b694d07b53807269d05ec3f6f1093e9545e8607121995ba7a8313/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8", size = 145657, upload-time = "2025-05-02T08:32:17.283Z" }, + { url = "https://files.pythonhosted.org/packages/92/9b/ad67f03d74554bed3aefd56fe836e1623a50780f7c998d00ca128924a499/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f", size = 147260, upload-time = "2025-05-02T08:32:18.807Z" }, + { url = "https://files.pythonhosted.org/packages/a6/e6/8aebae25e328160b20e31a7e9929b1578bbdc7f42e66f46595a432f8539e/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7", size = 149164, upload-time = "2025-05-02T08:32:20.333Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f2/b3c2f07dbcc248805f10e67a0262c93308cfa149a4cd3d1fe01f593e5fd2/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9", size = 144571, upload-time = "2025-05-02T08:32:21.86Z" }, + { url = "https://files.pythonhosted.org/packages/60/5b/c3f3a94bc345bc211622ea59b4bed9ae63c00920e2e8f11824aa5708e8b7/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544", size = 151952, upload-time = "2025-05-02T08:32:23.434Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4d/ff460c8b474122334c2fa394a3f99a04cf11c646da895f81402ae54f5c42/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82", size = 155959, upload-time = "2025-05-02T08:32:24.993Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/b964c6a2fda88611a1fe3d4c400d39c66a42d6c169c924818c848f922415/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0", size = 153030, upload-time = "2025-05-02T08:32:26.435Z" }, + { url = "https://files.pythonhosted.org/packages/59/2e/d3b9811db26a5ebf444bc0fa4f4be5aa6d76fc6e1c0fd537b16c14e849b6/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5", size = 148015, upload-time = "2025-05-02T08:32:28.376Z" }, + { url = "https://files.pythonhosted.org/packages/90/07/c5fd7c11eafd561bb51220d600a788f1c8d77c5eef37ee49454cc5c35575/charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a", size = 98106, upload-time = "2025-05-02T08:32:30.281Z" }, + { url = "https://files.pythonhosted.org/packages/a8/05/5e33dbef7e2f773d672b6d79f10ec633d4a71cd96db6673625838a4fd532/charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28", size = 105402, upload-time = "2025-05-02T08:32:32.191Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", size = 199936, upload-time = "2025-05-02T08:32:33.712Z" }, + { url = "https://files.pythonhosted.org/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", size = 143790, upload-time = "2025-05-02T08:32:35.768Z" }, + { url = "https://files.pythonhosted.org/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", size = 153924, upload-time = "2025-05-02T08:32:37.284Z" }, + { url = "https://files.pythonhosted.org/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", size = 146626, upload-time = "2025-05-02T08:32:38.803Z" }, + { url = "https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", size = 148567, upload-time = "2025-05-02T08:32:40.251Z" }, + { url = "https://files.pythonhosted.org/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", size = 150957, upload-time = "2025-05-02T08:32:41.705Z" }, + { url = "https://files.pythonhosted.org/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", size = 145408, upload-time = "2025-05-02T08:32:43.709Z" }, + { url = "https://files.pythonhosted.org/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", size = 153399, upload-time = "2025-05-02T08:32:46.197Z" }, + { url = "https://files.pythonhosted.org/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", size = 156815, upload-time = "2025-05-02T08:32:48.105Z" }, + { url = "https://files.pythonhosted.org/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", size = 154537, upload-time = "2025-05-02T08:32:49.719Z" }, + { url = "https://files.pythonhosted.org/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", size = 149565, upload-time = "2025-05-02T08:32:51.404Z" }, + { url = "https://files.pythonhosted.org/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", size = 98357, upload-time = "2025-05-02T08:32:53.079Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", size = 105776, upload-time = "2025-05-02T08:32:54.573Z" }, + { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622, upload-time = "2025-05-02T08:32:56.363Z" }, + { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435, upload-time = "2025-05-02T08:32:58.551Z" }, + { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653, upload-time = "2025-05-02T08:33:00.342Z" }, + { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231, upload-time = "2025-05-02T08:33:02.081Z" }, + { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243, upload-time = "2025-05-02T08:33:04.063Z" }, + { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442, upload-time = "2025-05-02T08:33:06.418Z" }, + { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147, upload-time = "2025-05-02T08:33:08.183Z" }, + { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057, upload-time = "2025-05-02T08:33:09.986Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454, upload-time = "2025-05-02T08:33:11.814Z" }, + { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174, upload-time = "2025-05-02T08:33:13.707Z" }, + { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166, upload-time = "2025-05-02T08:33:15.458Z" }, + { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064, upload-time = "2025-05-02T08:33:17.06Z" }, + { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641, upload-time = "2025-05-02T08:33:18.753Z" }, + { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" }, ] [[package]] @@ -578,22 +578,22 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/73/09/10d57569e399ce9cbc5eee2134996581c957f63a9addfa6ca657daf006b8/chroma_hnswlib-0.7.6.tar.gz", hash = "sha256:4dce282543039681160259d29fcde6151cc9106c6461e0485f57cdccd83059b7", size = 32256 } +sdist = { url = "https://files.pythonhosted.org/packages/73/09/10d57569e399ce9cbc5eee2134996581c957f63a9addfa6ca657daf006b8/chroma_hnswlib-0.7.6.tar.gz", hash = "sha256:4dce282543039681160259d29fcde6151cc9106c6461e0485f57cdccd83059b7", size = 32256, upload-time = "2024-07-22T20:19:29.259Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/74/b9dde05ea8685d2f8c4681b517e61c7887e974f6272bb24ebc8f2105875b/chroma_hnswlib-0.7.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f35192fbbeadc8c0633f0a69c3d3e9f1a4eab3a46b65458bbcbcabdd9e895c36", size = 195821 }, - { url = "https://files.pythonhosted.org/packages/fd/58/101bfa6bc41bc6cc55fbb5103c75462a7bf882e1704256eb4934df85b6a8/chroma_hnswlib-0.7.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f007b608c96362b8f0c8b6b2ac94f67f83fcbabd857c378ae82007ec92f4d82", size = 183854 }, - { url = "https://files.pythonhosted.org/packages/17/ff/95d49bb5ce134f10d6aa08d5f3bec624eaff945f0b17d8c3fce888b9a54a/chroma_hnswlib-0.7.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:456fd88fa0d14e6b385358515aef69fc89b3c2191706fd9aee62087b62aad09c", size = 2358774 }, - { url = "https://files.pythonhosted.org/packages/3a/6d/27826180a54df80dbba8a4f338b022ba21c0c8af96fd08ff8510626dee8f/chroma_hnswlib-0.7.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dfaae825499c2beaa3b75a12d7ec713b64226df72a5c4097203e3ed532680da", size = 2392739 }, - { url = "https://files.pythonhosted.org/packages/d6/63/ee3e8b7a8f931918755faacf783093b61f32f59042769d9db615999c3de0/chroma_hnswlib-0.7.6-cp310-cp310-win_amd64.whl", hash = "sha256:2487201982241fb1581be26524145092c95902cb09fc2646ccfbc407de3328ec", size = 150955 }, - { url = "https://files.pythonhosted.org/packages/f5/af/d15fdfed2a204c0f9467ad35084fbac894c755820b203e62f5dcba2d41f1/chroma_hnswlib-0.7.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81181d54a2b1e4727369486a631f977ffc53c5533d26e3d366dda243fb0998ca", size = 196911 }, - { url = "https://files.pythonhosted.org/packages/0d/19/aa6f2139f1ff7ad23a690ebf2a511b2594ab359915d7979f76f3213e46c4/chroma_hnswlib-0.7.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4b4ab4e11f1083dd0a11ee4f0e0b183ca9f0f2ed63ededba1935b13ce2b3606f", size = 185000 }, - { url = "https://files.pythonhosted.org/packages/79/b1/1b269c750e985ec7d40b9bbe7d66d0a890e420525187786718e7f6b07913/chroma_hnswlib-0.7.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53db45cd9173d95b4b0bdccb4dbff4c54a42b51420599c32267f3abbeb795170", size = 2377289 }, - { url = "https://files.pythonhosted.org/packages/c7/2d/d5663e134436e5933bc63516a20b5edc08b4c1b1588b9680908a5f1afd04/chroma_hnswlib-0.7.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c093f07a010b499c00a15bc9376036ee4800d335360570b14f7fe92badcdcf9", size = 2411755 }, - { url = "https://files.pythonhosted.org/packages/3e/79/1bce519cf186112d6d5ce2985392a89528c6e1e9332d680bf752694a4cdf/chroma_hnswlib-0.7.6-cp311-cp311-win_amd64.whl", hash = "sha256:0540b0ac96e47d0aa39e88ea4714358ae05d64bbe6bf33c52f316c664190a6a3", size = 151888 }, - { url = "https://files.pythonhosted.org/packages/93/ac/782b8d72de1c57b64fdf5cb94711540db99a92768d93d973174c62d45eb8/chroma_hnswlib-0.7.6-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e87e9b616c281bfbe748d01705817c71211613c3b063021f7ed5e47173556cb7", size = 197804 }, - { url = "https://files.pythonhosted.org/packages/32/4e/fd9ce0764228e9a98f6ff46af05e92804090b5557035968c5b4198bc7af9/chroma_hnswlib-0.7.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ec5ca25bc7b66d2ecbf14502b5729cde25f70945d22f2aaf523c2d747ea68912", size = 185421 }, - { url = "https://files.pythonhosted.org/packages/d9/3d/b59a8dedebd82545d873235ef2d06f95be244dfece7ee4a1a6044f080b18/chroma_hnswlib-0.7.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305ae491de9d5f3c51e8bd52d84fdf2545a4a2bc7af49765cda286b7bb30b1d4", size = 2389672 }, - { url = "https://files.pythonhosted.org/packages/74/1e/80a033ea4466338824974a34f418e7b034a7748bf906f56466f5caa434b0/chroma_hnswlib-0.7.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:822ede968d25a2c88823ca078a58f92c9b5c4142e38c7c8b4c48178894a0a3c5", size = 2436986 }, + { url = "https://files.pythonhosted.org/packages/a8/74/b9dde05ea8685d2f8c4681b517e61c7887e974f6272bb24ebc8f2105875b/chroma_hnswlib-0.7.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f35192fbbeadc8c0633f0a69c3d3e9f1a4eab3a46b65458bbcbcabdd9e895c36", size = 195821, upload-time = "2024-07-22T20:18:26.163Z" }, + { url = "https://files.pythonhosted.org/packages/fd/58/101bfa6bc41bc6cc55fbb5103c75462a7bf882e1704256eb4934df85b6a8/chroma_hnswlib-0.7.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f007b608c96362b8f0c8b6b2ac94f67f83fcbabd857c378ae82007ec92f4d82", size = 183854, upload-time = "2024-07-22T20:18:27.6Z" }, + { url = "https://files.pythonhosted.org/packages/17/ff/95d49bb5ce134f10d6aa08d5f3bec624eaff945f0b17d8c3fce888b9a54a/chroma_hnswlib-0.7.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:456fd88fa0d14e6b385358515aef69fc89b3c2191706fd9aee62087b62aad09c", size = 2358774, upload-time = "2024-07-22T20:18:29.161Z" }, + { url = "https://files.pythonhosted.org/packages/3a/6d/27826180a54df80dbba8a4f338b022ba21c0c8af96fd08ff8510626dee8f/chroma_hnswlib-0.7.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dfaae825499c2beaa3b75a12d7ec713b64226df72a5c4097203e3ed532680da", size = 2392739, upload-time = "2024-07-22T20:18:30.938Z" }, + { url = "https://files.pythonhosted.org/packages/d6/63/ee3e8b7a8f931918755faacf783093b61f32f59042769d9db615999c3de0/chroma_hnswlib-0.7.6-cp310-cp310-win_amd64.whl", hash = "sha256:2487201982241fb1581be26524145092c95902cb09fc2646ccfbc407de3328ec", size = 150955, upload-time = "2024-07-22T20:18:32.268Z" }, + { url = "https://files.pythonhosted.org/packages/f5/af/d15fdfed2a204c0f9467ad35084fbac894c755820b203e62f5dcba2d41f1/chroma_hnswlib-0.7.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81181d54a2b1e4727369486a631f977ffc53c5533d26e3d366dda243fb0998ca", size = 196911, upload-time = "2024-07-22T20:18:33.46Z" }, + { url = "https://files.pythonhosted.org/packages/0d/19/aa6f2139f1ff7ad23a690ebf2a511b2594ab359915d7979f76f3213e46c4/chroma_hnswlib-0.7.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4b4ab4e11f1083dd0a11ee4f0e0b183ca9f0f2ed63ededba1935b13ce2b3606f", size = 185000, upload-time = "2024-07-22T20:18:36.16Z" }, + { url = "https://files.pythonhosted.org/packages/79/b1/1b269c750e985ec7d40b9bbe7d66d0a890e420525187786718e7f6b07913/chroma_hnswlib-0.7.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53db45cd9173d95b4b0bdccb4dbff4c54a42b51420599c32267f3abbeb795170", size = 2377289, upload-time = "2024-07-22T20:18:37.761Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2d/d5663e134436e5933bc63516a20b5edc08b4c1b1588b9680908a5f1afd04/chroma_hnswlib-0.7.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c093f07a010b499c00a15bc9376036ee4800d335360570b14f7fe92badcdcf9", size = 2411755, upload-time = "2024-07-22T20:18:39.949Z" }, + { url = "https://files.pythonhosted.org/packages/3e/79/1bce519cf186112d6d5ce2985392a89528c6e1e9332d680bf752694a4cdf/chroma_hnswlib-0.7.6-cp311-cp311-win_amd64.whl", hash = "sha256:0540b0ac96e47d0aa39e88ea4714358ae05d64bbe6bf33c52f316c664190a6a3", size = 151888, upload-time = "2024-07-22T20:18:45.003Z" }, + { url = "https://files.pythonhosted.org/packages/93/ac/782b8d72de1c57b64fdf5cb94711540db99a92768d93d973174c62d45eb8/chroma_hnswlib-0.7.6-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e87e9b616c281bfbe748d01705817c71211613c3b063021f7ed5e47173556cb7", size = 197804, upload-time = "2024-07-22T20:18:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/32/4e/fd9ce0764228e9a98f6ff46af05e92804090b5557035968c5b4198bc7af9/chroma_hnswlib-0.7.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ec5ca25bc7b66d2ecbf14502b5729cde25f70945d22f2aaf523c2d747ea68912", size = 185421, upload-time = "2024-07-22T20:18:47.72Z" }, + { url = "https://files.pythonhosted.org/packages/d9/3d/b59a8dedebd82545d873235ef2d06f95be244dfece7ee4a1a6044f080b18/chroma_hnswlib-0.7.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305ae491de9d5f3c51e8bd52d84fdf2545a4a2bc7af49765cda286b7bb30b1d4", size = 2389672, upload-time = "2024-07-22T20:18:49.583Z" }, + { url = "https://files.pythonhosted.org/packages/74/1e/80a033ea4466338824974a34f418e7b034a7748bf906f56466f5caa434b0/chroma_hnswlib-0.7.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:822ede968d25a2c88823ca078a58f92c9b5c4142e38c7c8b4c48178894a0a3c5", size = 2436986, upload-time = "2024-07-22T20:18:51.872Z" }, ] [[package]] @@ -630,9 +630,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/64/28daa773f784bcd18de944fe26ed301de844d6ee17188e26a9d6b4baf122/chromadb-0.5.23.tar.gz", hash = "sha256:360a12b9795c5a33cb1f839d14410ccbde662ef1accd36153b0ae22312edabd1", size = 33700455 } +sdist = { url = "https://files.pythonhosted.org/packages/42/64/28daa773f784bcd18de944fe26ed301de844d6ee17188e26a9d6b4baf122/chromadb-0.5.23.tar.gz", hash = "sha256:360a12b9795c5a33cb1f839d14410ccbde662ef1accd36153b0ae22312edabd1", size = 33700455, upload-time = "2024-12-05T06:31:19.81Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/92/8c/a9eb95a28e6c35a0122417976a9d435eeaceb53f596a8973e33b3dd4cfac/chromadb-0.5.23-py3-none-any.whl", hash = "sha256:ffe5bdd7276d12cb682df0d38a13aa37573e6a3678e71889ac45f539ae05ad7e", size = 628347 }, + { url = "https://files.pythonhosted.org/packages/92/8c/a9eb95a28e6c35a0122417976a9d435eeaceb53f596a8973e33b3dd4cfac/chromadb-0.5.23-py3-none-any.whl", hash = "sha256:ffe5bdd7276d12cb682df0d38a13aa37573e6a3678e71889ac45f539ae05ad7e", size = 628347, upload-time = "2024-12-05T06:31:17.231Z" }, ] [[package]] @@ -642,9 +642,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" }, ] [[package]] @@ -662,18 +662,18 @@ dependencies = [ { name = "types-requests" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a1/33/69c7d1b25a20eafef4197a1444c7f87d5241e936194e54876ea8996157e6/cohere-5.15.0.tar.gz", hash = "sha256:e802d4718ddb0bb655654382ebbce002756a3800faac30296cde7f1bdc6ff2cc", size = 135021 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/33/69c7d1b25a20eafef4197a1444c7f87d5241e936194e54876ea8996157e6/cohere-5.15.0.tar.gz", hash = "sha256:e802d4718ddb0bb655654382ebbce002756a3800faac30296cde7f1bdc6ff2cc", size = 135021, upload-time = "2025-04-15T13:39:51.404Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/87/94694db7fe6df979fbc03286eaabdfa98f1c8fa532960e5afdf965e10960/cohere-5.15.0-py3-none-any.whl", hash = "sha256:22ff867c2a6f2fc2b585360c6072f584f11f275ef6d9242bac24e0fa2df1dfb5", size = 259522 }, + { url = "https://files.pythonhosted.org/packages/c7/87/94694db7fe6df979fbc03286eaabdfa98f1c8fa532960e5afdf965e10960/cohere-5.15.0-py3-none-any.whl", hash = "sha256:22ff867c2a6f2fc2b585360c6072f584f11f275ef6d9242bac24e0fa2df1dfb5", size = 259522, upload-time = "2025-04-15T13:39:49.498Z" }, ] [[package]] name = "colorama" version = "0.4.6" 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/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 }, + { 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]] @@ -683,73 +683,73 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "humanfriendly" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520 } +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/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018 }, + { 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 = "coverage" version = "7.8.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/07/998afa4a0ecdf9b1981ae05415dad2d4e7716e1b1f00abbd91691ac09ac9/coverage-7.8.2.tar.gz", hash = "sha256:a886d531373a1f6ff9fad2a2ba4a045b68467b779ae729ee0b3b10ac20033b27", size = 812759 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/6b/7dd06399a5c0b81007e3a6af0395cd60e6a30f959f8d407d3ee04642e896/coverage-7.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd8ec21e1443fd7a447881332f7ce9d35b8fbd2849e761bb290b584535636b0a", size = 211573 }, - { url = "https://files.pythonhosted.org/packages/f0/df/2b24090820a0bac1412955fb1a4dade6bc3b8dcef7b899c277ffaf16916d/coverage-7.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c26c2396674816deaeae7ded0e2b42c26537280f8fe313335858ffff35019be", size = 212006 }, - { url = "https://files.pythonhosted.org/packages/c5/c4/e4e3b998e116625562a872a342419652fa6ca73f464d9faf9f52f1aff427/coverage-7.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1aec326ed237e5880bfe69ad41616d333712c7937bcefc1343145e972938f9b3", size = 241128 }, - { url = "https://files.pythonhosted.org/packages/b1/67/b28904afea3e87a895da850ba587439a61699bf4b73d04d0dfd99bbd33b4/coverage-7.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e818796f71702d7a13e50c70de2a1924f729228580bcba1607cccf32eea46e6", size = 239026 }, - { url = "https://files.pythonhosted.org/packages/8c/0f/47bf7c5630d81bc2cd52b9e13043685dbb7c79372a7f5857279cc442b37c/coverage-7.8.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:546e537d9e24efc765c9c891328f30f826e3e4808e31f5d0f87c4ba12bbd1622", size = 240172 }, - { url = "https://files.pythonhosted.org/packages/ba/38/af3eb9d36d85abc881f5aaecf8209383dbe0fa4cac2d804c55d05c51cb04/coverage-7.8.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab9b09a2349f58e73f8ebc06fac546dd623e23b063e5398343c5270072e3201c", size = 240086 }, - { url = "https://files.pythonhosted.org/packages/9e/64/c40c27c2573adeba0fe16faf39a8aa57368a1f2148865d6bb24c67eadb41/coverage-7.8.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fd51355ab8a372d89fb0e6a31719e825cf8df8b6724bee942fb5b92c3f016ba3", size = 238792 }, - { url = "https://files.pythonhosted.org/packages/8e/ab/b7c85146f15457671c1412afca7c25a5696d7625e7158002aa017e2d7e3c/coverage-7.8.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0774df1e093acb6c9e4d58bce7f86656aeed6c132a16e2337692c12786b32404", size = 239096 }, - { url = "https://files.pythonhosted.org/packages/d3/50/9446dad1310905fb1dc284d60d4320a5b25d4e3e33f9ea08b8d36e244e23/coverage-7.8.2-cp310-cp310-win32.whl", hash = "sha256:00f2e2f2e37f47e5f54423aeefd6c32a7dbcedc033fcd3928a4f4948e8b96af7", size = 214144 }, - { url = "https://files.pythonhosted.org/packages/23/ed/792e66ad7b8b0df757db8d47af0c23659cdb5a65ef7ace8b111cacdbee89/coverage-7.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:145b07bea229821d51811bf15eeab346c236d523838eda395ea969d120d13347", size = 215043 }, - { url = "https://files.pythonhosted.org/packages/6a/4d/1ff618ee9f134d0de5cc1661582c21a65e06823f41caf801aadf18811a8e/coverage-7.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b99058eef42e6a8dcd135afb068b3d53aff3921ce699e127602efff9956457a9", size = 211692 }, - { url = "https://files.pythonhosted.org/packages/96/fa/c3c1b476de96f2bc7a8ca01a9f1fcb51c01c6b60a9d2c3e66194b2bdb4af/coverage-7.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5feb7f2c3e6ea94d3b877def0270dff0947b8d8c04cfa34a17be0a4dc1836879", size = 212115 }, - { url = "https://files.pythonhosted.org/packages/f7/c2/5414c5a1b286c0f3881ae5adb49be1854ac5b7e99011501f81c8c1453065/coverage-7.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:670a13249b957bb9050fab12d86acef7bf8f6a879b9d1a883799276e0d4c674a", size = 244740 }, - { url = "https://files.pythonhosted.org/packages/cd/46/1ae01912dfb06a642ef3dd9cf38ed4996fda8fe884dab8952da616f81a2b/coverage-7.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bdc8bf760459a4a4187b452213e04d039990211f98644c7292adf1e471162b5", size = 242429 }, - { url = "https://files.pythonhosted.org/packages/06/58/38c676aec594bfe2a87c7683942e5a30224791d8df99bcc8439fde140377/coverage-7.8.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07a989c867986c2a75f158f03fdb413128aad29aca9d4dbce5fc755672d96f11", size = 244218 }, - { url = "https://files.pythonhosted.org/packages/80/0c/95b1023e881ce45006d9abc250f76c6cdab7134a1c182d9713878dfefcb2/coverage-7.8.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2db10dedeb619a771ef0e2949ccba7b75e33905de959c2643a4607bef2f3fb3a", size = 243865 }, - { url = "https://files.pythonhosted.org/packages/57/37/0ae95989285a39e0839c959fe854a3ae46c06610439350d1ab860bf020ac/coverage-7.8.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e6ea7dba4e92926b7b5f0990634b78ea02f208d04af520c73a7c876d5a8d36cb", size = 242038 }, - { url = "https://files.pythonhosted.org/packages/4d/82/40e55f7c0eb5e97cc62cbd9d0746fd24e8caf57be5a408b87529416e0c70/coverage-7.8.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ef2f22795a7aca99fc3c84393a55a53dd18ab8c93fb431004e4d8f0774150f54", size = 242567 }, - { url = "https://files.pythonhosted.org/packages/f9/35/66a51adc273433a253989f0d9cc7aa6bcdb4855382cf0858200afe578861/coverage-7.8.2-cp311-cp311-win32.whl", hash = "sha256:641988828bc18a6368fe72355df5f1703e44411adbe49bba5644b941ce6f2e3a", size = 214194 }, - { url = "https://files.pythonhosted.org/packages/f6/8f/a543121f9f5f150eae092b08428cb4e6b6d2d134152c3357b77659d2a605/coverage-7.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8ab4a51cb39dc1933ba627e0875046d150e88478dbe22ce145a68393e9652975", size = 215109 }, - { url = "https://files.pythonhosted.org/packages/77/65/6cc84b68d4f35186463cd7ab1da1169e9abb59870c0f6a57ea6aba95f861/coverage-7.8.2-cp311-cp311-win_arm64.whl", hash = "sha256:8966a821e2083c74d88cca5b7dcccc0a3a888a596a04c0b9668a891de3a0cc53", size = 213521 }, - { url = "https://files.pythonhosted.org/packages/8d/2a/1da1ada2e3044fcd4a3254fb3576e160b8fe5b36d705c8a31f793423f763/coverage-7.8.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2f6fe3654468d061942591aef56686131335b7a8325684eda85dacdf311356c", size = 211876 }, - { url = "https://files.pythonhosted.org/packages/70/e9/3d715ffd5b6b17a8be80cd14a8917a002530a99943cc1939ad5bb2aa74b9/coverage-7.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76090fab50610798cc05241bf83b603477c40ee87acd358b66196ab0ca44ffa1", size = 212130 }, - { url = "https://files.pythonhosted.org/packages/a0/02/fdce62bb3c21649abfd91fbdcf041fb99be0d728ff00f3f9d54d97ed683e/coverage-7.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd0a0a5054be160777a7920b731a0570284db5142abaaf81bcbb282b8d99279", size = 246176 }, - { url = "https://files.pythonhosted.org/packages/a7/52/decbbed61e03b6ffe85cd0fea360a5e04a5a98a7423f292aae62423b8557/coverage-7.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da23ce9a3d356d0affe9c7036030b5c8f14556bd970c9b224f9c8205505e3b99", size = 243068 }, - { url = "https://files.pythonhosted.org/packages/38/6c/d0e9c0cce18faef79a52778219a3c6ee8e336437da8eddd4ab3dbd8fadff/coverage-7.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9392773cffeb8d7e042a7b15b82a414011e9d2b5fdbbd3f7e6a6b17d5e21b20", size = 245328 }, - { url = "https://files.pythonhosted.org/packages/f0/70/f703b553a2f6b6c70568c7e398ed0789d47f953d67fbba36a327714a7bca/coverage-7.8.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:876cbfd0b09ce09d81585d266c07a32657beb3eaec896f39484b631555be0fe2", size = 245099 }, - { url = "https://files.pythonhosted.org/packages/ec/fb/4cbb370dedae78460c3aacbdad9d249e853f3bc4ce5ff0e02b1983d03044/coverage-7.8.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3da9b771c98977a13fbc3830f6caa85cae6c9c83911d24cb2d218e9394259c57", size = 243314 }, - { url = "https://files.pythonhosted.org/packages/39/9f/1afbb2cb9c8699b8bc38afdce00a3b4644904e6a38c7bf9005386c9305ec/coverage-7.8.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a990f6510b3292686713bfef26d0049cd63b9c7bb17e0864f133cbfd2e6167f", size = 244489 }, - { url = "https://files.pythonhosted.org/packages/79/fa/f3e7ec7d220bff14aba7a4786ae47043770cbdceeea1803083059c878837/coverage-7.8.2-cp312-cp312-win32.whl", hash = "sha256:bf8111cddd0f2b54d34e96613e7fbdd59a673f0cf5574b61134ae75b6f5a33b8", size = 214366 }, - { url = "https://files.pythonhosted.org/packages/54/aa/9cbeade19b7e8e853e7ffc261df885d66bf3a782c71cba06c17df271f9e6/coverage-7.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:86a323a275e9e44cdf228af9b71c5030861d4d2610886ab920d9945672a81223", size = 215165 }, - { url = "https://files.pythonhosted.org/packages/c4/73/e2528bf1237d2448f882bbebaec5c3500ef07301816c5c63464b9da4d88a/coverage-7.8.2-cp312-cp312-win_arm64.whl", hash = "sha256:820157de3a589e992689ffcda8639fbabb313b323d26388d02e154164c57b07f", size = 213548 }, - { url = "https://files.pythonhosted.org/packages/1a/93/eb6400a745ad3b265bac36e8077fdffcf0268bdbbb6c02b7220b624c9b31/coverage-7.8.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ea561010914ec1c26ab4188aef8b1567272ef6de096312716f90e5baa79ef8ca", size = 211898 }, - { url = "https://files.pythonhosted.org/packages/1b/7c/bdbf113f92683024406a1cd226a199e4200a2001fc85d6a6e7e299e60253/coverage-7.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cb86337a4fcdd0e598ff2caeb513ac604d2f3da6d53df2c8e368e07ee38e277d", size = 212171 }, - { url = "https://files.pythonhosted.org/packages/91/22/594513f9541a6b88eb0dba4d5da7d71596dadef6b17a12dc2c0e859818a9/coverage-7.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a4636ddb666971345541b59899e969f3b301143dd86b0ddbb570bd591f1e85", size = 245564 }, - { url = "https://files.pythonhosted.org/packages/1f/f4/2860fd6abeebd9f2efcfe0fd376226938f22afc80c1943f363cd3c28421f/coverage-7.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5040536cf9b13fb033f76bcb5e1e5cb3b57c4807fef37db9e0ed129c6a094257", size = 242719 }, - { url = "https://files.pythonhosted.org/packages/89/60/f5f50f61b6332451520e6cdc2401700c48310c64bc2dd34027a47d6ab4ca/coverage-7.8.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc67994df9bcd7e0150a47ef41278b9e0a0ea187caba72414b71dc590b99a108", size = 244634 }, - { url = "https://files.pythonhosted.org/packages/3b/70/7f4e919039ab7d944276c446b603eea84da29ebcf20984fb1fdf6e602028/coverage-7.8.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e6c86888fd076d9e0fe848af0a2142bf606044dc5ceee0aa9eddb56e26895a0", size = 244824 }, - { url = "https://files.pythonhosted.org/packages/26/45/36297a4c0cea4de2b2c442fe32f60c3991056c59cdc3cdd5346fbb995c97/coverage-7.8.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:684ca9f58119b8e26bef860db33524ae0365601492e86ba0b71d513f525e7050", size = 242872 }, - { url = "https://files.pythonhosted.org/packages/a4/71/e041f1b9420f7b786b1367fa2a375703889ef376e0d48de9f5723fb35f11/coverage-7.8.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8165584ddedb49204c4e18da083913bdf6a982bfb558632a79bdaadcdafd0d48", size = 244179 }, - { url = "https://files.pythonhosted.org/packages/bd/db/3c2bf49bdc9de76acf2491fc03130c4ffc51469ce2f6889d2640eb563d77/coverage-7.8.2-cp313-cp313-win32.whl", hash = "sha256:34759ee2c65362163699cc917bdb2a54114dd06d19bab860725f94ef45a3d9b7", size = 214393 }, - { url = "https://files.pythonhosted.org/packages/c6/dc/947e75d47ebbb4b02d8babb1fad4ad381410d5bc9da7cfca80b7565ef401/coverage-7.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:2f9bc608fbafaee40eb60a9a53dbfb90f53cc66d3d32c2849dc27cf5638a21e3", size = 215194 }, - { url = "https://files.pythonhosted.org/packages/90/31/a980f7df8a37eaf0dc60f932507fda9656b3a03f0abf188474a0ea188d6d/coverage-7.8.2-cp313-cp313-win_arm64.whl", hash = "sha256:9fe449ee461a3b0c7105690419d0b0aba1232f4ff6d120a9e241e58a556733f7", size = 213580 }, - { url = "https://files.pythonhosted.org/packages/8a/6a/25a37dd90f6c95f59355629417ebcb74e1c34e38bb1eddf6ca9b38b0fc53/coverage-7.8.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8369a7c8ef66bded2b6484053749ff220dbf83cba84f3398c84c51a6f748a008", size = 212734 }, - { url = "https://files.pythonhosted.org/packages/36/8b/3a728b3118988725f40950931abb09cd7f43b3c740f4640a59f1db60e372/coverage-7.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:159b81df53a5fcbc7d45dae3adad554fdbde9829a994e15227b3f9d816d00b36", size = 212959 }, - { url = "https://files.pythonhosted.org/packages/53/3c/212d94e6add3a3c3f412d664aee452045ca17a066def8b9421673e9482c4/coverage-7.8.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6fcbbd35a96192d042c691c9e0c49ef54bd7ed865846a3c9d624c30bb67ce46", size = 257024 }, - { url = "https://files.pythonhosted.org/packages/a4/40/afc03f0883b1e51bbe804707aae62e29c4e8c8bbc365c75e3e4ddeee9ead/coverage-7.8.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05364b9cc82f138cc86128dc4e2e1251c2981a2218bfcd556fe6b0fbaa3501be", size = 252867 }, - { url = "https://files.pythonhosted.org/packages/18/a2/3699190e927b9439c6ded4998941a3c1d6fa99e14cb28d8536729537e307/coverage-7.8.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46d532db4e5ff3979ce47d18e2fe8ecad283eeb7367726da0e5ef88e4fe64740", size = 255096 }, - { url = "https://files.pythonhosted.org/packages/b4/06/16e3598b9466456b718eb3e789457d1a5b8bfb22e23b6e8bbc307df5daf0/coverage-7.8.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4000a31c34932e7e4fa0381a3d6deb43dc0c8f458e3e7ea6502e6238e10be625", size = 256276 }, - { url = "https://files.pythonhosted.org/packages/a7/d5/4b5a120d5d0223050a53d2783c049c311eea1709fa9de12d1c358e18b707/coverage-7.8.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:43ff5033d657cd51f83015c3b7a443287250dc14e69910577c3e03bd2e06f27b", size = 254478 }, - { url = "https://files.pythonhosted.org/packages/ba/85/f9ecdb910ecdb282b121bfcaa32fa8ee8cbd7699f83330ee13ff9bbf1a85/coverage-7.8.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94316e13f0981cbbba132c1f9f365cac1d26716aaac130866ca812006f662199", size = 255255 }, - { url = "https://files.pythonhosted.org/packages/50/63/2d624ac7d7ccd4ebbd3c6a9eba9d7fc4491a1226071360d59dd84928ccb2/coverage-7.8.2-cp313-cp313t-win32.whl", hash = "sha256:3f5673888d3676d0a745c3d0e16da338c5eea300cb1f4ada9c872981265e76d8", size = 215109 }, - { url = "https://files.pythonhosted.org/packages/22/5e/7053b71462e970e869111c1853afd642212568a350eba796deefdfbd0770/coverage-7.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:2c08b05ee8d7861e45dc5a2cc4195c8c66dca5ac613144eb6ebeaff2d502e73d", size = 216268 }, - { url = "https://files.pythonhosted.org/packages/07/69/afa41aa34147655543dbe96994f8a246daf94b361ccf5edfd5df62ce066a/coverage-7.8.2-cp313-cp313t-win_arm64.whl", hash = "sha256:1e1448bb72b387755e1ff3ef1268a06617afd94188164960dba8d0245a46004b", size = 214071 }, - { url = "https://files.pythonhosted.org/packages/69/2f/572b29496d8234e4a7773200dd835a0d32d9e171f2d974f3fe04a9dbc271/coverage-7.8.2-pp39.pp310.pp311-none-any.whl", hash = "sha256:ec455eedf3ba0bbdf8f5a570012617eb305c63cb9f03428d39bf544cb2b94837", size = 203636 }, - { url = "https://files.pythonhosted.org/packages/a0/1a/0b9c32220ad694d66062f571cc5cedfa9997b64a591e8a500bb63de1bd40/coverage-7.8.2-py3-none-any.whl", hash = "sha256:726f32ee3713f7359696331a18daf0c3b3a70bb0ae71141b9d3c52be7c595e32", size = 203623 }, +sdist = { url = "https://files.pythonhosted.org/packages/ba/07/998afa4a0ecdf9b1981ae05415dad2d4e7716e1b1f00abbd91691ac09ac9/coverage-7.8.2.tar.gz", hash = "sha256:a886d531373a1f6ff9fad2a2ba4a045b68467b779ae729ee0b3b10ac20033b27", size = 812759, upload-time = "2025-05-23T11:39:57.856Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/6b/7dd06399a5c0b81007e3a6af0395cd60e6a30f959f8d407d3ee04642e896/coverage-7.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd8ec21e1443fd7a447881332f7ce9d35b8fbd2849e761bb290b584535636b0a", size = 211573, upload-time = "2025-05-23T11:37:47.207Z" }, + { url = "https://files.pythonhosted.org/packages/f0/df/2b24090820a0bac1412955fb1a4dade6bc3b8dcef7b899c277ffaf16916d/coverage-7.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c26c2396674816deaeae7ded0e2b42c26537280f8fe313335858ffff35019be", size = 212006, upload-time = "2025-05-23T11:37:50.289Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c4/e4e3b998e116625562a872a342419652fa6ca73f464d9faf9f52f1aff427/coverage-7.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1aec326ed237e5880bfe69ad41616d333712c7937bcefc1343145e972938f9b3", size = 241128, upload-time = "2025-05-23T11:37:52.229Z" }, + { url = "https://files.pythonhosted.org/packages/b1/67/b28904afea3e87a895da850ba587439a61699bf4b73d04d0dfd99bbd33b4/coverage-7.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e818796f71702d7a13e50c70de2a1924f729228580bcba1607cccf32eea46e6", size = 239026, upload-time = "2025-05-23T11:37:53.846Z" }, + { url = "https://files.pythonhosted.org/packages/8c/0f/47bf7c5630d81bc2cd52b9e13043685dbb7c79372a7f5857279cc442b37c/coverage-7.8.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:546e537d9e24efc765c9c891328f30f826e3e4808e31f5d0f87c4ba12bbd1622", size = 240172, upload-time = "2025-05-23T11:37:55.711Z" }, + { url = "https://files.pythonhosted.org/packages/ba/38/af3eb9d36d85abc881f5aaecf8209383dbe0fa4cac2d804c55d05c51cb04/coverage-7.8.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab9b09a2349f58e73f8ebc06fac546dd623e23b063e5398343c5270072e3201c", size = 240086, upload-time = "2025-05-23T11:37:57.724Z" }, + { url = "https://files.pythonhosted.org/packages/9e/64/c40c27c2573adeba0fe16faf39a8aa57368a1f2148865d6bb24c67eadb41/coverage-7.8.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fd51355ab8a372d89fb0e6a31719e825cf8df8b6724bee942fb5b92c3f016ba3", size = 238792, upload-time = "2025-05-23T11:37:59.737Z" }, + { url = "https://files.pythonhosted.org/packages/8e/ab/b7c85146f15457671c1412afca7c25a5696d7625e7158002aa017e2d7e3c/coverage-7.8.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0774df1e093acb6c9e4d58bce7f86656aeed6c132a16e2337692c12786b32404", size = 239096, upload-time = "2025-05-23T11:38:01.693Z" }, + { url = "https://files.pythonhosted.org/packages/d3/50/9446dad1310905fb1dc284d60d4320a5b25d4e3e33f9ea08b8d36e244e23/coverage-7.8.2-cp310-cp310-win32.whl", hash = "sha256:00f2e2f2e37f47e5f54423aeefd6c32a7dbcedc033fcd3928a4f4948e8b96af7", size = 214144, upload-time = "2025-05-23T11:38:03.68Z" }, + { url = "https://files.pythonhosted.org/packages/23/ed/792e66ad7b8b0df757db8d47af0c23659cdb5a65ef7ace8b111cacdbee89/coverage-7.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:145b07bea229821d51811bf15eeab346c236d523838eda395ea969d120d13347", size = 215043, upload-time = "2025-05-23T11:38:05.217Z" }, + { url = "https://files.pythonhosted.org/packages/6a/4d/1ff618ee9f134d0de5cc1661582c21a65e06823f41caf801aadf18811a8e/coverage-7.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b99058eef42e6a8dcd135afb068b3d53aff3921ce699e127602efff9956457a9", size = 211692, upload-time = "2025-05-23T11:38:08.485Z" }, + { url = "https://files.pythonhosted.org/packages/96/fa/c3c1b476de96f2bc7a8ca01a9f1fcb51c01c6b60a9d2c3e66194b2bdb4af/coverage-7.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5feb7f2c3e6ea94d3b877def0270dff0947b8d8c04cfa34a17be0a4dc1836879", size = 212115, upload-time = "2025-05-23T11:38:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/f7/c2/5414c5a1b286c0f3881ae5adb49be1854ac5b7e99011501f81c8c1453065/coverage-7.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:670a13249b957bb9050fab12d86acef7bf8f6a879b9d1a883799276e0d4c674a", size = 244740, upload-time = "2025-05-23T11:38:11.947Z" }, + { url = "https://files.pythonhosted.org/packages/cd/46/1ae01912dfb06a642ef3dd9cf38ed4996fda8fe884dab8952da616f81a2b/coverage-7.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bdc8bf760459a4a4187b452213e04d039990211f98644c7292adf1e471162b5", size = 242429, upload-time = "2025-05-23T11:38:13.955Z" }, + { url = "https://files.pythonhosted.org/packages/06/58/38c676aec594bfe2a87c7683942e5a30224791d8df99bcc8439fde140377/coverage-7.8.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07a989c867986c2a75f158f03fdb413128aad29aca9d4dbce5fc755672d96f11", size = 244218, upload-time = "2025-05-23T11:38:15.631Z" }, + { url = "https://files.pythonhosted.org/packages/80/0c/95b1023e881ce45006d9abc250f76c6cdab7134a1c182d9713878dfefcb2/coverage-7.8.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2db10dedeb619a771ef0e2949ccba7b75e33905de959c2643a4607bef2f3fb3a", size = 243865, upload-time = "2025-05-23T11:38:17.622Z" }, + { url = "https://files.pythonhosted.org/packages/57/37/0ae95989285a39e0839c959fe854a3ae46c06610439350d1ab860bf020ac/coverage-7.8.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e6ea7dba4e92926b7b5f0990634b78ea02f208d04af520c73a7c876d5a8d36cb", size = 242038, upload-time = "2025-05-23T11:38:19.966Z" }, + { url = "https://files.pythonhosted.org/packages/4d/82/40e55f7c0eb5e97cc62cbd9d0746fd24e8caf57be5a408b87529416e0c70/coverage-7.8.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ef2f22795a7aca99fc3c84393a55a53dd18ab8c93fb431004e4d8f0774150f54", size = 242567, upload-time = "2025-05-23T11:38:21.912Z" }, + { url = "https://files.pythonhosted.org/packages/f9/35/66a51adc273433a253989f0d9cc7aa6bcdb4855382cf0858200afe578861/coverage-7.8.2-cp311-cp311-win32.whl", hash = "sha256:641988828bc18a6368fe72355df5f1703e44411adbe49bba5644b941ce6f2e3a", size = 214194, upload-time = "2025-05-23T11:38:23.571Z" }, + { url = "https://files.pythonhosted.org/packages/f6/8f/a543121f9f5f150eae092b08428cb4e6b6d2d134152c3357b77659d2a605/coverage-7.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8ab4a51cb39dc1933ba627e0875046d150e88478dbe22ce145a68393e9652975", size = 215109, upload-time = "2025-05-23T11:38:25.137Z" }, + { url = "https://files.pythonhosted.org/packages/77/65/6cc84b68d4f35186463cd7ab1da1169e9abb59870c0f6a57ea6aba95f861/coverage-7.8.2-cp311-cp311-win_arm64.whl", hash = "sha256:8966a821e2083c74d88cca5b7dcccc0a3a888a596a04c0b9668a891de3a0cc53", size = 213521, upload-time = "2025-05-23T11:38:27.123Z" }, + { url = "https://files.pythonhosted.org/packages/8d/2a/1da1ada2e3044fcd4a3254fb3576e160b8fe5b36d705c8a31f793423f763/coverage-7.8.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2f6fe3654468d061942591aef56686131335b7a8325684eda85dacdf311356c", size = 211876, upload-time = "2025-05-23T11:38:29.01Z" }, + { url = "https://files.pythonhosted.org/packages/70/e9/3d715ffd5b6b17a8be80cd14a8917a002530a99943cc1939ad5bb2aa74b9/coverage-7.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76090fab50610798cc05241bf83b603477c40ee87acd358b66196ab0ca44ffa1", size = 212130, upload-time = "2025-05-23T11:38:30.675Z" }, + { url = "https://files.pythonhosted.org/packages/a0/02/fdce62bb3c21649abfd91fbdcf041fb99be0d728ff00f3f9d54d97ed683e/coverage-7.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd0a0a5054be160777a7920b731a0570284db5142abaaf81bcbb282b8d99279", size = 246176, upload-time = "2025-05-23T11:38:32.395Z" }, + { url = "https://files.pythonhosted.org/packages/a7/52/decbbed61e03b6ffe85cd0fea360a5e04a5a98a7423f292aae62423b8557/coverage-7.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da23ce9a3d356d0affe9c7036030b5c8f14556bd970c9b224f9c8205505e3b99", size = 243068, upload-time = "2025-05-23T11:38:33.989Z" }, + { url = "https://files.pythonhosted.org/packages/38/6c/d0e9c0cce18faef79a52778219a3c6ee8e336437da8eddd4ab3dbd8fadff/coverage-7.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9392773cffeb8d7e042a7b15b82a414011e9d2b5fdbbd3f7e6a6b17d5e21b20", size = 245328, upload-time = "2025-05-23T11:38:35.568Z" }, + { url = "https://files.pythonhosted.org/packages/f0/70/f703b553a2f6b6c70568c7e398ed0789d47f953d67fbba36a327714a7bca/coverage-7.8.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:876cbfd0b09ce09d81585d266c07a32657beb3eaec896f39484b631555be0fe2", size = 245099, upload-time = "2025-05-23T11:38:37.627Z" }, + { url = "https://files.pythonhosted.org/packages/ec/fb/4cbb370dedae78460c3aacbdad9d249e853f3bc4ce5ff0e02b1983d03044/coverage-7.8.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3da9b771c98977a13fbc3830f6caa85cae6c9c83911d24cb2d218e9394259c57", size = 243314, upload-time = "2025-05-23T11:38:39.238Z" }, + { url = "https://files.pythonhosted.org/packages/39/9f/1afbb2cb9c8699b8bc38afdce00a3b4644904e6a38c7bf9005386c9305ec/coverage-7.8.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a990f6510b3292686713bfef26d0049cd63b9c7bb17e0864f133cbfd2e6167f", size = 244489, upload-time = "2025-05-23T11:38:40.845Z" }, + { url = "https://files.pythonhosted.org/packages/79/fa/f3e7ec7d220bff14aba7a4786ae47043770cbdceeea1803083059c878837/coverage-7.8.2-cp312-cp312-win32.whl", hash = "sha256:bf8111cddd0f2b54d34e96613e7fbdd59a673f0cf5574b61134ae75b6f5a33b8", size = 214366, upload-time = "2025-05-23T11:38:43.551Z" }, + { url = "https://files.pythonhosted.org/packages/54/aa/9cbeade19b7e8e853e7ffc261df885d66bf3a782c71cba06c17df271f9e6/coverage-7.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:86a323a275e9e44cdf228af9b71c5030861d4d2610886ab920d9945672a81223", size = 215165, upload-time = "2025-05-23T11:38:45.148Z" }, + { url = "https://files.pythonhosted.org/packages/c4/73/e2528bf1237d2448f882bbebaec5c3500ef07301816c5c63464b9da4d88a/coverage-7.8.2-cp312-cp312-win_arm64.whl", hash = "sha256:820157de3a589e992689ffcda8639fbabb313b323d26388d02e154164c57b07f", size = 213548, upload-time = "2025-05-23T11:38:46.74Z" }, + { url = "https://files.pythonhosted.org/packages/1a/93/eb6400a745ad3b265bac36e8077fdffcf0268bdbbb6c02b7220b624c9b31/coverage-7.8.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ea561010914ec1c26ab4188aef8b1567272ef6de096312716f90e5baa79ef8ca", size = 211898, upload-time = "2025-05-23T11:38:49.066Z" }, + { url = "https://files.pythonhosted.org/packages/1b/7c/bdbf113f92683024406a1cd226a199e4200a2001fc85d6a6e7e299e60253/coverage-7.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cb86337a4fcdd0e598ff2caeb513ac604d2f3da6d53df2c8e368e07ee38e277d", size = 212171, upload-time = "2025-05-23T11:38:51.207Z" }, + { url = "https://files.pythonhosted.org/packages/91/22/594513f9541a6b88eb0dba4d5da7d71596dadef6b17a12dc2c0e859818a9/coverage-7.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a4636ddb666971345541b59899e969f3b301143dd86b0ddbb570bd591f1e85", size = 245564, upload-time = "2025-05-23T11:38:52.857Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f4/2860fd6abeebd9f2efcfe0fd376226938f22afc80c1943f363cd3c28421f/coverage-7.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5040536cf9b13fb033f76bcb5e1e5cb3b57c4807fef37db9e0ed129c6a094257", size = 242719, upload-time = "2025-05-23T11:38:54.529Z" }, + { url = "https://files.pythonhosted.org/packages/89/60/f5f50f61b6332451520e6cdc2401700c48310c64bc2dd34027a47d6ab4ca/coverage-7.8.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc67994df9bcd7e0150a47ef41278b9e0a0ea187caba72414b71dc590b99a108", size = 244634, upload-time = "2025-05-23T11:38:57.326Z" }, + { url = "https://files.pythonhosted.org/packages/3b/70/7f4e919039ab7d944276c446b603eea84da29ebcf20984fb1fdf6e602028/coverage-7.8.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e6c86888fd076d9e0fe848af0a2142bf606044dc5ceee0aa9eddb56e26895a0", size = 244824, upload-time = "2025-05-23T11:38:59.421Z" }, + { url = "https://files.pythonhosted.org/packages/26/45/36297a4c0cea4de2b2c442fe32f60c3991056c59cdc3cdd5346fbb995c97/coverage-7.8.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:684ca9f58119b8e26bef860db33524ae0365601492e86ba0b71d513f525e7050", size = 242872, upload-time = "2025-05-23T11:39:01.049Z" }, + { url = "https://files.pythonhosted.org/packages/a4/71/e041f1b9420f7b786b1367fa2a375703889ef376e0d48de9f5723fb35f11/coverage-7.8.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8165584ddedb49204c4e18da083913bdf6a982bfb558632a79bdaadcdafd0d48", size = 244179, upload-time = "2025-05-23T11:39:02.709Z" }, + { url = "https://files.pythonhosted.org/packages/bd/db/3c2bf49bdc9de76acf2491fc03130c4ffc51469ce2f6889d2640eb563d77/coverage-7.8.2-cp313-cp313-win32.whl", hash = "sha256:34759ee2c65362163699cc917bdb2a54114dd06d19bab860725f94ef45a3d9b7", size = 214393, upload-time = "2025-05-23T11:39:05.457Z" }, + { url = "https://files.pythonhosted.org/packages/c6/dc/947e75d47ebbb4b02d8babb1fad4ad381410d5bc9da7cfca80b7565ef401/coverage-7.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:2f9bc608fbafaee40eb60a9a53dbfb90f53cc66d3d32c2849dc27cf5638a21e3", size = 215194, upload-time = "2025-05-23T11:39:07.171Z" }, + { url = "https://files.pythonhosted.org/packages/90/31/a980f7df8a37eaf0dc60f932507fda9656b3a03f0abf188474a0ea188d6d/coverage-7.8.2-cp313-cp313-win_arm64.whl", hash = "sha256:9fe449ee461a3b0c7105690419d0b0aba1232f4ff6d120a9e241e58a556733f7", size = 213580, upload-time = "2025-05-23T11:39:08.862Z" }, + { url = "https://files.pythonhosted.org/packages/8a/6a/25a37dd90f6c95f59355629417ebcb74e1c34e38bb1eddf6ca9b38b0fc53/coverage-7.8.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8369a7c8ef66bded2b6484053749ff220dbf83cba84f3398c84c51a6f748a008", size = 212734, upload-time = "2025-05-23T11:39:11.109Z" }, + { url = "https://files.pythonhosted.org/packages/36/8b/3a728b3118988725f40950931abb09cd7f43b3c740f4640a59f1db60e372/coverage-7.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:159b81df53a5fcbc7d45dae3adad554fdbde9829a994e15227b3f9d816d00b36", size = 212959, upload-time = "2025-05-23T11:39:12.751Z" }, + { url = "https://files.pythonhosted.org/packages/53/3c/212d94e6add3a3c3f412d664aee452045ca17a066def8b9421673e9482c4/coverage-7.8.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6fcbbd35a96192d042c691c9e0c49ef54bd7ed865846a3c9d624c30bb67ce46", size = 257024, upload-time = "2025-05-23T11:39:15.569Z" }, + { url = "https://files.pythonhosted.org/packages/a4/40/afc03f0883b1e51bbe804707aae62e29c4e8c8bbc365c75e3e4ddeee9ead/coverage-7.8.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05364b9cc82f138cc86128dc4e2e1251c2981a2218bfcd556fe6b0fbaa3501be", size = 252867, upload-time = "2025-05-23T11:39:17.64Z" }, + { url = "https://files.pythonhosted.org/packages/18/a2/3699190e927b9439c6ded4998941a3c1d6fa99e14cb28d8536729537e307/coverage-7.8.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46d532db4e5ff3979ce47d18e2fe8ecad283eeb7367726da0e5ef88e4fe64740", size = 255096, upload-time = "2025-05-23T11:39:19.328Z" }, + { url = "https://files.pythonhosted.org/packages/b4/06/16e3598b9466456b718eb3e789457d1a5b8bfb22e23b6e8bbc307df5daf0/coverage-7.8.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4000a31c34932e7e4fa0381a3d6deb43dc0c8f458e3e7ea6502e6238e10be625", size = 256276, upload-time = "2025-05-23T11:39:21.077Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d5/4b5a120d5d0223050a53d2783c049c311eea1709fa9de12d1c358e18b707/coverage-7.8.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:43ff5033d657cd51f83015c3b7a443287250dc14e69910577c3e03bd2e06f27b", size = 254478, upload-time = "2025-05-23T11:39:22.838Z" }, + { url = "https://files.pythonhosted.org/packages/ba/85/f9ecdb910ecdb282b121bfcaa32fa8ee8cbd7699f83330ee13ff9bbf1a85/coverage-7.8.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94316e13f0981cbbba132c1f9f365cac1d26716aaac130866ca812006f662199", size = 255255, upload-time = "2025-05-23T11:39:24.644Z" }, + { url = "https://files.pythonhosted.org/packages/50/63/2d624ac7d7ccd4ebbd3c6a9eba9d7fc4491a1226071360d59dd84928ccb2/coverage-7.8.2-cp313-cp313t-win32.whl", hash = "sha256:3f5673888d3676d0a745c3d0e16da338c5eea300cb1f4ada9c872981265e76d8", size = 215109, upload-time = "2025-05-23T11:39:26.722Z" }, + { url = "https://files.pythonhosted.org/packages/22/5e/7053b71462e970e869111c1853afd642212568a350eba796deefdfbd0770/coverage-7.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:2c08b05ee8d7861e45dc5a2cc4195c8c66dca5ac613144eb6ebeaff2d502e73d", size = 216268, upload-time = "2025-05-23T11:39:28.429Z" }, + { url = "https://files.pythonhosted.org/packages/07/69/afa41aa34147655543dbe96994f8a246daf94b361ccf5edfd5df62ce066a/coverage-7.8.2-cp313-cp313t-win_arm64.whl", hash = "sha256:1e1448bb72b387755e1ff3ef1268a06617afd94188164960dba8d0245a46004b", size = 214071, upload-time = "2025-05-23T11:39:30.55Z" }, + { url = "https://files.pythonhosted.org/packages/69/2f/572b29496d8234e4a7773200dd835a0d32d9e171f2d974f3fe04a9dbc271/coverage-7.8.2-pp39.pp310.pp311-none-any.whl", hash = "sha256:ec455eedf3ba0bbdf8f5a570012617eb305c63cb9f03428d39bf544cb2b94837", size = 203636, upload-time = "2025-05-23T11:39:52.002Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1a/0b9c32220ad694d66062f571cc5cedfa9997b64a591e8a500bb63de1bd40/coverage-7.8.2-py3-none-any.whl", hash = "sha256:726f32ee3713f7359696331a18daf0c3b3a70bb0ae71141b9d3c52be7c595e32", size = 203623, upload-time = "2025-05-23T11:39:53.846Z" }, ] [package.optional-dependencies] @@ -788,9 +788,9 @@ dependencies = [ { name = "tomli-w" }, { name = "uv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e7/53/c04da767da6defc6bf6cd2a03f15626441a5eb6079b5ede69059f060d8cb/crewai-0.126.0.tar.gz", hash = "sha256:2dc3a5159ccff8402a150c7242baa475b39c5ecf4652af967e8b430211c64586", size = 103524351 } +sdist = { url = "https://files.pythonhosted.org/packages/e7/53/c04da767da6defc6bf6cd2a03f15626441a5eb6079b5ede69059f060d8cb/crewai-0.126.0.tar.gz", hash = "sha256:2dc3a5159ccff8402a150c7242baa475b39c5ecf4652af967e8b430211c64586", size = 103524351, upload-time = "2025-06-05T00:50:15.306Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/82/a753902c9061eaf8b927d22d068b3ebf3ad1722848e00d9d0c746fe47101/crewai-0.126.0-py3-none-any.whl", hash = "sha256:9c780c1d05ae739c249d96840b136d06e5b41eb63394fa74e26fe378ef7a1d42", size = 321070 }, + { url = "https://files.pythonhosted.org/packages/5a/82/a753902c9061eaf8b927d22d068b3ebf3ad1722848e00d9d0c746fe47101/crewai-0.126.0-py3-none-any.whl", hash = "sha256:9c780c1d05ae739c249d96840b136d06e5b41eb63394fa74e26fe378ef7a1d42", size = 321070, upload-time = "2025-06-05T00:49:25.599Z" }, ] [[package]] @@ -800,53 +800,53 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f6/47/92a8914716f2405f33f1814b97353e3cfa223cd94a77104075d42de3099e/cryptography-45.0.2.tar.gz", hash = "sha256:d784d57b958ffd07e9e226d17272f9af0c41572557604ca7554214def32c26bf", size = 743865 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/2f/46b9e715157643ad16f039ec3c3c47d174da6f825bf5034b1c5f692ab9e2/cryptography-45.0.2-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:61a8b1bbddd9332917485b2453d1de49f142e6334ce1d97b7916d5a85d179c84", size = 7043448 }, - { url = "https://files.pythonhosted.org/packages/90/52/49e6c86278e1b5ec226e96b62322538ccc466306517bf9aad8854116a088/cryptography-45.0.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cc31c66411e14dd70e2f384a9204a859dc25b05e1f303df0f5326691061b839", size = 4201098 }, - { url = "https://files.pythonhosted.org/packages/7b/3a/201272539ac5b66b4cb1af89021e423fc0bfacb73498950280c51695fb78/cryptography-45.0.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:463096533acd5097f8751115bc600b0b64620c4aafcac10c6d0041e6e68f88fe", size = 4429839 }, - { url = "https://files.pythonhosted.org/packages/99/89/fa1a84832b8f8f3917875cb15324bba98def5a70175a889df7d21a45dc75/cryptography-45.0.2-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:cdafb86eb673c3211accffbffdb3cdffa3aaafacd14819e0898d23696d18e4d3", size = 4205154 }, - { url = "https://files.pythonhosted.org/packages/1c/c5/5225d5230d538ab461725711cf5220560a813d1eb68bafcfb00131b8f631/cryptography-45.0.2-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:05c2385b1f5c89a17df19900cfb1345115a77168f5ed44bdf6fd3de1ce5cc65b", size = 3897145 }, - { url = "https://files.pythonhosted.org/packages/fe/24/f19aae32526cc55ae17d473bc4588b1234af2979483d99cbfc57e55ffea6/cryptography-45.0.2-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:e9e4bdcd70216b08801e267c0b563316b787f957a46e215249921f99288456f9", size = 4462192 }, - { url = "https://files.pythonhosted.org/packages/19/18/4a69ac95b0b3f03355970baa6c3f9502bbfc54e7df81fdb179654a00f48e/cryptography-45.0.2-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b2de529027579e43b6dc1f805f467b102fb7d13c1e54c334f1403ee2b37d0059", size = 4208093 }, - { url = "https://files.pythonhosted.org/packages/7c/54/2dea55ccc9558b8fa14f67156250b6ee231e31765601524e4757d0b5db6b/cryptography-45.0.2-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10d68763892a7b19c22508ab57799c4423c7c8cd61d7eee4c5a6a55a46511949", size = 4461819 }, - { url = "https://files.pythonhosted.org/packages/37/f1/1b220fcd5ef4b1f0ff3e59e733b61597505e47f945606cc877adab2c1a17/cryptography-45.0.2-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2a90ce2f0f5b695e4785ac07c19a58244092f3c85d57db6d8eb1a2b26d2aad6", size = 4329202 }, - { url = "https://files.pythonhosted.org/packages/6d/e0/51d1dc4f96f819a56db70f0b4039b4185055bbb8616135884c3c3acc4c6d/cryptography-45.0.2-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:59c0c8f043dd376bbd9d4f636223836aed50431af4c5a467ed9bf61520294627", size = 4570412 }, - { url = "https://files.pythonhosted.org/packages/dc/44/88efb40a3600d15277a77cdc69eeeab45a98532078d2a36cffd9325d3b3f/cryptography-45.0.2-cp311-abi3-win32.whl", hash = "sha256:80303ee6a02ef38c4253160446cbeb5c400c07e01d4ddbd4ff722a89b736d95a", size = 2933584 }, - { url = "https://files.pythonhosted.org/packages/d9/a1/bc9f82ba08760442cc8346d1b4e7b769b86d197193c45b42b3595d231e84/cryptography-45.0.2-cp311-abi3-win_amd64.whl", hash = "sha256:7429936146063bd1b2cfc54f0e04016b90ee9b1c908a7bed0800049cbace70eb", size = 3408537 }, - { url = "https://files.pythonhosted.org/packages/59/bc/1b6acb1dca366f9c0b3880888ecd7fcfb68023930d57df854847c6da1d10/cryptography-45.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:e86c8d54cd19a13e9081898b3c24351683fd39d726ecf8e774aaa9d8d96f5f3a", size = 7025581 }, - { url = "https://files.pythonhosted.org/packages/31/a3/a3e4a298d3db4a04085728f5ae6c8cda157e49c5bb784886d463b9fbff70/cryptography-45.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e328357b6bbf79928363dbf13f4635b7aac0306afb7e5ad24d21d0c5761c3253", size = 4189148 }, - { url = "https://files.pythonhosted.org/packages/53/90/100dfadd4663b389cb56972541ec1103490a19ebad0132af284114ba0868/cryptography-45.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49af56491473231159c98c2c26f1a8f3799a60e5cf0e872d00745b858ddac9d2", size = 4424113 }, - { url = "https://files.pythonhosted.org/packages/0d/40/e2b9177dbed6f3fcbbf1942e1acea2fd15b17007204b79d675540dd053af/cryptography-45.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f169469d04a23282de9d0be349499cb6683b6ff1b68901210faacac9b0c24b7d", size = 4189696 }, - { url = "https://files.pythonhosted.org/packages/70/ae/ec29c79f481e1767c2ff916424ba36f3cf7774de93bbd60428a3c52d1357/cryptography-45.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9cfd1399064b13043082c660ddd97a0358e41c8b0dc7b77c1243e013d305c344", size = 3881498 }, - { url = "https://files.pythonhosted.org/packages/5f/4a/72937090e5637a232b2f73801c9361cd08404a2d4e620ca4ec58c7ea4b70/cryptography-45.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:18f8084b7ca3ce1b8d38bdfe33c48116edf9a08b4d056ef4a96dceaa36d8d965", size = 4451678 }, - { url = "https://files.pythonhosted.org/packages/d3/fa/1377fced81fd67a4a27514248261bb0d45c3c1e02169411fe231583088c8/cryptography-45.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2cb03a944a1a412724d15a7c051d50e63a868031f26b6a312f2016965b661942", size = 4192296 }, - { url = "https://files.pythonhosted.org/packages/d1/cf/b6fe837c83a08b9df81e63299d75fc5b3c6d82cf24b3e1e0e331050e9e5c/cryptography-45.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a9727a21957d3327cf6b7eb5ffc9e4b663909a25fea158e3fcbc49d4cdd7881b", size = 4451749 }, - { url = "https://files.pythonhosted.org/packages/af/d8/5a655675cc635c7190bfc8cffb84bcdc44fc62ce945ad1d844adaa884252/cryptography-45.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ddb8d01aa900b741d6b7cc585a97aff787175f160ab975e21f880e89d810781a", size = 4317601 }, - { url = "https://files.pythonhosted.org/packages/b9/d4/75d2375a20d80aa262a8adee77bf56950e9292929e394b9fae2481803f11/cryptography-45.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:c0c000c1a09f069632d8a9eb3b610ac029fcc682f1d69b758e625d6ee713f4ed", size = 4560535 }, - { url = "https://files.pythonhosted.org/packages/aa/18/c3a94474987ebcfb88692036b2ec44880d243fefa73794bdcbf748679a6e/cryptography-45.0.2-cp37-abi3-win32.whl", hash = "sha256:08281de408e7eb71ba3cd5098709a356bfdf65eebd7ee7633c3610f0aa80d79b", size = 2922045 }, - { url = "https://files.pythonhosted.org/packages/63/63/fb28b30c144182fd44ce93d13ab859791adbf923e43bdfb610024bfecda1/cryptography-45.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:48caa55c528617fa6db1a9c3bf2e37ccb31b73e098ac2b71408d1f2db551dde4", size = 3393321 }, - { url = "https://files.pythonhosted.org/packages/6e/f5/d1d4dead3b269671cda7be6d6b2970b25398e84219681cb397139bdce88b/cryptography-45.0.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a8ec324711596fbf21837d3a5db543937dd84597d364769b46e0102250023f77", size = 3578517 }, - { url = "https://files.pythonhosted.org/packages/ac/7b/00e18d24f08bc642e4018e0066a6f872d85c744e3265910c3beabb1f4d73/cryptography-45.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:965611880c3fa8e504b7458484c0697e00ae6e937279cd6734fdaa2bc954dc49", size = 4135515 }, - { url = "https://files.pythonhosted.org/packages/29/9f/ea7ad5239c33c36f0e2cbdf631a0e3b7633466e87e55923f5b5ea1b0b92d/cryptography-45.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d891942592789fa0ab71b502550bbadb12f540d7413d7d7c4cef4b02af0f5bc6", size = 4378133 }, - { url = "https://files.pythonhosted.org/packages/47/f8/b4e29d87fbc4d2cf46b36e01fcb98305bf76699f34de6b877cddd8bc3a64/cryptography-45.0.2-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b19f4b28dd2ef2e6d600307fee656c00825a2980c4356a7080bd758d633c3a6f", size = 4136787 }, - { url = "https://files.pythonhosted.org/packages/dc/7c/ac19bbf24d261667a67aac712d8aa3bb740f94bc2391f06ccc90e783f3ff/cryptography-45.0.2-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:7c73968fbb7698a4c5d6160859db560d3aac160edde89c751edd5a8bc6560c88", size = 4377741 }, - { url = "https://files.pythonhosted.org/packages/e2/69/51f1c3d03ef4e3bcac4d3f00738f6ac0a205199809e2b92368b6f15a9ec4/cryptography-45.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:501de1296b2041dccf2115e3c7d4947430585601b251b140970ce255c5cfb985", size = 3326934 }, - { url = "https://files.pythonhosted.org/packages/d7/74/2a0fb642c4c34d8c46c12b6eac89b10769b378c7b6a901ff94a8d4ba1b52/cryptography-45.0.2-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1655d3a76e3dedb683c982a6c3a2cbfae2d08f47a48ec5a3d58db52b3d29ea6f", size = 3587805 }, - { url = "https://files.pythonhosted.org/packages/8a/18/57bc98fa5d93e74c2c2b16a3c5383f7ec218f957aa44559c0008a46c3629/cryptography-45.0.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc7693573f16535428183de8fd27f0ca1ca37a51baa0b41dc5ed7b3d68fe80e2", size = 4143347 }, - { url = "https://files.pythonhosted.org/packages/84/6f/d015e7e7bd7f3a6c538973005de5a780d93b68138c2d88c804422cf46b1c/cryptography-45.0.2-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:614bca7c6ed0d8ad1dce683a6289afae1f880675b4090878a0136c3da16bc693", size = 4387414 }, - { url = "https://files.pythonhosted.org/packages/de/9e/fa5ec89cce7e4b86e430438da4d66b79113bdf321d0a00167d34b61daf19/cryptography-45.0.2-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:4142e20c29224cec63e9e32eb1e6014fb285fe39b7be66b3564ca978a3a8afe9", size = 4145849 }, - { url = "https://files.pythonhosted.org/packages/7c/09/5887d4fcc6f9c6fb19920789d094c4e25c2f604cc1b10b7e69d6f56187fe/cryptography-45.0.2-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:9a900036b42f7324df7c7ad9569eb92ba0b613cf699160dd9c2154b24fd02f8e", size = 4387449 }, - { url = "https://files.pythonhosted.org/packages/a5/4a/e27ab71dc3e517becc3f2ae358454bb4b78c0cb5af52f8e11b8943525ea6/cryptography-45.0.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:057723b79752a142efbc609e90b0dff27b0361ccbee3bd48312d70f5cdf53b78", size = 3335090 }, +sdist = { url = "https://files.pythonhosted.org/packages/f6/47/92a8914716f2405f33f1814b97353e3cfa223cd94a77104075d42de3099e/cryptography-45.0.2.tar.gz", hash = "sha256:d784d57b958ffd07e9e226d17272f9af0c41572557604ca7554214def32c26bf", size = 743865, upload-time = "2025-05-18T02:46:34.986Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/2f/46b9e715157643ad16f039ec3c3c47d174da6f825bf5034b1c5f692ab9e2/cryptography-45.0.2-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:61a8b1bbddd9332917485b2453d1de49f142e6334ce1d97b7916d5a85d179c84", size = 7043448, upload-time = "2025-05-18T02:45:12.495Z" }, + { url = "https://files.pythonhosted.org/packages/90/52/49e6c86278e1b5ec226e96b62322538ccc466306517bf9aad8854116a088/cryptography-45.0.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cc31c66411e14dd70e2f384a9204a859dc25b05e1f303df0f5326691061b839", size = 4201098, upload-time = "2025-05-18T02:45:15.178Z" }, + { url = "https://files.pythonhosted.org/packages/7b/3a/201272539ac5b66b4cb1af89021e423fc0bfacb73498950280c51695fb78/cryptography-45.0.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:463096533acd5097f8751115bc600b0b64620c4aafcac10c6d0041e6e68f88fe", size = 4429839, upload-time = "2025-05-18T02:45:17.614Z" }, + { url = "https://files.pythonhosted.org/packages/99/89/fa1a84832b8f8f3917875cb15324bba98def5a70175a889df7d21a45dc75/cryptography-45.0.2-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:cdafb86eb673c3211accffbffdb3cdffa3aaafacd14819e0898d23696d18e4d3", size = 4205154, upload-time = "2025-05-18T02:45:19.874Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c5/5225d5230d538ab461725711cf5220560a813d1eb68bafcfb00131b8f631/cryptography-45.0.2-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:05c2385b1f5c89a17df19900cfb1345115a77168f5ed44bdf6fd3de1ce5cc65b", size = 3897145, upload-time = "2025-05-18T02:45:22.209Z" }, + { url = "https://files.pythonhosted.org/packages/fe/24/f19aae32526cc55ae17d473bc4588b1234af2979483d99cbfc57e55ffea6/cryptography-45.0.2-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:e9e4bdcd70216b08801e267c0b563316b787f957a46e215249921f99288456f9", size = 4462192, upload-time = "2025-05-18T02:45:24.773Z" }, + { url = "https://files.pythonhosted.org/packages/19/18/4a69ac95b0b3f03355970baa6c3f9502bbfc54e7df81fdb179654a00f48e/cryptography-45.0.2-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b2de529027579e43b6dc1f805f467b102fb7d13c1e54c334f1403ee2b37d0059", size = 4208093, upload-time = "2025-05-18T02:45:27.028Z" }, + { url = "https://files.pythonhosted.org/packages/7c/54/2dea55ccc9558b8fa14f67156250b6ee231e31765601524e4757d0b5db6b/cryptography-45.0.2-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10d68763892a7b19c22508ab57799c4423c7c8cd61d7eee4c5a6a55a46511949", size = 4461819, upload-time = "2025-05-18T02:45:29.39Z" }, + { url = "https://files.pythonhosted.org/packages/37/f1/1b220fcd5ef4b1f0ff3e59e733b61597505e47f945606cc877adab2c1a17/cryptography-45.0.2-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2a90ce2f0f5b695e4785ac07c19a58244092f3c85d57db6d8eb1a2b26d2aad6", size = 4329202, upload-time = "2025-05-18T02:45:31.925Z" }, + { url = "https://files.pythonhosted.org/packages/6d/e0/51d1dc4f96f819a56db70f0b4039b4185055bbb8616135884c3c3acc4c6d/cryptography-45.0.2-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:59c0c8f043dd376bbd9d4f636223836aed50431af4c5a467ed9bf61520294627", size = 4570412, upload-time = "2025-05-18T02:45:34.348Z" }, + { url = "https://files.pythonhosted.org/packages/dc/44/88efb40a3600d15277a77cdc69eeeab45a98532078d2a36cffd9325d3b3f/cryptography-45.0.2-cp311-abi3-win32.whl", hash = "sha256:80303ee6a02ef38c4253160446cbeb5c400c07e01d4ddbd4ff722a89b736d95a", size = 2933584, upload-time = "2025-05-18T02:45:36.198Z" }, + { url = "https://files.pythonhosted.org/packages/d9/a1/bc9f82ba08760442cc8346d1b4e7b769b86d197193c45b42b3595d231e84/cryptography-45.0.2-cp311-abi3-win_amd64.whl", hash = "sha256:7429936146063bd1b2cfc54f0e04016b90ee9b1c908a7bed0800049cbace70eb", size = 3408537, upload-time = "2025-05-18T02:45:38.184Z" }, + { url = "https://files.pythonhosted.org/packages/59/bc/1b6acb1dca366f9c0b3880888ecd7fcfb68023930d57df854847c6da1d10/cryptography-45.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:e86c8d54cd19a13e9081898b3c24351683fd39d726ecf8e774aaa9d8d96f5f3a", size = 7025581, upload-time = "2025-05-18T02:45:40.632Z" }, + { url = "https://files.pythonhosted.org/packages/31/a3/a3e4a298d3db4a04085728f5ae6c8cda157e49c5bb784886d463b9fbff70/cryptography-45.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e328357b6bbf79928363dbf13f4635b7aac0306afb7e5ad24d21d0c5761c3253", size = 4189148, upload-time = "2025-05-18T02:45:42.538Z" }, + { url = "https://files.pythonhosted.org/packages/53/90/100dfadd4663b389cb56972541ec1103490a19ebad0132af284114ba0868/cryptography-45.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49af56491473231159c98c2c26f1a8f3799a60e5cf0e872d00745b858ddac9d2", size = 4424113, upload-time = "2025-05-18T02:45:44.316Z" }, + { url = "https://files.pythonhosted.org/packages/0d/40/e2b9177dbed6f3fcbbf1942e1acea2fd15b17007204b79d675540dd053af/cryptography-45.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f169469d04a23282de9d0be349499cb6683b6ff1b68901210faacac9b0c24b7d", size = 4189696, upload-time = "2025-05-18T02:45:46.622Z" }, + { url = "https://files.pythonhosted.org/packages/70/ae/ec29c79f481e1767c2ff916424ba36f3cf7774de93bbd60428a3c52d1357/cryptography-45.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9cfd1399064b13043082c660ddd97a0358e41c8b0dc7b77c1243e013d305c344", size = 3881498, upload-time = "2025-05-18T02:45:48.884Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4a/72937090e5637a232b2f73801c9361cd08404a2d4e620ca4ec58c7ea4b70/cryptography-45.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:18f8084b7ca3ce1b8d38bdfe33c48116edf9a08b4d056ef4a96dceaa36d8d965", size = 4451678, upload-time = "2025-05-18T02:45:50.706Z" }, + { url = "https://files.pythonhosted.org/packages/d3/fa/1377fced81fd67a4a27514248261bb0d45c3c1e02169411fe231583088c8/cryptography-45.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2cb03a944a1a412724d15a7c051d50e63a868031f26b6a312f2016965b661942", size = 4192296, upload-time = "2025-05-18T02:45:52.422Z" }, + { url = "https://files.pythonhosted.org/packages/d1/cf/b6fe837c83a08b9df81e63299d75fc5b3c6d82cf24b3e1e0e331050e9e5c/cryptography-45.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a9727a21957d3327cf6b7eb5ffc9e4b663909a25fea158e3fcbc49d4cdd7881b", size = 4451749, upload-time = "2025-05-18T02:45:55.025Z" }, + { url = "https://files.pythonhosted.org/packages/af/d8/5a655675cc635c7190bfc8cffb84bcdc44fc62ce945ad1d844adaa884252/cryptography-45.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ddb8d01aa900b741d6b7cc585a97aff787175f160ab975e21f880e89d810781a", size = 4317601, upload-time = "2025-05-18T02:45:56.911Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d4/75d2375a20d80aa262a8adee77bf56950e9292929e394b9fae2481803f11/cryptography-45.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:c0c000c1a09f069632d8a9eb3b610ac029fcc682f1d69b758e625d6ee713f4ed", size = 4560535, upload-time = "2025-05-18T02:45:59.33Z" }, + { url = "https://files.pythonhosted.org/packages/aa/18/c3a94474987ebcfb88692036b2ec44880d243fefa73794bdcbf748679a6e/cryptography-45.0.2-cp37-abi3-win32.whl", hash = "sha256:08281de408e7eb71ba3cd5098709a356bfdf65eebd7ee7633c3610f0aa80d79b", size = 2922045, upload-time = "2025-05-18T02:46:01.012Z" }, + { url = "https://files.pythonhosted.org/packages/63/63/fb28b30c144182fd44ce93d13ab859791adbf923e43bdfb610024bfecda1/cryptography-45.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:48caa55c528617fa6db1a9c3bf2e37ccb31b73e098ac2b71408d1f2db551dde4", size = 3393321, upload-time = "2025-05-18T02:46:03.441Z" }, + { url = "https://files.pythonhosted.org/packages/6e/f5/d1d4dead3b269671cda7be6d6b2970b25398e84219681cb397139bdce88b/cryptography-45.0.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a8ec324711596fbf21837d3a5db543937dd84597d364769b46e0102250023f77", size = 3578517, upload-time = "2025-05-18T02:46:05.263Z" }, + { url = "https://files.pythonhosted.org/packages/ac/7b/00e18d24f08bc642e4018e0066a6f872d85c744e3265910c3beabb1f4d73/cryptography-45.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:965611880c3fa8e504b7458484c0697e00ae6e937279cd6734fdaa2bc954dc49", size = 4135515, upload-time = "2025-05-18T02:46:07.241Z" }, + { url = "https://files.pythonhosted.org/packages/29/9f/ea7ad5239c33c36f0e2cbdf631a0e3b7633466e87e55923f5b5ea1b0b92d/cryptography-45.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d891942592789fa0ab71b502550bbadb12f540d7413d7d7c4cef4b02af0f5bc6", size = 4378133, upload-time = "2025-05-18T02:46:09.035Z" }, + { url = "https://files.pythonhosted.org/packages/47/f8/b4e29d87fbc4d2cf46b36e01fcb98305bf76699f34de6b877cddd8bc3a64/cryptography-45.0.2-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b19f4b28dd2ef2e6d600307fee656c00825a2980c4356a7080bd758d633c3a6f", size = 4136787, upload-time = "2025-05-18T02:46:10.772Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7c/ac19bbf24d261667a67aac712d8aa3bb740f94bc2391f06ccc90e783f3ff/cryptography-45.0.2-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:7c73968fbb7698a4c5d6160859db560d3aac160edde89c751edd5a8bc6560c88", size = 4377741, upload-time = "2025-05-18T02:46:13.215Z" }, + { url = "https://files.pythonhosted.org/packages/e2/69/51f1c3d03ef4e3bcac4d3f00738f6ac0a205199809e2b92368b6f15a9ec4/cryptography-45.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:501de1296b2041dccf2115e3c7d4947430585601b251b140970ce255c5cfb985", size = 3326934, upload-time = "2025-05-18T02:46:15.081Z" }, + { url = "https://files.pythonhosted.org/packages/d7/74/2a0fb642c4c34d8c46c12b6eac89b10769b378c7b6a901ff94a8d4ba1b52/cryptography-45.0.2-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1655d3a76e3dedb683c982a6c3a2cbfae2d08f47a48ec5a3d58db52b3d29ea6f", size = 3587805, upload-time = "2025-05-18T02:46:17.531Z" }, + { url = "https://files.pythonhosted.org/packages/8a/18/57bc98fa5d93e74c2c2b16a3c5383f7ec218f957aa44559c0008a46c3629/cryptography-45.0.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc7693573f16535428183de8fd27f0ca1ca37a51baa0b41dc5ed7b3d68fe80e2", size = 4143347, upload-time = "2025-05-18T02:46:19.934Z" }, + { url = "https://files.pythonhosted.org/packages/84/6f/d015e7e7bd7f3a6c538973005de5a780d93b68138c2d88c804422cf46b1c/cryptography-45.0.2-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:614bca7c6ed0d8ad1dce683a6289afae1f880675b4090878a0136c3da16bc693", size = 4387414, upload-time = "2025-05-18T02:46:21.944Z" }, + { url = "https://files.pythonhosted.org/packages/de/9e/fa5ec89cce7e4b86e430438da4d66b79113bdf321d0a00167d34b61daf19/cryptography-45.0.2-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:4142e20c29224cec63e9e32eb1e6014fb285fe39b7be66b3564ca978a3a8afe9", size = 4145849, upload-time = "2025-05-18T02:46:24.327Z" }, + { url = "https://files.pythonhosted.org/packages/7c/09/5887d4fcc6f9c6fb19920789d094c4e25c2f604cc1b10b7e69d6f56187fe/cryptography-45.0.2-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:9a900036b42f7324df7c7ad9569eb92ba0b613cf699160dd9c2154b24fd02f8e", size = 4387449, upload-time = "2025-05-18T02:46:26.144Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4a/e27ab71dc3e517becc3f2ae358454bb4b78c0cb5af52f8e11b8943525ea6/cryptography-45.0.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:057723b79752a142efbc609e90b0dff27b0361ccbee3bd48312d70f5cdf53b78", size = 3335090, upload-time = "2025-05-18T02:46:27.913Z" }, ] [[package]] name = "decorator" version = "5.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711 } +sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190 }, + { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, ] [[package]] @@ -856,54 +856,54 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/98/97/06afe62762c9a8a86af0cfb7bfdab22a43ad17138b07af5b1a58442690a2/deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d", size = 2928744 } +sdist = { url = "https://files.pythonhosted.org/packages/98/97/06afe62762c9a8a86af0cfb7bfdab22a43ad17138b07af5b1a58442690a2/deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d", size = 2928744, upload-time = "2025-01-27T10:46:25.7Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec", size = 9998 }, + { url = "https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec", size = 9998, upload-time = "2025-01-27T10:46:09.186Z" }, ] [[package]] name = "distlib" version = "0.3.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923 } +sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923, upload-time = "2024-10-09T18:35:47.551Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 }, + { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973, upload-time = "2024-10-09T18:35:44.272Z" }, ] [[package]] name = "distro" version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722 } +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/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277 }, + { 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 = "docstring-parser" version = "0.16" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/08/12/9c22a58c0b1e29271051222d8906257616da84135af9ed167c9e28f85cb3/docstring_parser-0.16.tar.gz", hash = "sha256:538beabd0af1e2db0146b6bd3caa526c35a34d61af9fd2887f3a8a27a739aa6e", size = 26565 } +sdist = { url = "https://files.pythonhosted.org/packages/08/12/9c22a58c0b1e29271051222d8906257616da84135af9ed167c9e28f85cb3/docstring_parser-0.16.tar.gz", hash = "sha256:538beabd0af1e2db0146b6bd3caa526c35a34d61af9fd2887f3a8a27a739aa6e", size = 26565, upload-time = "2024-03-15T10:39:44.419Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/7c/e9fcff7623954d86bdc17782036cbf715ecab1bec4847c008557affe1ca8/docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637", size = 36533 }, + { url = "https://files.pythonhosted.org/packages/d5/7c/e9fcff7623954d86bdc17782036cbf715ecab1bec4847c008557affe1ca8/docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637", size = 36533, upload-time = "2024-03-15T10:39:41.527Z" }, ] [[package]] name = "durationpy" version = "0.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/a4/e44218c2b394e31a6dd0d6b095c4e1f32d0be54c2a4b250032d717647bab/durationpy-0.10.tar.gz", hash = "sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba", size = 3335 } +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/b0/0d/9feae160378a3553fa9a339b0e9c1a048e147a4127210e286ef18b730f03/durationpy-0.10-py3-none-any.whl", hash = "sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286", size = 3922 }, + { 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 = "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 } +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 }, + { 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]] @@ -913,18 +913,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749 } +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674 }, + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, ] [[package]] name = "executing" version = "2.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755", size = 978693 } +sdist = { url = "https://files.pythonhosted.org/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755", size = 978693, upload-time = "2025-01-22T15:41:29.403Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702 }, + { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702, upload-time = "2025-01-22T15:41:25.929Z" }, ] [[package]] @@ -936,167 +936,167 @@ dependencies = [ { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236 } +sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236, upload-time = "2025-03-23T22:55:43.822Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164 }, + { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164, upload-time = "2025-03-23T22:55:42.101Z" }, ] [[package]] name = "fastavro" version = "1.11.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/48/8f/32664a3245247b13702d13d2657ea534daf64e58a3f72a3a2d10598d6916/fastavro-1.11.1.tar.gz", hash = "sha256:bf6acde5ee633a29fb8dfd6dfea13b164722bc3adc05a0e055df080549c1c2f8", size = 1016250 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ae/be/53df3fec7fdabc1848896a76afb0f01ab96b58abb29611aa68a994290167/fastavro-1.11.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:603aa1c1d1be21fb4bcb63e1efb0711a9ddb337de81391c32dac95c6e0dacfcc", size = 944225 }, - { url = "https://files.pythonhosted.org/packages/d0/cc/c7c76a082fbf5aaaf82ab7da7b9ede6fc99eb8f008c084c67d230b29c446/fastavro-1.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45653b312d4ce297e2bd802ea3ffd17ecbe718e5e8b6e2ae04cd72cb50bb99d5", size = 3105189 }, - { url = "https://files.pythonhosted.org/packages/48/ff/5f1f0b5e3835e788ba8121d6dd6426cd4c6e58ce1bff02cb7810278648b0/fastavro-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:998a53fc552e6bee9acda32af258f02557313c85fb5b48becba5b71ec82f421e", size = 3113124 }, - { url = "https://files.pythonhosted.org/packages/e5/b8/1ac01433b55460dabeb6d3fbb05ba1c971d57137041e8f53b2e9f46cd033/fastavro-1.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9f878c9ad819467120cb066f1c73496c42eb24ecdd7c992ec996f465ef4cedad", size = 3155196 }, - { url = "https://files.pythonhosted.org/packages/5e/a8/66e599b946ead031a5caba12772e614a7802d95476e8732e2e9481369973/fastavro-1.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da9e4c231ac4951092c2230ca423d8a3f2966718f072ac1e2c5d2d44c70b2a50", size = 3229028 }, - { url = "https://files.pythonhosted.org/packages/0e/e7/17c35e2dfe8a9e4f3735eabdeec366b0edc4041bb1a84fcd528c8efd12af/fastavro-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:7423bfad3199567eeee7ad6816402c7c0ee1658b959e8c10540cfbc60ce96c2a", size = 449177 }, - { url = "https://files.pythonhosted.org/packages/8e/63/f33d6fd50d8711f305f07ad8c7b4a25f2092288f376f484c979dcf277b07/fastavro-1.11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3573340e4564e8962e22f814ac937ffe0d4be5eabbd2250f77738dc47e3c8fe9", size = 957526 }, - { url = "https://files.pythonhosted.org/packages/f4/09/a57ad9d8cb9b8affb2e43c29d8fb8cbdc0f1156f8496067a0712c944bacc/fastavro-1.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7291cf47735b8bd6ff5d9b33120e6e0974f52fd5dff90cd24151b22018e7fd29", size = 3322808 }, - { url = "https://files.pythonhosted.org/packages/86/70/d6df59309d3754d6d4b0c7beca45b9b1a957d6725aed8da3aca247db3475/fastavro-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf3bb065d657d5bac8b2cb39945194aa086a9b3354f2da7f89c30e4dc20e08e2", size = 3330870 }, - { url = "https://files.pythonhosted.org/packages/ad/ea/122315154d2a799a2787058435ef0d4d289c0e8e575245419436e9b702ca/fastavro-1.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8758317c85296b848698132efb13bc44a4fbd6017431cc0f26eaeb0d6fa13d35", size = 3343369 }, - { url = "https://files.pythonhosted.org/packages/62/12/7800de5fec36d55a818adf3db3b085b1a033c4edd60323cf6ca0754cf8cb/fastavro-1.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ad99d57228f83bf3e2214d183fbf6e2fda97fd649b2bdaf8e9110c36cbb02624", size = 3430629 }, - { url = "https://files.pythonhosted.org/packages/48/65/2b74ccfeba9dcc3f7dbe64907307386b4a0af3f71d2846f63254df0f1e1d/fastavro-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:9134090178bdbf9eefd467717ced3dc151e27a7e7bfc728260ce512697efe5a4", size = 451621 }, - { url = "https://files.pythonhosted.org/packages/99/58/8e789b0a2f532b22e2d090c20d27c88f26a5faadcba4c445c6958ae566cf/fastavro-1.11.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e8bc238f2637cd5d15238adbe8fb8c58d2e6f1870e0fb28d89508584670bae4b", size = 939583 }, - { url = "https://files.pythonhosted.org/packages/34/3f/02ed44742b1224fe23c9fc9b9b037fc61769df716c083cf80b59a02b9785/fastavro-1.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b403933081c83fc4d8a012ee64b86e560a024b1280e3711ee74f2abc904886e8", size = 3257734 }, - { url = "https://files.pythonhosted.org/packages/cc/bc/9cc8b19eeee9039dd49719f8b4020771e805def262435f823fa8f27ddeea/fastavro-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f6ecb4b5f77aa756d973b7dd1c2fb4e4c95b4832a3c98b059aa96c61870c709", size = 3318218 }, - { url = "https://files.pythonhosted.org/packages/39/77/3b73a986606494596b6d3032eadf813a05b59d1623f54384a23de4217d5f/fastavro-1.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:059893df63ef823b0231b485c9d43016c7e32850cae7bf69f4e9d46dd41c28f2", size = 3297296 }, - { url = "https://files.pythonhosted.org/packages/8e/1c/b69ceef6494bd0df14752b5d8648b159ad52566127bfd575e9f5ecc0c092/fastavro-1.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5120ffc9a200699218e01777e695a2f08afb3547ba818184198c757dc39417bd", size = 3438056 }, - { url = "https://files.pythonhosted.org/packages/ef/11/5c2d0db3bd0e6407546fabae9e267bb0824eacfeba79e7dd81ad88afa27d/fastavro-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:7bb9d0d2233f33a52908b6ea9b376fe0baf1144bdfdfb3c6ad326e200a8b56b0", size = 442824 }, - { url = "https://files.pythonhosted.org/packages/ec/08/8e25b9e87a98f8c96b25e64565fa1a1208c0095bb6a84a5c8a4b925688a5/fastavro-1.11.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f963b8ddaf179660e814ab420850c1b4ea33e2ad2de8011549d958b21f77f20a", size = 931520 }, - { url = "https://files.pythonhosted.org/packages/02/ee/7cf5561ef94781ed6942cee6b394a5e698080f4247f00f158ee396ec244d/fastavro-1.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0253e5b6a3c9b62fae9fc3abd8184c5b64a833322b6af7d666d3db266ad879b5", size = 3195989 }, - { url = "https://files.pythonhosted.org/packages/b3/31/f02f097d79f090e5c5aca8a743010c4e833a257c0efdeb289c68294f7928/fastavro-1.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca637b150e1f4c0e8e564fad40a16bd922bcb7ffd1a6e4836e6084f2c4f4e8db", size = 3239755 }, - { url = "https://files.pythonhosted.org/packages/09/4c/46626b4ee4eb8eb5aa7835973c6ba8890cf082ef2daface6071e788d2992/fastavro-1.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76af1709031621828ca6ce7f027f7711fa33ac23e8269e7a5733996ff8d318da", size = 3243788 }, - { url = "https://files.pythonhosted.org/packages/a7/6f/8ed42524e9e8dc0554f0f211dd1c6c7a9dde83b95388ddcf7c137e70796f/fastavro-1.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8224e6d8d9864d4e55dafbe88920d6a1b8c19cc3006acfac6aa4f494a6af3450", size = 3378330 }, - { url = "https://files.pythonhosted.org/packages/b8/51/38cbe243d5facccab40fc43a4c17db264c261be955ce003803d25f0da2c3/fastavro-1.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:cde7ed91b52ff21f0f9f157329760ba7251508ca3e9618af3ffdac986d9faaa2", size = 443115 }, - { url = "https://files.pythonhosted.org/packages/d0/57/0d31ed1a49c65ad9f0f0128d9a928972878017781f9d4336f5f60982334c/fastavro-1.11.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e5ed1325c1c414dd954e7a2c5074daefe1eceb672b8c727aa030ba327aa00693", size = 1021401 }, - { url = "https://files.pythonhosted.org/packages/56/7a/a3f1a75fbfc16b3eff65dc0efcdb92364967923194312b3f8c8fc2cb95be/fastavro-1.11.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cd3c95baeec37188899824faf44a5ee94dfc4d8667b05b2f867070c7eb174c4", size = 3384349 }, - { url = "https://files.pythonhosted.org/packages/be/84/02bceb7518867df84027232a75225db758b9b45f12017c9743f45b73101e/fastavro-1.11.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e0babcd81acceb4c60110af9efa25d890dbb68f7de880f806dadeb1e70fe413", size = 3240658 }, - { url = "https://files.pythonhosted.org/packages/f2/17/508c846c644d39bc432b027112068b8e96e7560468304d4c0757539dd73a/fastavro-1.11.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b2c0cb8063c7208b53b6867983dc6ae7cc80b91116b51d435d2610a5db2fc52f", size = 3372809 }, - { url = "https://files.pythonhosted.org/packages/fe/84/9c2917a70ed570ddbfd1d32ac23200c1d011e36c332e59950d2f6d204941/fastavro-1.11.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1bc2824e9969c04ab6263d269a1e0e5d40b9bd16ade6b70c29d6ffbc4f3cc102", size = 3387171 }, +sdist = { url = "https://files.pythonhosted.org/packages/48/8f/32664a3245247b13702d13d2657ea534daf64e58a3f72a3a2d10598d6916/fastavro-1.11.1.tar.gz", hash = "sha256:bf6acde5ee633a29fb8dfd6dfea13b164722bc3adc05a0e055df080549c1c2f8", size = 1016250, upload-time = "2025-05-18T04:54:31.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/be/53df3fec7fdabc1848896a76afb0f01ab96b58abb29611aa68a994290167/fastavro-1.11.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:603aa1c1d1be21fb4bcb63e1efb0711a9ddb337de81391c32dac95c6e0dacfcc", size = 944225, upload-time = "2025-05-18T04:54:34.586Z" }, + { url = "https://files.pythonhosted.org/packages/d0/cc/c7c76a082fbf5aaaf82ab7da7b9ede6fc99eb8f008c084c67d230b29c446/fastavro-1.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45653b312d4ce297e2bd802ea3ffd17ecbe718e5e8b6e2ae04cd72cb50bb99d5", size = 3105189, upload-time = "2025-05-18T04:54:36.855Z" }, + { url = "https://files.pythonhosted.org/packages/48/ff/5f1f0b5e3835e788ba8121d6dd6426cd4c6e58ce1bff02cb7810278648b0/fastavro-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:998a53fc552e6bee9acda32af258f02557313c85fb5b48becba5b71ec82f421e", size = 3113124, upload-time = "2025-05-18T04:54:40.013Z" }, + { url = "https://files.pythonhosted.org/packages/e5/b8/1ac01433b55460dabeb6d3fbb05ba1c971d57137041e8f53b2e9f46cd033/fastavro-1.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9f878c9ad819467120cb066f1c73496c42eb24ecdd7c992ec996f465ef4cedad", size = 3155196, upload-time = "2025-05-18T04:54:42.307Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a8/66e599b946ead031a5caba12772e614a7802d95476e8732e2e9481369973/fastavro-1.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da9e4c231ac4951092c2230ca423d8a3f2966718f072ac1e2c5d2d44c70b2a50", size = 3229028, upload-time = "2025-05-18T04:54:44.503Z" }, + { url = "https://files.pythonhosted.org/packages/0e/e7/17c35e2dfe8a9e4f3735eabdeec366b0edc4041bb1a84fcd528c8efd12af/fastavro-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:7423bfad3199567eeee7ad6816402c7c0ee1658b959e8c10540cfbc60ce96c2a", size = 449177, upload-time = "2025-05-18T04:54:46.127Z" }, + { url = "https://files.pythonhosted.org/packages/8e/63/f33d6fd50d8711f305f07ad8c7b4a25f2092288f376f484c979dcf277b07/fastavro-1.11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3573340e4564e8962e22f814ac937ffe0d4be5eabbd2250f77738dc47e3c8fe9", size = 957526, upload-time = "2025-05-18T04:54:47.701Z" }, + { url = "https://files.pythonhosted.org/packages/f4/09/a57ad9d8cb9b8affb2e43c29d8fb8cbdc0f1156f8496067a0712c944bacc/fastavro-1.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7291cf47735b8bd6ff5d9b33120e6e0974f52fd5dff90cd24151b22018e7fd29", size = 3322808, upload-time = "2025-05-18T04:54:50.419Z" }, + { url = "https://files.pythonhosted.org/packages/86/70/d6df59309d3754d6d4b0c7beca45b9b1a957d6725aed8da3aca247db3475/fastavro-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf3bb065d657d5bac8b2cb39945194aa086a9b3354f2da7f89c30e4dc20e08e2", size = 3330870, upload-time = "2025-05-18T04:54:52.406Z" }, + { url = "https://files.pythonhosted.org/packages/ad/ea/122315154d2a799a2787058435ef0d4d289c0e8e575245419436e9b702ca/fastavro-1.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8758317c85296b848698132efb13bc44a4fbd6017431cc0f26eaeb0d6fa13d35", size = 3343369, upload-time = "2025-05-18T04:54:54.652Z" }, + { url = "https://files.pythonhosted.org/packages/62/12/7800de5fec36d55a818adf3db3b085b1a033c4edd60323cf6ca0754cf8cb/fastavro-1.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ad99d57228f83bf3e2214d183fbf6e2fda97fd649b2bdaf8e9110c36cbb02624", size = 3430629, upload-time = "2025-05-18T04:54:56.513Z" }, + { url = "https://files.pythonhosted.org/packages/48/65/2b74ccfeba9dcc3f7dbe64907307386b4a0af3f71d2846f63254df0f1e1d/fastavro-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:9134090178bdbf9eefd467717ced3dc151e27a7e7bfc728260ce512697efe5a4", size = 451621, upload-time = "2025-05-18T04:54:58.156Z" }, + { url = "https://files.pythonhosted.org/packages/99/58/8e789b0a2f532b22e2d090c20d27c88f26a5faadcba4c445c6958ae566cf/fastavro-1.11.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e8bc238f2637cd5d15238adbe8fb8c58d2e6f1870e0fb28d89508584670bae4b", size = 939583, upload-time = "2025-05-18T04:54:59.853Z" }, + { url = "https://files.pythonhosted.org/packages/34/3f/02ed44742b1224fe23c9fc9b9b037fc61769df716c083cf80b59a02b9785/fastavro-1.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b403933081c83fc4d8a012ee64b86e560a024b1280e3711ee74f2abc904886e8", size = 3257734, upload-time = "2025-05-18T04:55:02.366Z" }, + { url = "https://files.pythonhosted.org/packages/cc/bc/9cc8b19eeee9039dd49719f8b4020771e805def262435f823fa8f27ddeea/fastavro-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f6ecb4b5f77aa756d973b7dd1c2fb4e4c95b4832a3c98b059aa96c61870c709", size = 3318218, upload-time = "2025-05-18T04:55:04.352Z" }, + { url = "https://files.pythonhosted.org/packages/39/77/3b73a986606494596b6d3032eadf813a05b59d1623f54384a23de4217d5f/fastavro-1.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:059893df63ef823b0231b485c9d43016c7e32850cae7bf69f4e9d46dd41c28f2", size = 3297296, upload-time = "2025-05-18T04:55:06.175Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1c/b69ceef6494bd0df14752b5d8648b159ad52566127bfd575e9f5ecc0c092/fastavro-1.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5120ffc9a200699218e01777e695a2f08afb3547ba818184198c757dc39417bd", size = 3438056, upload-time = "2025-05-18T04:55:08.276Z" }, + { url = "https://files.pythonhosted.org/packages/ef/11/5c2d0db3bd0e6407546fabae9e267bb0824eacfeba79e7dd81ad88afa27d/fastavro-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:7bb9d0d2233f33a52908b6ea9b376fe0baf1144bdfdfb3c6ad326e200a8b56b0", size = 442824, upload-time = "2025-05-18T04:55:10.385Z" }, + { url = "https://files.pythonhosted.org/packages/ec/08/8e25b9e87a98f8c96b25e64565fa1a1208c0095bb6a84a5c8a4b925688a5/fastavro-1.11.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f963b8ddaf179660e814ab420850c1b4ea33e2ad2de8011549d958b21f77f20a", size = 931520, upload-time = "2025-05-18T04:55:11.614Z" }, + { url = "https://files.pythonhosted.org/packages/02/ee/7cf5561ef94781ed6942cee6b394a5e698080f4247f00f158ee396ec244d/fastavro-1.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0253e5b6a3c9b62fae9fc3abd8184c5b64a833322b6af7d666d3db266ad879b5", size = 3195989, upload-time = "2025-05-18T04:55:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/b3/31/f02f097d79f090e5c5aca8a743010c4e833a257c0efdeb289c68294f7928/fastavro-1.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca637b150e1f4c0e8e564fad40a16bd922bcb7ffd1a6e4836e6084f2c4f4e8db", size = 3239755, upload-time = "2025-05-18T04:55:16.463Z" }, + { url = "https://files.pythonhosted.org/packages/09/4c/46626b4ee4eb8eb5aa7835973c6ba8890cf082ef2daface6071e788d2992/fastavro-1.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76af1709031621828ca6ce7f027f7711fa33ac23e8269e7a5733996ff8d318da", size = 3243788, upload-time = "2025-05-18T04:55:18.544Z" }, + { url = "https://files.pythonhosted.org/packages/a7/6f/8ed42524e9e8dc0554f0f211dd1c6c7a9dde83b95388ddcf7c137e70796f/fastavro-1.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8224e6d8d9864d4e55dafbe88920d6a1b8c19cc3006acfac6aa4f494a6af3450", size = 3378330, upload-time = "2025-05-18T04:55:20.887Z" }, + { url = "https://files.pythonhosted.org/packages/b8/51/38cbe243d5facccab40fc43a4c17db264c261be955ce003803d25f0da2c3/fastavro-1.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:cde7ed91b52ff21f0f9f157329760ba7251508ca3e9618af3ffdac986d9faaa2", size = 443115, upload-time = "2025-05-18T04:55:22.107Z" }, + { url = "https://files.pythonhosted.org/packages/d0/57/0d31ed1a49c65ad9f0f0128d9a928972878017781f9d4336f5f60982334c/fastavro-1.11.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e5ed1325c1c414dd954e7a2c5074daefe1eceb672b8c727aa030ba327aa00693", size = 1021401, upload-time = "2025-05-18T04:55:23.431Z" }, + { url = "https://files.pythonhosted.org/packages/56/7a/a3f1a75fbfc16b3eff65dc0efcdb92364967923194312b3f8c8fc2cb95be/fastavro-1.11.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cd3c95baeec37188899824faf44a5ee94dfc4d8667b05b2f867070c7eb174c4", size = 3384349, upload-time = "2025-05-18T04:55:25.575Z" }, + { url = "https://files.pythonhosted.org/packages/be/84/02bceb7518867df84027232a75225db758b9b45f12017c9743f45b73101e/fastavro-1.11.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e0babcd81acceb4c60110af9efa25d890dbb68f7de880f806dadeb1e70fe413", size = 3240658, upload-time = "2025-05-18T04:55:27.633Z" }, + { url = "https://files.pythonhosted.org/packages/f2/17/508c846c644d39bc432b027112068b8e96e7560468304d4c0757539dd73a/fastavro-1.11.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b2c0cb8063c7208b53b6867983dc6ae7cc80b91116b51d435d2610a5db2fc52f", size = 3372809, upload-time = "2025-05-18T04:55:30.063Z" }, + { url = "https://files.pythonhosted.org/packages/fe/84/9c2917a70ed570ddbfd1d32ac23200c1d011e36c332e59950d2f6d204941/fastavro-1.11.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1bc2824e9969c04ab6263d269a1e0e5d40b9bd16ade6b70c29d6ffbc4f3cc102", size = 3387171, upload-time = "2025-05-18T04:55:32.531Z" }, ] [[package]] name = "filelock" version = "3.18.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075 } +sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075, upload-time = "2025-03-14T07:11:40.47Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215 }, + { url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215, upload-time = "2025-03-14T07:11:39.145Z" }, ] [[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 } +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 }, + { 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 = "frozenlist" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/f4/d744cba2da59b5c1d88823cf9e8a6c74e4659e2b27604ed973be2a0bf5ab/frozenlist-1.6.0.tar.gz", hash = "sha256:b99655c32c1c8e06d111e7f41c06c29a5318cb1835df23a45518e02a47c63b68", size = 42831 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/44/03/22e4eb297981d48468c3d9982ab6076b10895106d3039302a943bb60fd70/frozenlist-1.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e6e558ea1e47fd6fa8ac9ccdad403e5dd5ecc6ed8dda94343056fa4277d5c65e", size = 160584 }, - { url = "https://files.pythonhosted.org/packages/2b/b8/c213e35bcf1c20502c6fd491240b08cdd6ceec212ea54873f4cae99a51e4/frozenlist-1.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f4b3cd7334a4bbc0c472164f3744562cb72d05002cc6fcf58adb104630bbc352", size = 124099 }, - { url = "https://files.pythonhosted.org/packages/2b/33/df17b921c2e37b971407b4045deeca6f6de7caf0103c43958da5e1b85e40/frozenlist-1.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9799257237d0479736e2b4c01ff26b5c7f7694ac9692a426cb717f3dc02fff9b", size = 122106 }, - { url = "https://files.pythonhosted.org/packages/8e/09/93f0293e8a95c05eea7cf9277fef8929fb4d0a2234ad9394cd2a6b6a6bb4/frozenlist-1.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a7bb0fe1f7a70fb5c6f497dc32619db7d2cdd53164af30ade2f34673f8b1fc", size = 287205 }, - { url = "https://files.pythonhosted.org/packages/5e/34/35612f6f1b1ae0f66a4058599687d8b39352ade8ed329df0890fb553ea1e/frozenlist-1.6.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:36d2fc099229f1e4237f563b2a3e0ff7ccebc3999f729067ce4e64a97a7f2869", size = 295079 }, - { url = "https://files.pythonhosted.org/packages/e5/ca/51577ef6cc4ec818aab94a0034ef37808d9017c2e53158fef8834dbb3a07/frozenlist-1.6.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f27a9f9a86dcf00708be82359db8de86b80d029814e6693259befe82bb58a106", size = 308068 }, - { url = "https://files.pythonhosted.org/packages/36/27/c63a23863b9dcbd064560f0fea41b516bbbf4d2e8e7eec3ff880a96f0224/frozenlist-1.6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75ecee69073312951244f11b8627e3700ec2bfe07ed24e3a685a5979f0412d24", size = 305640 }, - { url = "https://files.pythonhosted.org/packages/33/c2/91720b3562a6073ba604547a417c8d3bf5d33e4c8f1231f3f8ff6719e05c/frozenlist-1.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2c7d5aa19714b1b01a0f515d078a629e445e667b9da869a3cd0e6fe7dec78bd", size = 278509 }, - { url = "https://files.pythonhosted.org/packages/d0/6e/1b64671ab2fca1ebf32c5b500205724ac14c98b9bc1574b2ef55853f4d71/frozenlist-1.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69bbd454f0fb23b51cadc9bdba616c9678e4114b6f9fa372d462ff2ed9323ec8", size = 287318 }, - { url = "https://files.pythonhosted.org/packages/66/30/589a8d8395d5ebe22a6b21262a4d32876df822c9a152e9f2919967bb8e1a/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7daa508e75613809c7a57136dec4871a21bca3080b3a8fc347c50b187df4f00c", size = 290923 }, - { url = "https://files.pythonhosted.org/packages/4d/e0/2bd0d2a4a7062b7e4b5aad621697cd3579e5d1c39d99f2833763d91e746d/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:89ffdb799154fd4d7b85c56d5fa9d9ad48946619e0eb95755723fffa11022d75", size = 304847 }, - { url = "https://files.pythonhosted.org/packages/70/a0/a1a44204398a4b308c3ee1b7bf3bf56b9dcbcc4e61c890e038721d1498db/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:920b6bd77d209931e4c263223381d63f76828bec574440f29eb497cf3394c249", size = 285580 }, - { url = "https://files.pythonhosted.org/packages/78/ed/3862bc9abe05839a6a5f5bab8b6bbdf0fc9369505cb77cd15b8c8948f6a0/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d3ceb265249fb401702fce3792e6b44c1166b9319737d21495d3611028d95769", size = 304033 }, - { url = "https://files.pythonhosted.org/packages/2c/9c/1c48454a9e1daf810aa6d977626c894b406651ca79d722fce0f13c7424f1/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:52021b528f1571f98a7d4258c58aa8d4b1a96d4f01d00d51f1089f2e0323cb02", size = 307566 }, - { url = "https://files.pythonhosted.org/packages/35/ef/cb43655c21f1bad5c42bcd540095bba6af78bf1e474b19367f6fd67d029d/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0f2ca7810b809ed0f1917293050163c7654cefc57a49f337d5cd9de717b8fad3", size = 295354 }, - { url = "https://files.pythonhosted.org/packages/9f/59/d8069a688a0f54a968c73300d6013e4786b029bfec308664094130dcea66/frozenlist-1.6.0-cp310-cp310-win32.whl", hash = "sha256:0e6f8653acb82e15e5443dba415fb62a8732b68fe09936bb6d388c725b57f812", size = 115586 }, - { url = "https://files.pythonhosted.org/packages/f9/a6/8f0cef021912ba7aa3b9920fe0a4557f6e85c41bbf71bb568cd744828df5/frozenlist-1.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:f1a39819a5a3e84304cd286e3dc62a549fe60985415851b3337b6f5cc91907f1", size = 120845 }, - { url = "https://files.pythonhosted.org/packages/53/b5/bc883b5296ec902115c00be161da93bf661199c465ec4c483feec6ea4c32/frozenlist-1.6.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae8337990e7a45683548ffb2fee1af2f1ed08169284cd829cdd9a7fa7470530d", size = 160912 }, - { url = "https://files.pythonhosted.org/packages/6f/93/51b058b563d0704b39c56baa222828043aafcac17fd3734bec5dbeb619b1/frozenlist-1.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8c952f69dd524558694818a461855f35d36cc7f5c0adddce37e962c85d06eac0", size = 124315 }, - { url = "https://files.pythonhosted.org/packages/c9/e0/46cd35219428d350558b874d595e132d1c17a9471a1bd0d01d518a261e7c/frozenlist-1.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8f5fef13136c4e2dee91bfb9a44e236fff78fc2cd9f838eddfc470c3d7d90afe", size = 122230 }, - { url = "https://files.pythonhosted.org/packages/d1/0f/7ad2ce928ad06d6dd26a61812b959ded573d3e9d0ee6109d96c2be7172e9/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:716bbba09611b4663ecbb7cd022f640759af8259e12a6ca939c0a6acd49eedba", size = 314842 }, - { url = "https://files.pythonhosted.org/packages/34/76/98cbbd8a20a5c3359a2004ae5e5b216af84a150ccbad67c8f8f30fb2ea91/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7b8c4dc422c1a3ffc550b465090e53b0bf4839047f3e436a34172ac67c45d595", size = 304919 }, - { url = "https://files.pythonhosted.org/packages/9a/fa/258e771ce3a44348c05e6b01dffc2bc67603fba95761458c238cd09a2c77/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b11534872256e1666116f6587a1592ef395a98b54476addb5e8d352925cb5d4a", size = 324074 }, - { url = "https://files.pythonhosted.org/packages/d5/a4/047d861fd8c538210e12b208c0479912273f991356b6bdee7ea8356b07c9/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c6eceb88aaf7221f75be6ab498dc622a151f5f88d536661af3ffc486245a626", size = 321292 }, - { url = "https://files.pythonhosted.org/packages/c0/25/cfec8af758b4525676cabd36efcaf7102c1348a776c0d1ad046b8a7cdc65/frozenlist-1.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62c828a5b195570eb4b37369fcbbd58e96c905768d53a44d13044355647838ff", size = 301569 }, - { url = "https://files.pythonhosted.org/packages/87/2f/0c819372fa9f0c07b153124bf58683b8d0ca7bb73ea5ccde9b9ef1745beb/frozenlist-1.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1c6bd2c6399920c9622362ce95a7d74e7f9af9bfec05fff91b8ce4b9647845a", size = 313625 }, - { url = "https://files.pythonhosted.org/packages/50/5f/f0cf8b0fdedffdb76b3745aa13d5dbe404d63493cc211ce8250f2025307f/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:49ba23817781e22fcbd45fd9ff2b9b8cdb7b16a42a4851ab8025cae7b22e96d0", size = 312523 }, - { url = "https://files.pythonhosted.org/packages/e1/6c/38c49108491272d3e84125bbabf2c2d0b304899b52f49f0539deb26ad18d/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:431ef6937ae0f853143e2ca67d6da76c083e8b1fe3df0e96f3802fd37626e606", size = 322657 }, - { url = "https://files.pythonhosted.org/packages/bd/4b/3bd3bad5be06a9d1b04b1c22be80b5fe65b502992d62fab4bdb25d9366ee/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9d124b38b3c299ca68433597ee26b7819209cb8a3a9ea761dfe9db3a04bba584", size = 303414 }, - { url = "https://files.pythonhosted.org/packages/5b/89/7e225a30bef6e85dbfe22622c24afe932e9444de3b40d58b1ea589a14ef8/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:118e97556306402e2b010da1ef21ea70cb6d6122e580da64c056b96f524fbd6a", size = 320321 }, - { url = "https://files.pythonhosted.org/packages/22/72/7e3acef4dd9e86366cb8f4d8f28e852c2b7e116927e9722b31a6f71ea4b0/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fb3b309f1d4086b5533cf7bbcf3f956f0ae6469664522f1bde4feed26fba60f1", size = 323975 }, - { url = "https://files.pythonhosted.org/packages/d8/85/e5da03d20507e13c66ce612c9792b76811b7a43e3320cce42d95b85ac755/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54dece0d21dce4fdb188a1ffc555926adf1d1c516e493c2914d7c370e454bc9e", size = 316553 }, - { url = "https://files.pythonhosted.org/packages/ac/8e/6c609cbd0580ae8a0661c408149f196aade7d325b1ae7adc930501b81acb/frozenlist-1.6.0-cp311-cp311-win32.whl", hash = "sha256:654e4ba1d0b2154ca2f096bed27461cf6160bc7f504a7f9a9ef447c293caf860", size = 115511 }, - { url = "https://files.pythonhosted.org/packages/f2/13/a84804cfde6de12d44ed48ecbf777ba62b12ff09e761f76cdd1ff9e14bb1/frozenlist-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:3e911391bffdb806001002c1f860787542f45916c3baf764264a52765d5a5603", size = 120863 }, - { url = "https://files.pythonhosted.org/packages/9c/8a/289b7d0de2fbac832ea80944d809759976f661557a38bb8e77db5d9f79b7/frozenlist-1.6.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c5b9e42ace7d95bf41e19b87cec8f262c41d3510d8ad7514ab3862ea2197bfb1", size = 160193 }, - { url = "https://files.pythonhosted.org/packages/19/80/2fd17d322aec7f430549f0669f599997174f93ee17929ea5b92781ec902c/frozenlist-1.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ca9973735ce9f770d24d5484dcb42f68f135351c2fc81a7a9369e48cf2998a29", size = 123831 }, - { url = "https://files.pythonhosted.org/packages/99/06/f5812da431273f78c6543e0b2f7de67dfd65eb0a433978b2c9c63d2205e4/frozenlist-1.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6ac40ec76041c67b928ca8aaffba15c2b2ee3f5ae8d0cb0617b5e63ec119ca25", size = 121862 }, - { url = "https://files.pythonhosted.org/packages/d0/31/9e61c6b5fc493cf24d54881731204d27105234d09878be1a5983182cc4a5/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b7a8a3180dfb280eb044fdec562f9b461614c0ef21669aea6f1d3dac6ee576", size = 316361 }, - { url = "https://files.pythonhosted.org/packages/9d/55/22ca9362d4f0222324981470fd50192be200154d51509ee6eb9baa148e96/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c444d824e22da6c9291886d80c7d00c444981a72686e2b59d38b285617cb52c8", size = 307115 }, - { url = "https://files.pythonhosted.org/packages/ae/39/4fff42920a57794881e7bb3898dc7f5f539261711ea411b43bba3cde8b79/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb52c8166499a8150bfd38478248572c924c003cbb45fe3bcd348e5ac7c000f9", size = 322505 }, - { url = "https://files.pythonhosted.org/packages/55/f2/88c41f374c1e4cf0092a5459e5f3d6a1e17ed274c98087a76487783df90c/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b35298b2db9c2468106278537ee529719228950a5fdda686582f68f247d1dc6e", size = 322666 }, - { url = "https://files.pythonhosted.org/packages/75/51/034eeb75afdf3fd03997856195b500722c0b1a50716664cde64e28299c4b/frozenlist-1.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d108e2d070034f9d57210f22fefd22ea0d04609fc97c5f7f5a686b3471028590", size = 302119 }, - { url = "https://files.pythonhosted.org/packages/2b/a6/564ecde55ee633270a793999ef4fd1d2c2b32b5a7eec903b1012cb7c5143/frozenlist-1.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e1be9111cb6756868ac242b3c2bd1f09d9aea09846e4f5c23715e7afb647103", size = 316226 }, - { url = "https://files.pythonhosted.org/packages/f1/c8/6c0682c32377f402b8a6174fb16378b683cf6379ab4d2827c580892ab3c7/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:94bb451c664415f02f07eef4ece976a2c65dcbab9c2f1705b7031a3a75349d8c", size = 312788 }, - { url = "https://files.pythonhosted.org/packages/b6/b8/10fbec38f82c5d163ca1750bfff4ede69713badf236a016781cf1f10a0f0/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d1a686d0b0949182b8faddea596f3fc11f44768d1f74d4cad70213b2e139d821", size = 325914 }, - { url = "https://files.pythonhosted.org/packages/62/ca/2bf4f3a1bd40cdedd301e6ecfdbb291080d5afc5f9ce350c0739f773d6b9/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ea8e59105d802c5a38bdbe7362822c522230b3faba2aa35c0fa1765239b7dd70", size = 305283 }, - { url = "https://files.pythonhosted.org/packages/09/64/20cc13ccf94abc2a1f482f74ad210703dc78a590d0b805af1c9aa67f76f9/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:abc4e880a9b920bc5020bf6a431a6bb40589d9bca3975c980495f63632e8382f", size = 319264 }, - { url = "https://files.pythonhosted.org/packages/20/ff/86c6a2bbe98cfc231519f5e6d712a0898488ceac804a917ce014f32e68f6/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9a79713adfe28830f27a3c62f6b5406c37376c892b05ae070906f07ae4487046", size = 326482 }, - { url = "https://files.pythonhosted.org/packages/2f/da/8e381f66367d79adca245d1d71527aac774e30e291d41ef161ce2d80c38e/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a0318c2068e217a8f5e3b85e35899f5a19e97141a45bb925bb357cfe1daf770", size = 318248 }, - { url = "https://files.pythonhosted.org/packages/39/24/1a1976563fb476ab6f0fa9fefaac7616a4361dbe0461324f9fd7bf425dbe/frozenlist-1.6.0-cp312-cp312-win32.whl", hash = "sha256:853ac025092a24bb3bf09ae87f9127de9fe6e0c345614ac92536577cf956dfcc", size = 115161 }, - { url = "https://files.pythonhosted.org/packages/80/2e/fb4ed62a65f8cd66044706b1013f0010930d8cbb0729a2219561ea075434/frozenlist-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:2bdfe2d7e6c9281c6e55523acd6c2bf77963cb422fdc7d142fb0cb6621b66878", size = 120548 }, - { url = "https://files.pythonhosted.org/packages/6f/e5/04c7090c514d96ca00887932417f04343ab94904a56ab7f57861bf63652d/frozenlist-1.6.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1d7fb014fe0fbfee3efd6a94fc635aeaa68e5e1720fe9e57357f2e2c6e1a647e", size = 158182 }, - { url = "https://files.pythonhosted.org/packages/e9/8f/60d0555c61eec855783a6356268314d204137f5e0c53b59ae2fc28938c99/frozenlist-1.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01bcaa305a0fdad12745502bfd16a1c75b14558dabae226852f9159364573117", size = 122838 }, - { url = "https://files.pythonhosted.org/packages/5a/a7/d0ec890e3665b4b3b7c05dc80e477ed8dc2e2e77719368e78e2cd9fec9c8/frozenlist-1.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b314faa3051a6d45da196a2c495e922f987dc848e967d8cfeaee8a0328b1cd4", size = 120980 }, - { url = "https://files.pythonhosted.org/packages/cc/19/9b355a5e7a8eba903a008579964192c3e427444752f20b2144b10bb336df/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da62fecac21a3ee10463d153549d8db87549a5e77eefb8c91ac84bb42bb1e4e3", size = 305463 }, - { url = "https://files.pythonhosted.org/packages/9c/8d/5b4c758c2550131d66935ef2fa700ada2461c08866aef4229ae1554b93ca/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1eb89bf3454e2132e046f9599fbcf0a4483ed43b40f545551a39316d0201cd1", size = 297985 }, - { url = "https://files.pythonhosted.org/packages/48/2c/537ec09e032b5865715726b2d1d9813e6589b571d34d01550c7aeaad7e53/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18689b40cb3936acd971f663ccb8e2589c45db5e2c5f07e0ec6207664029a9c", size = 311188 }, - { url = "https://files.pythonhosted.org/packages/31/2f/1aa74b33f74d54817055de9a4961eff798f066cdc6f67591905d4fc82a84/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e67ddb0749ed066b1a03fba812e2dcae791dd50e5da03be50b6a14d0c1a9ee45", size = 311874 }, - { url = "https://files.pythonhosted.org/packages/bf/f0/cfec18838f13ebf4b37cfebc8649db5ea71a1b25dacd691444a10729776c/frozenlist-1.6.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc5e64626e6682638d6e44398c9baf1d6ce6bc236d40b4b57255c9d3f9761f1f", size = 291897 }, - { url = "https://files.pythonhosted.org/packages/ea/a5/deb39325cbbea6cd0a46db8ccd76150ae2fcbe60d63243d9df4a0b8c3205/frozenlist-1.6.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:437cfd39564744ae32ad5929e55b18ebd88817f9180e4cc05e7d53b75f79ce85", size = 305799 }, - { url = "https://files.pythonhosted.org/packages/78/22/6ddec55c5243a59f605e4280f10cee8c95a449f81e40117163383829c241/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62dd7df78e74d924952e2feb7357d826af8d2f307557a779d14ddf94d7311be8", size = 302804 }, - { url = "https://files.pythonhosted.org/packages/5d/b7/d9ca9bab87f28855063c4d202936800219e39db9e46f9fb004d521152623/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a66781d7e4cddcbbcfd64de3d41a61d6bdde370fc2e38623f30b2bd539e84a9f", size = 316404 }, - { url = "https://files.pythonhosted.org/packages/a6/3a/1255305db7874d0b9eddb4fe4a27469e1fb63720f1fc6d325a5118492d18/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:482fe06e9a3fffbcd41950f9d890034b4a54395c60b5e61fae875d37a699813f", size = 295572 }, - { url = "https://files.pythonhosted.org/packages/2a/f2/8d38eeee39a0e3a91b75867cc102159ecccf441deb6ddf67be96d3410b84/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e4f9373c500dfc02feea39f7a56e4f543e670212102cc2eeb51d3a99c7ffbde6", size = 307601 }, - { url = "https://files.pythonhosted.org/packages/38/04/80ec8e6b92f61ef085422d7b196822820404f940950dde5b2e367bede8bc/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e69bb81de06827147b7bfbaeb284d85219fa92d9f097e32cc73675f279d70188", size = 314232 }, - { url = "https://files.pythonhosted.org/packages/3a/58/93b41fb23e75f38f453ae92a2f987274c64637c450285577bd81c599b715/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7613d9977d2ab4a9141dde4a149f4357e4065949674c5649f920fec86ecb393e", size = 308187 }, - { url = "https://files.pythonhosted.org/packages/6a/a2/e64df5c5aa36ab3dee5a40d254f3e471bb0603c225f81664267281c46a2d/frozenlist-1.6.0-cp313-cp313-win32.whl", hash = "sha256:4def87ef6d90429f777c9d9de3961679abf938cb6b7b63d4a7eb8a268babfce4", size = 114772 }, - { url = "https://files.pythonhosted.org/packages/a0/77/fead27441e749b2d574bb73d693530d59d520d4b9e9679b8e3cb779d37f2/frozenlist-1.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:37a8a52c3dfff01515e9bbbee0e6063181362f9de3db2ccf9bc96189b557cbfd", size = 119847 }, - { url = "https://files.pythonhosted.org/packages/df/bd/cc6d934991c1e5d9cafda83dfdc52f987c7b28343686aef2e58a9cf89f20/frozenlist-1.6.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:46138f5a0773d064ff663d273b309b696293d7a7c00a0994c5c13a5078134b64", size = 174937 }, - { url = "https://files.pythonhosted.org/packages/f2/a2/daf945f335abdbfdd5993e9dc348ef4507436936ab3c26d7cfe72f4843bf/frozenlist-1.6.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f88bc0a2b9c2a835cb888b32246c27cdab5740059fb3688852bf91e915399b91", size = 136029 }, - { url = "https://files.pythonhosted.org/packages/51/65/4c3145f237a31247c3429e1c94c384d053f69b52110a0d04bfc8afc55fb2/frozenlist-1.6.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:777704c1d7655b802c7850255639672e90e81ad6fa42b99ce5ed3fbf45e338dd", size = 134831 }, - { url = "https://files.pythonhosted.org/packages/77/38/03d316507d8dea84dfb99bdd515ea245628af964b2bf57759e3c9205cc5e/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85ef8d41764c7de0dcdaf64f733a27352248493a85a80661f3c678acd27e31f2", size = 392981 }, - { url = "https://files.pythonhosted.org/packages/37/02/46285ef9828f318ba400a51d5bb616ded38db8466836a9cfa39f3903260b/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:da5cb36623f2b846fb25009d9d9215322318ff1c63403075f812b3b2876c8506", size = 371999 }, - { url = "https://files.pythonhosted.org/packages/0d/64/1212fea37a112c3c5c05bfb5f0a81af4836ce349e69be75af93f99644da9/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbb56587a16cf0fb8acd19e90ff9924979ac1431baea8681712716a8337577b0", size = 392200 }, - { url = "https://files.pythonhosted.org/packages/81/ce/9a6ea1763e3366e44a5208f76bf37c76c5da570772375e4d0be85180e588/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6154c3ba59cda3f954c6333025369e42c3acd0c6e8b6ce31eb5c5b8116c07e0", size = 390134 }, - { url = "https://files.pythonhosted.org/packages/bc/36/939738b0b495b2c6d0c39ba51563e453232813042a8d908b8f9544296c29/frozenlist-1.6.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e8246877afa3f1ae5c979fe85f567d220f86a50dc6c493b9b7d8191181ae01e", size = 365208 }, - { url = "https://files.pythonhosted.org/packages/b4/8b/939e62e93c63409949c25220d1ba8e88e3960f8ef6a8d9ede8f94b459d27/frozenlist-1.6.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0f6cce16306d2e117cf9db71ab3a9e8878a28176aeaf0dbe35248d97b28d0c", size = 385548 }, - { url = "https://files.pythonhosted.org/packages/62/38/22d2873c90102e06a7c5a3a5b82ca47e393c6079413e8a75c72bff067fa8/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:1b8e8cd8032ba266f91136d7105706ad57770f3522eac4a111d77ac126a25a9b", size = 391123 }, - { url = "https://files.pythonhosted.org/packages/44/78/63aaaf533ee0701549500f6d819be092c6065cb5c577edb70c09df74d5d0/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e2ada1d8515d3ea5378c018a5f6d14b4994d4036591a52ceaf1a1549dec8e1ad", size = 394199 }, - { url = "https://files.pythonhosted.org/packages/54/45/71a6b48981d429e8fbcc08454dc99c4c2639865a646d549812883e9c9dd3/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:cdb2c7f071e4026c19a3e32b93a09e59b12000751fc9b0b7758da899e657d215", size = 373854 }, - { url = "https://files.pythonhosted.org/packages/3f/f3/dbf2a5e11736ea81a66e37288bf9f881143a7822b288a992579ba1b4204d/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:03572933a1969a6d6ab509d509e5af82ef80d4a5d4e1e9f2e1cdd22c77a3f4d2", size = 395412 }, - { url = "https://files.pythonhosted.org/packages/b3/f1/c63166806b331f05104d8ea385c4acd511598568b1f3e4e8297ca54f2676/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:77effc978947548b676c54bbd6a08992759ea6f410d4987d69feea9cd0919911", size = 394936 }, - { url = "https://files.pythonhosted.org/packages/ef/ea/4f3e69e179a430473eaa1a75ff986526571215fefc6b9281cdc1f09a4eb8/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a2bda8be77660ad4089caf2223fdbd6db1858462c4b85b67fbfa22102021e497", size = 391459 }, - { url = "https://files.pythonhosted.org/packages/d3/c3/0fc2c97dea550df9afd072a37c1e95421652e3206bbeaa02378b24c2b480/frozenlist-1.6.0-cp313-cp313t-win32.whl", hash = "sha256:a4d96dc5bcdbd834ec6b0f91027817214216b5b30316494d2b1aebffb87c534f", size = 128797 }, - { url = "https://files.pythonhosted.org/packages/ae/f5/79c9320c5656b1965634fe4be9c82b12a3305bdbc58ad9cb941131107b20/frozenlist-1.6.0-cp313-cp313t-win_amd64.whl", hash = "sha256:e18036cb4caa17ea151fd5f3d70be9d354c99eb8cf817a3ccde8a7873b074348", size = 134709 }, - { url = "https://files.pythonhosted.org/packages/71/3e/b04a0adda73bd52b390d730071c0d577073d3d26740ee1bad25c3ad0f37b/frozenlist-1.6.0-py3-none-any.whl", hash = "sha256:535eec9987adb04701266b92745d6cdcef2e77669299359c3009c3404dd5d191", size = 12404 }, +sdist = { url = "https://files.pythonhosted.org/packages/ee/f4/d744cba2da59b5c1d88823cf9e8a6c74e4659e2b27604ed973be2a0bf5ab/frozenlist-1.6.0.tar.gz", hash = "sha256:b99655c32c1c8e06d111e7f41c06c29a5318cb1835df23a45518e02a47c63b68", size = 42831, upload-time = "2025-04-17T22:38:53.099Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/03/22e4eb297981d48468c3d9982ab6076b10895106d3039302a943bb60fd70/frozenlist-1.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e6e558ea1e47fd6fa8ac9ccdad403e5dd5ecc6ed8dda94343056fa4277d5c65e", size = 160584, upload-time = "2025-04-17T22:35:48.163Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b8/c213e35bcf1c20502c6fd491240b08cdd6ceec212ea54873f4cae99a51e4/frozenlist-1.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f4b3cd7334a4bbc0c472164f3744562cb72d05002cc6fcf58adb104630bbc352", size = 124099, upload-time = "2025-04-17T22:35:50.241Z" }, + { url = "https://files.pythonhosted.org/packages/2b/33/df17b921c2e37b971407b4045deeca6f6de7caf0103c43958da5e1b85e40/frozenlist-1.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9799257237d0479736e2b4c01ff26b5c7f7694ac9692a426cb717f3dc02fff9b", size = 122106, upload-time = "2025-04-17T22:35:51.697Z" }, + { url = "https://files.pythonhosted.org/packages/8e/09/93f0293e8a95c05eea7cf9277fef8929fb4d0a2234ad9394cd2a6b6a6bb4/frozenlist-1.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a7bb0fe1f7a70fb5c6f497dc32619db7d2cdd53164af30ade2f34673f8b1fc", size = 287205, upload-time = "2025-04-17T22:35:53.441Z" }, + { url = "https://files.pythonhosted.org/packages/5e/34/35612f6f1b1ae0f66a4058599687d8b39352ade8ed329df0890fb553ea1e/frozenlist-1.6.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:36d2fc099229f1e4237f563b2a3e0ff7ccebc3999f729067ce4e64a97a7f2869", size = 295079, upload-time = "2025-04-17T22:35:55.617Z" }, + { url = "https://files.pythonhosted.org/packages/e5/ca/51577ef6cc4ec818aab94a0034ef37808d9017c2e53158fef8834dbb3a07/frozenlist-1.6.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f27a9f9a86dcf00708be82359db8de86b80d029814e6693259befe82bb58a106", size = 308068, upload-time = "2025-04-17T22:35:57.119Z" }, + { url = "https://files.pythonhosted.org/packages/36/27/c63a23863b9dcbd064560f0fea41b516bbbf4d2e8e7eec3ff880a96f0224/frozenlist-1.6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75ecee69073312951244f11b8627e3700ec2bfe07ed24e3a685a5979f0412d24", size = 305640, upload-time = "2025-04-17T22:35:58.667Z" }, + { url = "https://files.pythonhosted.org/packages/33/c2/91720b3562a6073ba604547a417c8d3bf5d33e4c8f1231f3f8ff6719e05c/frozenlist-1.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2c7d5aa19714b1b01a0f515d078a629e445e667b9da869a3cd0e6fe7dec78bd", size = 278509, upload-time = "2025-04-17T22:36:00.199Z" }, + { url = "https://files.pythonhosted.org/packages/d0/6e/1b64671ab2fca1ebf32c5b500205724ac14c98b9bc1574b2ef55853f4d71/frozenlist-1.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69bbd454f0fb23b51cadc9bdba616c9678e4114b6f9fa372d462ff2ed9323ec8", size = 287318, upload-time = "2025-04-17T22:36:02.179Z" }, + { url = "https://files.pythonhosted.org/packages/66/30/589a8d8395d5ebe22a6b21262a4d32876df822c9a152e9f2919967bb8e1a/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7daa508e75613809c7a57136dec4871a21bca3080b3a8fc347c50b187df4f00c", size = 290923, upload-time = "2025-04-17T22:36:03.766Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e0/2bd0d2a4a7062b7e4b5aad621697cd3579e5d1c39d99f2833763d91e746d/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:89ffdb799154fd4d7b85c56d5fa9d9ad48946619e0eb95755723fffa11022d75", size = 304847, upload-time = "2025-04-17T22:36:05.518Z" }, + { url = "https://files.pythonhosted.org/packages/70/a0/a1a44204398a4b308c3ee1b7bf3bf56b9dcbcc4e61c890e038721d1498db/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:920b6bd77d209931e4c263223381d63f76828bec574440f29eb497cf3394c249", size = 285580, upload-time = "2025-04-17T22:36:07.538Z" }, + { url = "https://files.pythonhosted.org/packages/78/ed/3862bc9abe05839a6a5f5bab8b6bbdf0fc9369505cb77cd15b8c8948f6a0/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d3ceb265249fb401702fce3792e6b44c1166b9319737d21495d3611028d95769", size = 304033, upload-time = "2025-04-17T22:36:09.082Z" }, + { url = "https://files.pythonhosted.org/packages/2c/9c/1c48454a9e1daf810aa6d977626c894b406651ca79d722fce0f13c7424f1/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:52021b528f1571f98a7d4258c58aa8d4b1a96d4f01d00d51f1089f2e0323cb02", size = 307566, upload-time = "2025-04-17T22:36:10.561Z" }, + { url = "https://files.pythonhosted.org/packages/35/ef/cb43655c21f1bad5c42bcd540095bba6af78bf1e474b19367f6fd67d029d/frozenlist-1.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0f2ca7810b809ed0f1917293050163c7654cefc57a49f337d5cd9de717b8fad3", size = 295354, upload-time = "2025-04-17T22:36:12.181Z" }, + { url = "https://files.pythonhosted.org/packages/9f/59/d8069a688a0f54a968c73300d6013e4786b029bfec308664094130dcea66/frozenlist-1.6.0-cp310-cp310-win32.whl", hash = "sha256:0e6f8653acb82e15e5443dba415fb62a8732b68fe09936bb6d388c725b57f812", size = 115586, upload-time = "2025-04-17T22:36:14.01Z" }, + { url = "https://files.pythonhosted.org/packages/f9/a6/8f0cef021912ba7aa3b9920fe0a4557f6e85c41bbf71bb568cd744828df5/frozenlist-1.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:f1a39819a5a3e84304cd286e3dc62a549fe60985415851b3337b6f5cc91907f1", size = 120845, upload-time = "2025-04-17T22:36:15.383Z" }, + { url = "https://files.pythonhosted.org/packages/53/b5/bc883b5296ec902115c00be161da93bf661199c465ec4c483feec6ea4c32/frozenlist-1.6.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae8337990e7a45683548ffb2fee1af2f1ed08169284cd829cdd9a7fa7470530d", size = 160912, upload-time = "2025-04-17T22:36:17.235Z" }, + { url = "https://files.pythonhosted.org/packages/6f/93/51b058b563d0704b39c56baa222828043aafcac17fd3734bec5dbeb619b1/frozenlist-1.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8c952f69dd524558694818a461855f35d36cc7f5c0adddce37e962c85d06eac0", size = 124315, upload-time = "2025-04-17T22:36:18.735Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e0/46cd35219428d350558b874d595e132d1c17a9471a1bd0d01d518a261e7c/frozenlist-1.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8f5fef13136c4e2dee91bfb9a44e236fff78fc2cd9f838eddfc470c3d7d90afe", size = 122230, upload-time = "2025-04-17T22:36:20.6Z" }, + { url = "https://files.pythonhosted.org/packages/d1/0f/7ad2ce928ad06d6dd26a61812b959ded573d3e9d0ee6109d96c2be7172e9/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:716bbba09611b4663ecbb7cd022f640759af8259e12a6ca939c0a6acd49eedba", size = 314842, upload-time = "2025-04-17T22:36:22.088Z" }, + { url = "https://files.pythonhosted.org/packages/34/76/98cbbd8a20a5c3359a2004ae5e5b216af84a150ccbad67c8f8f30fb2ea91/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7b8c4dc422c1a3ffc550b465090e53b0bf4839047f3e436a34172ac67c45d595", size = 304919, upload-time = "2025-04-17T22:36:24.247Z" }, + { url = "https://files.pythonhosted.org/packages/9a/fa/258e771ce3a44348c05e6b01dffc2bc67603fba95761458c238cd09a2c77/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b11534872256e1666116f6587a1592ef395a98b54476addb5e8d352925cb5d4a", size = 324074, upload-time = "2025-04-17T22:36:26.291Z" }, + { url = "https://files.pythonhosted.org/packages/d5/a4/047d861fd8c538210e12b208c0479912273f991356b6bdee7ea8356b07c9/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c6eceb88aaf7221f75be6ab498dc622a151f5f88d536661af3ffc486245a626", size = 321292, upload-time = "2025-04-17T22:36:27.909Z" }, + { url = "https://files.pythonhosted.org/packages/c0/25/cfec8af758b4525676cabd36efcaf7102c1348a776c0d1ad046b8a7cdc65/frozenlist-1.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62c828a5b195570eb4b37369fcbbd58e96c905768d53a44d13044355647838ff", size = 301569, upload-time = "2025-04-17T22:36:29.448Z" }, + { url = "https://files.pythonhosted.org/packages/87/2f/0c819372fa9f0c07b153124bf58683b8d0ca7bb73ea5ccde9b9ef1745beb/frozenlist-1.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1c6bd2c6399920c9622362ce95a7d74e7f9af9bfec05fff91b8ce4b9647845a", size = 313625, upload-time = "2025-04-17T22:36:31.55Z" }, + { url = "https://files.pythonhosted.org/packages/50/5f/f0cf8b0fdedffdb76b3745aa13d5dbe404d63493cc211ce8250f2025307f/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:49ba23817781e22fcbd45fd9ff2b9b8cdb7b16a42a4851ab8025cae7b22e96d0", size = 312523, upload-time = "2025-04-17T22:36:33.078Z" }, + { url = "https://files.pythonhosted.org/packages/e1/6c/38c49108491272d3e84125bbabf2c2d0b304899b52f49f0539deb26ad18d/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:431ef6937ae0f853143e2ca67d6da76c083e8b1fe3df0e96f3802fd37626e606", size = 322657, upload-time = "2025-04-17T22:36:34.688Z" }, + { url = "https://files.pythonhosted.org/packages/bd/4b/3bd3bad5be06a9d1b04b1c22be80b5fe65b502992d62fab4bdb25d9366ee/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9d124b38b3c299ca68433597ee26b7819209cb8a3a9ea761dfe9db3a04bba584", size = 303414, upload-time = "2025-04-17T22:36:36.363Z" }, + { url = "https://files.pythonhosted.org/packages/5b/89/7e225a30bef6e85dbfe22622c24afe932e9444de3b40d58b1ea589a14ef8/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:118e97556306402e2b010da1ef21ea70cb6d6122e580da64c056b96f524fbd6a", size = 320321, upload-time = "2025-04-17T22:36:38.16Z" }, + { url = "https://files.pythonhosted.org/packages/22/72/7e3acef4dd9e86366cb8f4d8f28e852c2b7e116927e9722b31a6f71ea4b0/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fb3b309f1d4086b5533cf7bbcf3f956f0ae6469664522f1bde4feed26fba60f1", size = 323975, upload-time = "2025-04-17T22:36:40.289Z" }, + { url = "https://files.pythonhosted.org/packages/d8/85/e5da03d20507e13c66ce612c9792b76811b7a43e3320cce42d95b85ac755/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54dece0d21dce4fdb188a1ffc555926adf1d1c516e493c2914d7c370e454bc9e", size = 316553, upload-time = "2025-04-17T22:36:42.045Z" }, + { url = "https://files.pythonhosted.org/packages/ac/8e/6c609cbd0580ae8a0661c408149f196aade7d325b1ae7adc930501b81acb/frozenlist-1.6.0-cp311-cp311-win32.whl", hash = "sha256:654e4ba1d0b2154ca2f096bed27461cf6160bc7f504a7f9a9ef447c293caf860", size = 115511, upload-time = "2025-04-17T22:36:44.067Z" }, + { url = "https://files.pythonhosted.org/packages/f2/13/a84804cfde6de12d44ed48ecbf777ba62b12ff09e761f76cdd1ff9e14bb1/frozenlist-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:3e911391bffdb806001002c1f860787542f45916c3baf764264a52765d5a5603", size = 120863, upload-time = "2025-04-17T22:36:45.465Z" }, + { url = "https://files.pythonhosted.org/packages/9c/8a/289b7d0de2fbac832ea80944d809759976f661557a38bb8e77db5d9f79b7/frozenlist-1.6.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c5b9e42ace7d95bf41e19b87cec8f262c41d3510d8ad7514ab3862ea2197bfb1", size = 160193, upload-time = "2025-04-17T22:36:47.382Z" }, + { url = "https://files.pythonhosted.org/packages/19/80/2fd17d322aec7f430549f0669f599997174f93ee17929ea5b92781ec902c/frozenlist-1.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ca9973735ce9f770d24d5484dcb42f68f135351c2fc81a7a9369e48cf2998a29", size = 123831, upload-time = "2025-04-17T22:36:49.401Z" }, + { url = "https://files.pythonhosted.org/packages/99/06/f5812da431273f78c6543e0b2f7de67dfd65eb0a433978b2c9c63d2205e4/frozenlist-1.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6ac40ec76041c67b928ca8aaffba15c2b2ee3f5ae8d0cb0617b5e63ec119ca25", size = 121862, upload-time = "2025-04-17T22:36:51.899Z" }, + { url = "https://files.pythonhosted.org/packages/d0/31/9e61c6b5fc493cf24d54881731204d27105234d09878be1a5983182cc4a5/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b7a8a3180dfb280eb044fdec562f9b461614c0ef21669aea6f1d3dac6ee576", size = 316361, upload-time = "2025-04-17T22:36:53.402Z" }, + { url = "https://files.pythonhosted.org/packages/9d/55/22ca9362d4f0222324981470fd50192be200154d51509ee6eb9baa148e96/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c444d824e22da6c9291886d80c7d00c444981a72686e2b59d38b285617cb52c8", size = 307115, upload-time = "2025-04-17T22:36:55.016Z" }, + { url = "https://files.pythonhosted.org/packages/ae/39/4fff42920a57794881e7bb3898dc7f5f539261711ea411b43bba3cde8b79/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb52c8166499a8150bfd38478248572c924c003cbb45fe3bcd348e5ac7c000f9", size = 322505, upload-time = "2025-04-17T22:36:57.12Z" }, + { url = "https://files.pythonhosted.org/packages/55/f2/88c41f374c1e4cf0092a5459e5f3d6a1e17ed274c98087a76487783df90c/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b35298b2db9c2468106278537ee529719228950a5fdda686582f68f247d1dc6e", size = 322666, upload-time = "2025-04-17T22:36:58.735Z" }, + { url = "https://files.pythonhosted.org/packages/75/51/034eeb75afdf3fd03997856195b500722c0b1a50716664cde64e28299c4b/frozenlist-1.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d108e2d070034f9d57210f22fefd22ea0d04609fc97c5f7f5a686b3471028590", size = 302119, upload-time = "2025-04-17T22:37:00.512Z" }, + { url = "https://files.pythonhosted.org/packages/2b/a6/564ecde55ee633270a793999ef4fd1d2c2b32b5a7eec903b1012cb7c5143/frozenlist-1.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e1be9111cb6756868ac242b3c2bd1f09d9aea09846e4f5c23715e7afb647103", size = 316226, upload-time = "2025-04-17T22:37:02.102Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c8/6c0682c32377f402b8a6174fb16378b683cf6379ab4d2827c580892ab3c7/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:94bb451c664415f02f07eef4ece976a2c65dcbab9c2f1705b7031a3a75349d8c", size = 312788, upload-time = "2025-04-17T22:37:03.578Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b8/10fbec38f82c5d163ca1750bfff4ede69713badf236a016781cf1f10a0f0/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d1a686d0b0949182b8faddea596f3fc11f44768d1f74d4cad70213b2e139d821", size = 325914, upload-time = "2025-04-17T22:37:05.213Z" }, + { url = "https://files.pythonhosted.org/packages/62/ca/2bf4f3a1bd40cdedd301e6ecfdbb291080d5afc5f9ce350c0739f773d6b9/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ea8e59105d802c5a38bdbe7362822c522230b3faba2aa35c0fa1765239b7dd70", size = 305283, upload-time = "2025-04-17T22:37:06.985Z" }, + { url = "https://files.pythonhosted.org/packages/09/64/20cc13ccf94abc2a1f482f74ad210703dc78a590d0b805af1c9aa67f76f9/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:abc4e880a9b920bc5020bf6a431a6bb40589d9bca3975c980495f63632e8382f", size = 319264, upload-time = "2025-04-17T22:37:08.618Z" }, + { url = "https://files.pythonhosted.org/packages/20/ff/86c6a2bbe98cfc231519f5e6d712a0898488ceac804a917ce014f32e68f6/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9a79713adfe28830f27a3c62f6b5406c37376c892b05ae070906f07ae4487046", size = 326482, upload-time = "2025-04-17T22:37:10.196Z" }, + { url = "https://files.pythonhosted.org/packages/2f/da/8e381f66367d79adca245d1d71527aac774e30e291d41ef161ce2d80c38e/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a0318c2068e217a8f5e3b85e35899f5a19e97141a45bb925bb357cfe1daf770", size = 318248, upload-time = "2025-04-17T22:37:12.284Z" }, + { url = "https://files.pythonhosted.org/packages/39/24/1a1976563fb476ab6f0fa9fefaac7616a4361dbe0461324f9fd7bf425dbe/frozenlist-1.6.0-cp312-cp312-win32.whl", hash = "sha256:853ac025092a24bb3bf09ae87f9127de9fe6e0c345614ac92536577cf956dfcc", size = 115161, upload-time = "2025-04-17T22:37:13.902Z" }, + { url = "https://files.pythonhosted.org/packages/80/2e/fb4ed62a65f8cd66044706b1013f0010930d8cbb0729a2219561ea075434/frozenlist-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:2bdfe2d7e6c9281c6e55523acd6c2bf77963cb422fdc7d142fb0cb6621b66878", size = 120548, upload-time = "2025-04-17T22:37:15.326Z" }, + { url = "https://files.pythonhosted.org/packages/6f/e5/04c7090c514d96ca00887932417f04343ab94904a56ab7f57861bf63652d/frozenlist-1.6.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1d7fb014fe0fbfee3efd6a94fc635aeaa68e5e1720fe9e57357f2e2c6e1a647e", size = 158182, upload-time = "2025-04-17T22:37:16.837Z" }, + { url = "https://files.pythonhosted.org/packages/e9/8f/60d0555c61eec855783a6356268314d204137f5e0c53b59ae2fc28938c99/frozenlist-1.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01bcaa305a0fdad12745502bfd16a1c75b14558dabae226852f9159364573117", size = 122838, upload-time = "2025-04-17T22:37:18.352Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a7/d0ec890e3665b4b3b7c05dc80e477ed8dc2e2e77719368e78e2cd9fec9c8/frozenlist-1.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b314faa3051a6d45da196a2c495e922f987dc848e967d8cfeaee8a0328b1cd4", size = 120980, upload-time = "2025-04-17T22:37:19.857Z" }, + { url = "https://files.pythonhosted.org/packages/cc/19/9b355a5e7a8eba903a008579964192c3e427444752f20b2144b10bb336df/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da62fecac21a3ee10463d153549d8db87549a5e77eefb8c91ac84bb42bb1e4e3", size = 305463, upload-time = "2025-04-17T22:37:21.328Z" }, + { url = "https://files.pythonhosted.org/packages/9c/8d/5b4c758c2550131d66935ef2fa700ada2461c08866aef4229ae1554b93ca/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1eb89bf3454e2132e046f9599fbcf0a4483ed43b40f545551a39316d0201cd1", size = 297985, upload-time = "2025-04-17T22:37:23.55Z" }, + { url = "https://files.pythonhosted.org/packages/48/2c/537ec09e032b5865715726b2d1d9813e6589b571d34d01550c7aeaad7e53/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18689b40cb3936acd971f663ccb8e2589c45db5e2c5f07e0ec6207664029a9c", size = 311188, upload-time = "2025-04-17T22:37:25.221Z" }, + { url = "https://files.pythonhosted.org/packages/31/2f/1aa74b33f74d54817055de9a4961eff798f066cdc6f67591905d4fc82a84/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e67ddb0749ed066b1a03fba812e2dcae791dd50e5da03be50b6a14d0c1a9ee45", size = 311874, upload-time = "2025-04-17T22:37:26.791Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f0/cfec18838f13ebf4b37cfebc8649db5ea71a1b25dacd691444a10729776c/frozenlist-1.6.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc5e64626e6682638d6e44398c9baf1d6ce6bc236d40b4b57255c9d3f9761f1f", size = 291897, upload-time = "2025-04-17T22:37:28.958Z" }, + { url = "https://files.pythonhosted.org/packages/ea/a5/deb39325cbbea6cd0a46db8ccd76150ae2fcbe60d63243d9df4a0b8c3205/frozenlist-1.6.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:437cfd39564744ae32ad5929e55b18ebd88817f9180e4cc05e7d53b75f79ce85", size = 305799, upload-time = "2025-04-17T22:37:30.889Z" }, + { url = "https://files.pythonhosted.org/packages/78/22/6ddec55c5243a59f605e4280f10cee8c95a449f81e40117163383829c241/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62dd7df78e74d924952e2feb7357d826af8d2f307557a779d14ddf94d7311be8", size = 302804, upload-time = "2025-04-17T22:37:32.489Z" }, + { url = "https://files.pythonhosted.org/packages/5d/b7/d9ca9bab87f28855063c4d202936800219e39db9e46f9fb004d521152623/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a66781d7e4cddcbbcfd64de3d41a61d6bdde370fc2e38623f30b2bd539e84a9f", size = 316404, upload-time = "2025-04-17T22:37:34.59Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3a/1255305db7874d0b9eddb4fe4a27469e1fb63720f1fc6d325a5118492d18/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:482fe06e9a3fffbcd41950f9d890034b4a54395c60b5e61fae875d37a699813f", size = 295572, upload-time = "2025-04-17T22:37:36.337Z" }, + { url = "https://files.pythonhosted.org/packages/2a/f2/8d38eeee39a0e3a91b75867cc102159ecccf441deb6ddf67be96d3410b84/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e4f9373c500dfc02feea39f7a56e4f543e670212102cc2eeb51d3a99c7ffbde6", size = 307601, upload-time = "2025-04-17T22:37:37.923Z" }, + { url = "https://files.pythonhosted.org/packages/38/04/80ec8e6b92f61ef085422d7b196822820404f940950dde5b2e367bede8bc/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e69bb81de06827147b7bfbaeb284d85219fa92d9f097e32cc73675f279d70188", size = 314232, upload-time = "2025-04-17T22:37:39.669Z" }, + { url = "https://files.pythonhosted.org/packages/3a/58/93b41fb23e75f38f453ae92a2f987274c64637c450285577bd81c599b715/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7613d9977d2ab4a9141dde4a149f4357e4065949674c5649f920fec86ecb393e", size = 308187, upload-time = "2025-04-17T22:37:41.662Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a2/e64df5c5aa36ab3dee5a40d254f3e471bb0603c225f81664267281c46a2d/frozenlist-1.6.0-cp313-cp313-win32.whl", hash = "sha256:4def87ef6d90429f777c9d9de3961679abf938cb6b7b63d4a7eb8a268babfce4", size = 114772, upload-time = "2025-04-17T22:37:43.132Z" }, + { url = "https://files.pythonhosted.org/packages/a0/77/fead27441e749b2d574bb73d693530d59d520d4b9e9679b8e3cb779d37f2/frozenlist-1.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:37a8a52c3dfff01515e9bbbee0e6063181362f9de3db2ccf9bc96189b557cbfd", size = 119847, upload-time = "2025-04-17T22:37:45.118Z" }, + { url = "https://files.pythonhosted.org/packages/df/bd/cc6d934991c1e5d9cafda83dfdc52f987c7b28343686aef2e58a9cf89f20/frozenlist-1.6.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:46138f5a0773d064ff663d273b309b696293d7a7c00a0994c5c13a5078134b64", size = 174937, upload-time = "2025-04-17T22:37:46.635Z" }, + { url = "https://files.pythonhosted.org/packages/f2/a2/daf945f335abdbfdd5993e9dc348ef4507436936ab3c26d7cfe72f4843bf/frozenlist-1.6.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f88bc0a2b9c2a835cb888b32246c27cdab5740059fb3688852bf91e915399b91", size = 136029, upload-time = "2025-04-17T22:37:48.192Z" }, + { url = "https://files.pythonhosted.org/packages/51/65/4c3145f237a31247c3429e1c94c384d053f69b52110a0d04bfc8afc55fb2/frozenlist-1.6.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:777704c1d7655b802c7850255639672e90e81ad6fa42b99ce5ed3fbf45e338dd", size = 134831, upload-time = "2025-04-17T22:37:50.485Z" }, + { url = "https://files.pythonhosted.org/packages/77/38/03d316507d8dea84dfb99bdd515ea245628af964b2bf57759e3c9205cc5e/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85ef8d41764c7de0dcdaf64f733a27352248493a85a80661f3c678acd27e31f2", size = 392981, upload-time = "2025-04-17T22:37:52.558Z" }, + { url = "https://files.pythonhosted.org/packages/37/02/46285ef9828f318ba400a51d5bb616ded38db8466836a9cfa39f3903260b/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:da5cb36623f2b846fb25009d9d9215322318ff1c63403075f812b3b2876c8506", size = 371999, upload-time = "2025-04-17T22:37:54.092Z" }, + { url = "https://files.pythonhosted.org/packages/0d/64/1212fea37a112c3c5c05bfb5f0a81af4836ce349e69be75af93f99644da9/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbb56587a16cf0fb8acd19e90ff9924979ac1431baea8681712716a8337577b0", size = 392200, upload-time = "2025-04-17T22:37:55.951Z" }, + { url = "https://files.pythonhosted.org/packages/81/ce/9a6ea1763e3366e44a5208f76bf37c76c5da570772375e4d0be85180e588/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6154c3ba59cda3f954c6333025369e42c3acd0c6e8b6ce31eb5c5b8116c07e0", size = 390134, upload-time = "2025-04-17T22:37:57.633Z" }, + { url = "https://files.pythonhosted.org/packages/bc/36/939738b0b495b2c6d0c39ba51563e453232813042a8d908b8f9544296c29/frozenlist-1.6.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e8246877afa3f1ae5c979fe85f567d220f86a50dc6c493b9b7d8191181ae01e", size = 365208, upload-time = "2025-04-17T22:37:59.742Z" }, + { url = "https://files.pythonhosted.org/packages/b4/8b/939e62e93c63409949c25220d1ba8e88e3960f8ef6a8d9ede8f94b459d27/frozenlist-1.6.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0f6cce16306d2e117cf9db71ab3a9e8878a28176aeaf0dbe35248d97b28d0c", size = 385548, upload-time = "2025-04-17T22:38:01.416Z" }, + { url = "https://files.pythonhosted.org/packages/62/38/22d2873c90102e06a7c5a3a5b82ca47e393c6079413e8a75c72bff067fa8/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:1b8e8cd8032ba266f91136d7105706ad57770f3522eac4a111d77ac126a25a9b", size = 391123, upload-time = "2025-04-17T22:38:03.049Z" }, + { url = "https://files.pythonhosted.org/packages/44/78/63aaaf533ee0701549500f6d819be092c6065cb5c577edb70c09df74d5d0/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e2ada1d8515d3ea5378c018a5f6d14b4994d4036591a52ceaf1a1549dec8e1ad", size = 394199, upload-time = "2025-04-17T22:38:04.776Z" }, + { url = "https://files.pythonhosted.org/packages/54/45/71a6b48981d429e8fbcc08454dc99c4c2639865a646d549812883e9c9dd3/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:cdb2c7f071e4026c19a3e32b93a09e59b12000751fc9b0b7758da899e657d215", size = 373854, upload-time = "2025-04-17T22:38:06.576Z" }, + { url = "https://files.pythonhosted.org/packages/3f/f3/dbf2a5e11736ea81a66e37288bf9f881143a7822b288a992579ba1b4204d/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:03572933a1969a6d6ab509d509e5af82ef80d4a5d4e1e9f2e1cdd22c77a3f4d2", size = 395412, upload-time = "2025-04-17T22:38:08.197Z" }, + { url = "https://files.pythonhosted.org/packages/b3/f1/c63166806b331f05104d8ea385c4acd511598568b1f3e4e8297ca54f2676/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:77effc978947548b676c54bbd6a08992759ea6f410d4987d69feea9cd0919911", size = 394936, upload-time = "2025-04-17T22:38:10.056Z" }, + { url = "https://files.pythonhosted.org/packages/ef/ea/4f3e69e179a430473eaa1a75ff986526571215fefc6b9281cdc1f09a4eb8/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a2bda8be77660ad4089caf2223fdbd6db1858462c4b85b67fbfa22102021e497", size = 391459, upload-time = "2025-04-17T22:38:11.826Z" }, + { url = "https://files.pythonhosted.org/packages/d3/c3/0fc2c97dea550df9afd072a37c1e95421652e3206bbeaa02378b24c2b480/frozenlist-1.6.0-cp313-cp313t-win32.whl", hash = "sha256:a4d96dc5bcdbd834ec6b0f91027817214216b5b30316494d2b1aebffb87c534f", size = 128797, upload-time = "2025-04-17T22:38:14.013Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f5/79c9320c5656b1965634fe4be9c82b12a3305bdbc58ad9cb941131107b20/frozenlist-1.6.0-cp313-cp313t-win_amd64.whl", hash = "sha256:e18036cb4caa17ea151fd5f3d70be9d354c99eb8cf817a3ccde8a7873b074348", size = 134709, upload-time = "2025-04-17T22:38:15.551Z" }, + { url = "https://files.pythonhosted.org/packages/71/3e/b04a0adda73bd52b390d730071c0d577073d3d26740ee1bad25c3ad0f37b/frozenlist-1.6.0-py3-none-any.whl", hash = "sha256:535eec9987adb04701266b92745d6cdcef2e77669299359c3009c3404dd5d191", size = 12404, upload-time = "2025-04-17T22:38:51.668Z" }, ] [[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 } +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 }, + { 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]] @@ -1110,9 +1110,9 @@ dependencies = [ { name = "protobuf" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/dc/21/e9d043e88222317afdbdb567165fdbc3b0aad90064c7e0c9eb0ad9955ad8/google_api_core-2.25.1.tar.gz", hash = "sha256:d2aaa0b13c78c61cb3f4282c464c046e45fbd75755683c9c525e6e8f7ed0a5e8", size = 165443 } +sdist = { url = "https://files.pythonhosted.org/packages/dc/21/e9d043e88222317afdbdb567165fdbc3b0aad90064c7e0c9eb0ad9955ad8/google_api_core-2.25.1.tar.gz", hash = "sha256:d2aaa0b13c78c61cb3f4282c464c046e45fbd75755683c9c525e6e8f7ed0a5e8", size = 165443, upload-time = "2025-06-12T20:52:20.439Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/4b/ead00905132820b623732b175d66354e9d3e69fcf2a5dcdab780664e7896/google_api_core-2.25.1-py3-none-any.whl", hash = "sha256:8a2a56c1fef82987a524371f99f3bd0143702fecc670c72e600c1cda6bf8dbb7", size = 160807 }, + { url = "https://files.pythonhosted.org/packages/14/4b/ead00905132820b623732b175d66354e9d3e69fcf2a5dcdab780664e7896/google_api_core-2.25.1-py3-none-any.whl", hash = "sha256:8a2a56c1fef82987a524371f99f3bd0143702fecc670c72e600c1cda6bf8dbb7", size = 160807, upload-time = "2025-06-12T20:52:19.334Z" }, ] [package.optional-dependencies] @@ -1130,9 +1130,9 @@ dependencies = [ { name = "pyasn1-modules" }, { name = "rsa" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/84/f67f53c505a6b2c5da05c988e2a5483f5ba9eee4b1841d2e3ff22f547cd5/google_auth-2.40.2.tar.gz", hash = "sha256:a33cde547a2134273226fa4b853883559947ebe9207521f7afc707efbf690f58", size = 280990 } +sdist = { url = "https://files.pythonhosted.org/packages/66/84/f67f53c505a6b2c5da05c988e2a5483f5ba9eee4b1841d2e3ff22f547cd5/google_auth-2.40.2.tar.gz", hash = "sha256:a33cde547a2134273226fa4b853883559947ebe9207521f7afc707efbf690f58", size = 280990, upload-time = "2025-05-21T18:04:59.816Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/c7/e2d82e6702e2a9e2311c138f8e1100f21d08aed0231290872b229ae57a86/google_auth-2.40.2-py2.py3-none-any.whl", hash = "sha256:f7e568d42eedfded58734f6a60c58321896a621f7c116c411550a4b4a13da90b", size = 216102 }, + { url = "https://files.pythonhosted.org/packages/6a/c7/e2d82e6702e2a9e2311c138f8e1100f21d08aed0231290872b229ae57a86/google_auth-2.40.2-py2.py3-none-any.whl", hash = "sha256:f7e568d42eedfded58734f6a60c58321896a621f7c116c411550a4b4a13da90b", size = 216102, upload-time = "2025-05-21T18:04:57.547Z" }, ] [package.optional-dependencies] @@ -1159,9 +1159,9 @@ dependencies = [ { name = "shapely" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7c/fc/c801934d177f7eac3f3d0eadac21232a4700477bf50b4ab3c9e39c29a919/google_cloud_aiplatform-1.101.0.tar.gz", hash = "sha256:03e18763525526e165a674113840f6c048b0e4d289a6b5a05118964f41e1a579", size = 9439723 } +sdist = { url = "https://files.pythonhosted.org/packages/7c/fc/c801934d177f7eac3f3d0eadac21232a4700477bf50b4ab3c9e39c29a919/google_cloud_aiplatform-1.101.0.tar.gz", hash = "sha256:03e18763525526e165a674113840f6c048b0e4d289a6b5a05118964f41e1a579", size = 9439723, upload-time = "2025-07-01T23:11:37.024Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/e9/ce1e48bdc01c22929cb7672579106f013338cc8f535c57fff240ce869047/google_cloud_aiplatform-1.101.0-py2.py3-none-any.whl", hash = "sha256:677f55317d473eaa7a469d333144c73425b1dd15308981adcf62212f18f7b52a", size = 7850411 }, + { url = "https://files.pythonhosted.org/packages/1f/e9/ce1e48bdc01c22929cb7672579106f013338cc8f535c57fff240ce869047/google_cloud_aiplatform-1.101.0-py2.py3-none-any.whl", hash = "sha256:677f55317d473eaa7a469d333144c73425b1dd15308981adcf62212f18f7b52a", size = 7850411, upload-time = "2025-07-01T23:11:34.264Z" }, ] [[package]] @@ -1177,9 +1177,9 @@ dependencies = [ { name = "python-dateutil" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/24/f9/e9da2d56d7028f05c0e2f5edf6ce43c773220c3172666c3dd925791d763d/google_cloud_bigquery-3.34.0.tar.gz", hash = "sha256:5ee1a78ba5c2ccb9f9a8b2bf3ed76b378ea68f49b6cac0544dc55cc97ff7c1ce", size = 489091 } +sdist = { url = "https://files.pythonhosted.org/packages/24/f9/e9da2d56d7028f05c0e2f5edf6ce43c773220c3172666c3dd925791d763d/google_cloud_bigquery-3.34.0.tar.gz", hash = "sha256:5ee1a78ba5c2ccb9f9a8b2bf3ed76b378ea68f49b6cac0544dc55cc97ff7c1ce", size = 489091, upload-time = "2025-05-29T17:18:06.03Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/7e/7115c4f67ca0bc678f25bff1eab56cc37d06eb9a3978940b2ebd0705aa0a/google_cloud_bigquery-3.34.0-py3-none-any.whl", hash = "sha256:de20ded0680f8136d92ff5256270b5920dfe4fae479f5d0f73e90e5df30b1cf7", size = 253555 }, + { url = "https://files.pythonhosted.org/packages/b1/7e/7115c4f67ca0bc678f25bff1eab56cc37d06eb9a3978940b2ebd0705aa0a/google_cloud_bigquery-3.34.0-py3-none-any.whl", hash = "sha256:de20ded0680f8136d92ff5256270b5920dfe4fae479f5d0f73e90e5df30b1cf7", size = 253555, upload-time = "2025-05-29T17:18:02.904Z" }, ] [[package]] @@ -1190,9 +1190,9 @@ dependencies = [ { name = "google-api-core" }, { name = "google-auth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d6/b8/2b53838d2acd6ec6168fd284a990c76695e84c65deee79c9f3a4276f6b4f/google_cloud_core-2.4.3.tar.gz", hash = "sha256:1fab62d7102844b278fe6dead3af32408b1df3eb06f5c7e8634cbd40edc4da53", size = 35861 } +sdist = { url = "https://files.pythonhosted.org/packages/d6/b8/2b53838d2acd6ec6168fd284a990c76695e84c65deee79c9f3a4276f6b4f/google_cloud_core-2.4.3.tar.gz", hash = "sha256:1fab62d7102844b278fe6dead3af32408b1df3eb06f5c7e8634cbd40edc4da53", size = 35861, upload-time = "2025-03-10T21:05:38.948Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/86/bda7241a8da2d28a754aad2ba0f6776e35b67e37c36ae0c45d49370f1014/google_cloud_core-2.4.3-py2.py3-none-any.whl", hash = "sha256:5130f9f4c14b4fafdff75c79448f9495cfade0d8775facf1b09c3bf67e027f6e", size = 29348 }, + { url = "https://files.pythonhosted.org/packages/40/86/bda7241a8da2d28a754aad2ba0f6776e35b67e37c36ae0c45d49370f1014/google_cloud_core-2.4.3-py2.py3-none-any.whl", hash = "sha256:5130f9f4c14b4fafdff75c79448f9495cfade0d8775facf1b09c3bf67e027f6e", size = 29348, upload-time = "2025-03-10T21:05:37.785Z" }, ] [[package]] @@ -1206,9 +1206,9 @@ dependencies = [ { name = "proto-plus" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6e/ca/a4648f5038cb94af4b3942815942a03aa9398f9fb0bef55b3f1585b9940d/google_cloud_resource_manager-1.14.2.tar.gz", hash = "sha256:962e2d904c550d7bac48372607904ff7bb3277e3bb4a36d80cc9a37e28e6eb74", size = 446370 } +sdist = { url = "https://files.pythonhosted.org/packages/6e/ca/a4648f5038cb94af4b3942815942a03aa9398f9fb0bef55b3f1585b9940d/google_cloud_resource_manager-1.14.2.tar.gz", hash = "sha256:962e2d904c550d7bac48372607904ff7bb3277e3bb4a36d80cc9a37e28e6eb74", size = 446370, upload-time = "2025-03-17T11:35:56.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/ea/a92631c358da377af34d3a9682c97af83185c2d66363d5939ab4a1169a7f/google_cloud_resource_manager-1.14.2-py3-none-any.whl", hash = "sha256:d0fa954dedd1d2b8e13feae9099c01b8aac515b648e612834f9942d2795a9900", size = 394344 }, + { url = "https://files.pythonhosted.org/packages/b1/ea/a92631c358da377af34d3a9682c97af83185c2d66363d5939ab4a1169a7f/google_cloud_resource_manager-1.14.2-py3-none-any.whl", hash = "sha256:d0fa954dedd1d2b8e13feae9099c01b8aac515b648e612834f9942d2795a9900", size = 394344, upload-time = "2025-03-17T11:35:54.722Z" }, ] [[package]] @@ -1223,44 +1223,44 @@ dependencies = [ { name = "google-resumable-media" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/36/76/4d965702e96bb67976e755bed9828fa50306dca003dbee08b67f41dd265e/google_cloud_storage-2.19.0.tar.gz", hash = "sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2", size = 5535488 } +sdist = { url = "https://files.pythonhosted.org/packages/36/76/4d965702e96bb67976e755bed9828fa50306dca003dbee08b67f41dd265e/google_cloud_storage-2.19.0.tar.gz", hash = "sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2", size = 5535488, upload-time = "2024-12-05T01:35:06.49Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/94/6db383d8ee1adf45dc6c73477152b82731fa4c4a46d9c1932cc8757e0fd4/google_cloud_storage-2.19.0-py2.py3-none-any.whl", hash = "sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba", size = 131787 }, + { url = "https://files.pythonhosted.org/packages/d5/94/6db383d8ee1adf45dc6c73477152b82731fa4c4a46d9c1932cc8757e0fd4/google_cloud_storage-2.19.0-py2.py3-none-any.whl", hash = "sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba", size = 131787, upload-time = "2024-12-05T01:35:04.736Z" }, ] [[package]] name = "google-crc32c" version = "1.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/ae/87802e6d9f9d69adfaedfcfd599266bf386a54d0be058b532d04c794f76d/google_crc32c-1.7.1.tar.gz", hash = "sha256:2bff2305f98846f3e825dbeec9ee406f89da7962accdb29356e4eadc251bd472", size = 14495 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/69/b1b05cf415df0d86691d6a8b4b7e60ab3a6fb6efb783ee5cd3ed1382bfd3/google_crc32c-1.7.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:b07d48faf8292b4db7c3d64ab86f950c2e94e93a11fd47271c28ba458e4a0d76", size = 30467 }, - { url = "https://files.pythonhosted.org/packages/44/3d/92f8928ecd671bd5b071756596971c79d252d09b835cdca5a44177fa87aa/google_crc32c-1.7.1-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:7cc81b3a2fbd932a4313eb53cc7d9dde424088ca3a0337160f35d91826880c1d", size = 30311 }, - { url = "https://files.pythonhosted.org/packages/33/42/c2d15a73df79d45ed6b430b9e801d0bd8e28ac139a9012d7d58af50a385d/google_crc32c-1.7.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1c67ca0a1f5b56162951a9dae987988679a7db682d6f97ce0f6381ebf0fbea4c", size = 37889 }, - { url = "https://files.pythonhosted.org/packages/57/ea/ac59c86a3c694afd117bb669bde32aaf17d0de4305d01d706495f09cbf19/google_crc32c-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc5319db92daa516b653600794d5b9f9439a9a121f3e162f94b0e1891c7933cb", size = 33028 }, - { url = "https://files.pythonhosted.org/packages/60/44/87e77e8476767a4a93f6cf271157c6d948eacec63688c093580af13b04be/google_crc32c-1.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcdf5a64adb747610140572ed18d011896e3b9ae5195f2514b7ff678c80f1603", size = 38026 }, - { url = "https://files.pythonhosted.org/packages/c8/bf/21ac7bb305cd7c1a6de9c52f71db0868e104a5b573a4977cd9d0ff830f82/google_crc32c-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:754561c6c66e89d55754106739e22fdaa93fafa8da7221b29c8b8e8270c6ec8a", size = 33476 }, - { url = "https://files.pythonhosted.org/packages/f7/94/220139ea87822b6fdfdab4fb9ba81b3fff7ea2c82e2af34adc726085bffc/google_crc32c-1.7.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6fbab4b935989e2c3610371963ba1b86afb09537fd0c633049be82afe153ac06", size = 30468 }, - { url = "https://files.pythonhosted.org/packages/94/97/789b23bdeeb9d15dc2904660463ad539d0318286d7633fe2760c10ed0c1c/google_crc32c-1.7.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:ed66cbe1ed9cbaaad9392b5259b3eba4a9e565420d734e6238813c428c3336c9", size = 30313 }, - { url = "https://files.pythonhosted.org/packages/81/b8/976a2b843610c211e7ccb3e248996a61e87dbb2c09b1499847e295080aec/google_crc32c-1.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee6547b657621b6cbed3562ea7826c3e11cab01cd33b74e1f677690652883e77", size = 33048 }, - { url = "https://files.pythonhosted.org/packages/c9/16/a3842c2cf591093b111d4a5e2bfb478ac6692d02f1b386d2a33283a19dc9/google_crc32c-1.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d68e17bad8f7dd9a49181a1f5a8f4b251c6dbc8cc96fb79f1d321dfd57d66f53", size = 32669 }, - { url = "https://files.pythonhosted.org/packages/04/17/ed9aba495916fcf5fe4ecb2267ceb851fc5f273c4e4625ae453350cfd564/google_crc32c-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:6335de12921f06e1f774d0dd1fbea6bf610abe0887a1638f64d694013138be5d", size = 33476 }, - { url = "https://files.pythonhosted.org/packages/dd/b7/787e2453cf8639c94b3d06c9d61f512234a82e1d12d13d18584bd3049904/google_crc32c-1.7.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2d73a68a653c57281401871dd4aeebbb6af3191dcac751a76ce430df4d403194", size = 30470 }, - { url = "https://files.pythonhosted.org/packages/ed/b4/6042c2b0cbac3ec3a69bb4c49b28d2f517b7a0f4a0232603c42c58e22b44/google_crc32c-1.7.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:22beacf83baaf59f9d3ab2bbb4db0fb018da8e5aebdce07ef9f09fce8220285e", size = 30315 }, - { url = "https://files.pythonhosted.org/packages/29/ad/01e7a61a5d059bc57b702d9ff6a18b2585ad97f720bd0a0dbe215df1ab0e/google_crc32c-1.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19eafa0e4af11b0a4eb3974483d55d2d77ad1911e6cf6f832e1574f6781fd337", size = 33180 }, - { url = "https://files.pythonhosted.org/packages/3b/a5/7279055cf004561894ed3a7bfdf5bf90a53f28fadd01af7cd166e88ddf16/google_crc32c-1.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d86616faaea68101195c6bdc40c494e4d76f41e07a37ffdef270879c15fb65", size = 32794 }, - { url = "https://files.pythonhosted.org/packages/0f/d6/77060dbd140c624e42ae3ece3df53b9d811000729a5c821b9fd671ceaac6/google_crc32c-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:b7491bdc0c7564fcf48c0179d2048ab2f7c7ba36b84ccd3a3e1c3f7a72d3bba6", size = 33477 }, - { url = "https://files.pythonhosted.org/packages/8b/72/b8d785e9184ba6297a8620c8a37cf6e39b81a8ca01bb0796d7cbb28b3386/google_crc32c-1.7.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:df8b38bdaf1629d62d51be8bdd04888f37c451564c2042d36e5812da9eff3c35", size = 30467 }, - { url = "https://files.pythonhosted.org/packages/34/25/5f18076968212067c4e8ea95bf3b69669f9fc698476e5f5eb97d5b37999f/google_crc32c-1.7.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:e42e20a83a29aa2709a0cf271c7f8aefaa23b7ab52e53b322585297bb94d4638", size = 30309 }, - { url = "https://files.pythonhosted.org/packages/92/83/9228fe65bf70e93e419f38bdf6c5ca5083fc6d32886ee79b450ceefd1dbd/google_crc32c-1.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:905a385140bf492ac300026717af339790921f411c0dfd9aa5a9e69a08ed32eb", size = 33133 }, - { url = "https://files.pythonhosted.org/packages/c3/ca/1ea2fd13ff9f8955b85e7956872fdb7050c4ace8a2306a6d177edb9cf7fe/google_crc32c-1.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b211ddaf20f7ebeec5c333448582c224a7c90a9d98826fbab82c0ddc11348e6", size = 32773 }, - { url = "https://files.pythonhosted.org/packages/89/32/a22a281806e3ef21b72db16f948cad22ec68e4bdd384139291e00ff82fe2/google_crc32c-1.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:0f99eaa09a9a7e642a61e06742856eec8b19fc0037832e03f941fe7cf0c8e4db", size = 33475 }, - { url = "https://files.pythonhosted.org/packages/b8/c5/002975aff514e57fc084ba155697a049b3f9b52225ec3bc0f542871dd524/google_crc32c-1.7.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32d1da0d74ec5634a05f53ef7df18fc646666a25efaaca9fc7dcfd4caf1d98c3", size = 33243 }, - { url = "https://files.pythonhosted.org/packages/61/cb/c585282a03a0cea70fcaa1bf55d5d702d0f2351094d663ec3be1c6c67c52/google_crc32c-1.7.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e10554d4abc5238823112c2ad7e4560f96c7bf3820b202660373d769d9e6e4c9", size = 32870 }, - { url = "https://files.pythonhosted.org/packages/0b/43/31e57ce04530794917dfe25243860ec141de9fadf4aa9783dffe7dac7c39/google_crc32c-1.7.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8e9afc74168b0b2232fb32dd202c93e46b7d5e4bf03e66ba5dc273bb3559589", size = 28242 }, - { url = "https://files.pythonhosted.org/packages/eb/f3/8b84cd4e0ad111e63e30eb89453f8dd308e3ad36f42305cf8c202461cdf0/google_crc32c-1.7.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa8136cc14dd27f34a3221c0f16fd42d8a40e4778273e61a3c19aedaa44daf6b", size = 28049 }, - { url = "https://files.pythonhosted.org/packages/16/1b/1693372bf423ada422f80fd88260dbfd140754adb15cbc4d7e9a68b1cb8e/google_crc32c-1.7.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85fef7fae11494e747c9fd1359a527e5970fc9603c90764843caabd3a16a0a48", size = 28241 }, - { url = "https://files.pythonhosted.org/packages/fd/3c/2a19a60a473de48717b4efb19398c3f914795b64a96cf3fbe82588044f78/google_crc32c-1.7.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6efb97eb4369d52593ad6f75e7e10d053cf00c48983f7a973105bc70b0ac4d82", size = 28048 }, +sdist = { url = "https://files.pythonhosted.org/packages/19/ae/87802e6d9f9d69adfaedfcfd599266bf386a54d0be058b532d04c794f76d/google_crc32c-1.7.1.tar.gz", hash = "sha256:2bff2305f98846f3e825dbeec9ee406f89da7962accdb29356e4eadc251bd472", size = 14495, upload-time = "2025-03-26T14:29:13.32Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/69/b1b05cf415df0d86691d6a8b4b7e60ab3a6fb6efb783ee5cd3ed1382bfd3/google_crc32c-1.7.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:b07d48faf8292b4db7c3d64ab86f950c2e94e93a11fd47271c28ba458e4a0d76", size = 30467, upload-time = "2025-03-26T14:31:11.92Z" }, + { url = "https://files.pythonhosted.org/packages/44/3d/92f8928ecd671bd5b071756596971c79d252d09b835cdca5a44177fa87aa/google_crc32c-1.7.1-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:7cc81b3a2fbd932a4313eb53cc7d9dde424088ca3a0337160f35d91826880c1d", size = 30311, upload-time = "2025-03-26T14:53:14.161Z" }, + { url = "https://files.pythonhosted.org/packages/33/42/c2d15a73df79d45ed6b430b9e801d0bd8e28ac139a9012d7d58af50a385d/google_crc32c-1.7.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1c67ca0a1f5b56162951a9dae987988679a7db682d6f97ce0f6381ebf0fbea4c", size = 37889, upload-time = "2025-03-26T14:41:27.83Z" }, + { url = "https://files.pythonhosted.org/packages/57/ea/ac59c86a3c694afd117bb669bde32aaf17d0de4305d01d706495f09cbf19/google_crc32c-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc5319db92daa516b653600794d5b9f9439a9a121f3e162f94b0e1891c7933cb", size = 33028, upload-time = "2025-03-26T14:41:29.141Z" }, + { url = "https://files.pythonhosted.org/packages/60/44/87e77e8476767a4a93f6cf271157c6d948eacec63688c093580af13b04be/google_crc32c-1.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcdf5a64adb747610140572ed18d011896e3b9ae5195f2514b7ff678c80f1603", size = 38026, upload-time = "2025-03-26T14:41:29.921Z" }, + { url = "https://files.pythonhosted.org/packages/c8/bf/21ac7bb305cd7c1a6de9c52f71db0868e104a5b573a4977cd9d0ff830f82/google_crc32c-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:754561c6c66e89d55754106739e22fdaa93fafa8da7221b29c8b8e8270c6ec8a", size = 33476, upload-time = "2025-03-26T14:29:09.086Z" }, + { url = "https://files.pythonhosted.org/packages/f7/94/220139ea87822b6fdfdab4fb9ba81b3fff7ea2c82e2af34adc726085bffc/google_crc32c-1.7.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6fbab4b935989e2c3610371963ba1b86afb09537fd0c633049be82afe153ac06", size = 30468, upload-time = "2025-03-26T14:32:52.215Z" }, + { url = "https://files.pythonhosted.org/packages/94/97/789b23bdeeb9d15dc2904660463ad539d0318286d7633fe2760c10ed0c1c/google_crc32c-1.7.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:ed66cbe1ed9cbaaad9392b5259b3eba4a9e565420d734e6238813c428c3336c9", size = 30313, upload-time = "2025-03-26T14:57:38.758Z" }, + { url = "https://files.pythonhosted.org/packages/81/b8/976a2b843610c211e7ccb3e248996a61e87dbb2c09b1499847e295080aec/google_crc32c-1.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee6547b657621b6cbed3562ea7826c3e11cab01cd33b74e1f677690652883e77", size = 33048, upload-time = "2025-03-26T14:41:30.679Z" }, + { url = "https://files.pythonhosted.org/packages/c9/16/a3842c2cf591093b111d4a5e2bfb478ac6692d02f1b386d2a33283a19dc9/google_crc32c-1.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d68e17bad8f7dd9a49181a1f5a8f4b251c6dbc8cc96fb79f1d321dfd57d66f53", size = 32669, upload-time = "2025-03-26T14:41:31.432Z" }, + { url = "https://files.pythonhosted.org/packages/04/17/ed9aba495916fcf5fe4ecb2267ceb851fc5f273c4e4625ae453350cfd564/google_crc32c-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:6335de12921f06e1f774d0dd1fbea6bf610abe0887a1638f64d694013138be5d", size = 33476, upload-time = "2025-03-26T14:29:10.211Z" }, + { url = "https://files.pythonhosted.org/packages/dd/b7/787e2453cf8639c94b3d06c9d61f512234a82e1d12d13d18584bd3049904/google_crc32c-1.7.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2d73a68a653c57281401871dd4aeebbb6af3191dcac751a76ce430df4d403194", size = 30470, upload-time = "2025-03-26T14:34:31.655Z" }, + { url = "https://files.pythonhosted.org/packages/ed/b4/6042c2b0cbac3ec3a69bb4c49b28d2f517b7a0f4a0232603c42c58e22b44/google_crc32c-1.7.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:22beacf83baaf59f9d3ab2bbb4db0fb018da8e5aebdce07ef9f09fce8220285e", size = 30315, upload-time = "2025-03-26T15:01:54.634Z" }, + { url = "https://files.pythonhosted.org/packages/29/ad/01e7a61a5d059bc57b702d9ff6a18b2585ad97f720bd0a0dbe215df1ab0e/google_crc32c-1.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19eafa0e4af11b0a4eb3974483d55d2d77ad1911e6cf6f832e1574f6781fd337", size = 33180, upload-time = "2025-03-26T14:41:32.168Z" }, + { url = "https://files.pythonhosted.org/packages/3b/a5/7279055cf004561894ed3a7bfdf5bf90a53f28fadd01af7cd166e88ddf16/google_crc32c-1.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d86616faaea68101195c6bdc40c494e4d76f41e07a37ffdef270879c15fb65", size = 32794, upload-time = "2025-03-26T14:41:33.264Z" }, + { url = "https://files.pythonhosted.org/packages/0f/d6/77060dbd140c624e42ae3ece3df53b9d811000729a5c821b9fd671ceaac6/google_crc32c-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:b7491bdc0c7564fcf48c0179d2048ab2f7c7ba36b84ccd3a3e1c3f7a72d3bba6", size = 33477, upload-time = "2025-03-26T14:29:10.94Z" }, + { url = "https://files.pythonhosted.org/packages/8b/72/b8d785e9184ba6297a8620c8a37cf6e39b81a8ca01bb0796d7cbb28b3386/google_crc32c-1.7.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:df8b38bdaf1629d62d51be8bdd04888f37c451564c2042d36e5812da9eff3c35", size = 30467, upload-time = "2025-03-26T14:36:06.909Z" }, + { url = "https://files.pythonhosted.org/packages/34/25/5f18076968212067c4e8ea95bf3b69669f9fc698476e5f5eb97d5b37999f/google_crc32c-1.7.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:e42e20a83a29aa2709a0cf271c7f8aefaa23b7ab52e53b322585297bb94d4638", size = 30309, upload-time = "2025-03-26T15:06:15.318Z" }, + { url = "https://files.pythonhosted.org/packages/92/83/9228fe65bf70e93e419f38bdf6c5ca5083fc6d32886ee79b450ceefd1dbd/google_crc32c-1.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:905a385140bf492ac300026717af339790921f411c0dfd9aa5a9e69a08ed32eb", size = 33133, upload-time = "2025-03-26T14:41:34.388Z" }, + { url = "https://files.pythonhosted.org/packages/c3/ca/1ea2fd13ff9f8955b85e7956872fdb7050c4ace8a2306a6d177edb9cf7fe/google_crc32c-1.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b211ddaf20f7ebeec5c333448582c224a7c90a9d98826fbab82c0ddc11348e6", size = 32773, upload-time = "2025-03-26T14:41:35.19Z" }, + { url = "https://files.pythonhosted.org/packages/89/32/a22a281806e3ef21b72db16f948cad22ec68e4bdd384139291e00ff82fe2/google_crc32c-1.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:0f99eaa09a9a7e642a61e06742856eec8b19fc0037832e03f941fe7cf0c8e4db", size = 33475, upload-time = "2025-03-26T14:29:11.771Z" }, + { url = "https://files.pythonhosted.org/packages/b8/c5/002975aff514e57fc084ba155697a049b3f9b52225ec3bc0f542871dd524/google_crc32c-1.7.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32d1da0d74ec5634a05f53ef7df18fc646666a25efaaca9fc7dcfd4caf1d98c3", size = 33243, upload-time = "2025-03-26T14:41:35.975Z" }, + { url = "https://files.pythonhosted.org/packages/61/cb/c585282a03a0cea70fcaa1bf55d5d702d0f2351094d663ec3be1c6c67c52/google_crc32c-1.7.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e10554d4abc5238823112c2ad7e4560f96c7bf3820b202660373d769d9e6e4c9", size = 32870, upload-time = "2025-03-26T14:41:37.08Z" }, + { url = "https://files.pythonhosted.org/packages/0b/43/31e57ce04530794917dfe25243860ec141de9fadf4aa9783dffe7dac7c39/google_crc32c-1.7.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8e9afc74168b0b2232fb32dd202c93e46b7d5e4bf03e66ba5dc273bb3559589", size = 28242, upload-time = "2025-03-26T14:41:42.858Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f3/8b84cd4e0ad111e63e30eb89453f8dd308e3ad36f42305cf8c202461cdf0/google_crc32c-1.7.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa8136cc14dd27f34a3221c0f16fd42d8a40e4778273e61a3c19aedaa44daf6b", size = 28049, upload-time = "2025-03-26T14:41:44.651Z" }, + { url = "https://files.pythonhosted.org/packages/16/1b/1693372bf423ada422f80fd88260dbfd140754adb15cbc4d7e9a68b1cb8e/google_crc32c-1.7.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85fef7fae11494e747c9fd1359a527e5970fc9603c90764843caabd3a16a0a48", size = 28241, upload-time = "2025-03-26T14:41:45.898Z" }, + { url = "https://files.pythonhosted.org/packages/fd/3c/2a19a60a473de48717b4efb19398c3f914795b64a96cf3fbe82588044f78/google_crc32c-1.7.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6efb97eb4369d52593ad6f75e7e10d053cf00c48983f7a973105bc70b0ac4d82", size = 28048, upload-time = "2025-03-26T14:41:46.696Z" }, ] [[package]] @@ -1276,9 +1276,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/1f/1a52736e87b4a22afef615de45e2f509fbfb55c09798620b0c3f394076ef/google_genai-1.16.1.tar.gz", hash = "sha256:4b4ed4ed781a9d61e5ce0fef1486dd3a5d7ff0a73bd76b9633d21e687ab998df", size = 194270 } +sdist = { url = "https://files.pythonhosted.org/packages/ca/1f/1a52736e87b4a22afef615de45e2f509fbfb55c09798620b0c3f394076ef/google_genai-1.16.1.tar.gz", hash = "sha256:4b4ed4ed781a9d61e5ce0fef1486dd3a5d7ff0a73bd76b9633d21e687ab998df", size = 194270, upload-time = "2025-05-20T01:05:26.717Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/31/30caa8d4ae987e47c5250fb6680588733863fd5b39cacb03ba1977c29bde/google_genai-1.16.1-py3-none-any.whl", hash = "sha256:6ae5d24282244f577ca4f0d95c09f75ab29e556602c9d3531b70161e34cd2a39", size = 196327 }, + { url = "https://files.pythonhosted.org/packages/bc/31/30caa8d4ae987e47c5250fb6680588733863fd5b39cacb03ba1977c29bde/google_genai-1.16.1-py3-none-any.whl", hash = "sha256:6ae5d24282244f577ca4f0d95c09f75ab29e556602c9d3531b70161e34cd2a39", size = 196327, upload-time = "2025-05-20T01:05:24.831Z" }, ] [[package]] @@ -1288,9 +1288,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-crc32c" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/5a/0efdc02665dca14e0837b62c8a1a93132c264bd02054a15abb2218afe0ae/google_resumable_media-2.7.2.tar.gz", hash = "sha256:5280aed4629f2b60b847b0d42f9857fd4935c11af266744df33d8074cae92fe0", size = 2163099 } +sdist = { url = "https://files.pythonhosted.org/packages/58/5a/0efdc02665dca14e0837b62c8a1a93132c264bd02054a15abb2218afe0ae/google_resumable_media-2.7.2.tar.gz", hash = "sha256:5280aed4629f2b60b847b0d42f9857fd4935c11af266744df33d8074cae92fe0", size = 2163099, upload-time = "2024-08-07T22:20:38.555Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/35/b8d3baf8c46695858cb9d8835a53baa1eeb9906ddaf2f728a5f5b640fd1e/google_resumable_media-2.7.2-py2.py3-none-any.whl", hash = "sha256:3ce7551e9fe6d99e9a126101d2536612bb73486721951e9562fee0f90c6ababa", size = 81251 }, + { url = "https://files.pythonhosted.org/packages/82/35/b8d3baf8c46695858cb9d8835a53baa1eeb9906ddaf2f728a5f5b640fd1e/google_resumable_media-2.7.2-py2.py3-none-any.whl", hash = "sha256:3ce7551e9fe6d99e9a126101d2536612bb73486721951e9562fee0f90c6ababa", size = 81251, upload-time = "2024-08-07T22:20:36.409Z" }, ] [[package]] @@ -1300,9 +1300,9 @@ 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 } +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 }, + { 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.optional-dependencies] @@ -1319,57 +1319,57 @@ dependencies = [ { name = "grpcio" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/4e/8d0ca3b035e41fe0b3f31ebbb638356af720335e5a11154c330169b40777/grpc_google_iam_v1-0.14.2.tar.gz", hash = "sha256:b3e1fc387a1a329e41672197d0ace9de22c78dd7d215048c4c78712073f7bd20", size = 16259 } +sdist = { url = "https://files.pythonhosted.org/packages/b9/4e/8d0ca3b035e41fe0b3f31ebbb638356af720335e5a11154c330169b40777/grpc_google_iam_v1-0.14.2.tar.gz", hash = "sha256:b3e1fc387a1a329e41672197d0ace9de22c78dd7d215048c4c78712073f7bd20", size = 16259, upload-time = "2025-03-17T11:40:23.586Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/66/6f/dd9b178aee7835b96c2e63715aba6516a9d50f6bebbd1cc1d32c82a2a6c3/grpc_google_iam_v1-0.14.2-py3-none-any.whl", hash = "sha256:a3171468459770907926d56a440b2bb643eec1d7ba215f48f3ecece42b4d8351", size = 19242 }, + { url = "https://files.pythonhosted.org/packages/66/6f/dd9b178aee7835b96c2e63715aba6516a9d50f6bebbd1cc1d32c82a2a6c3/grpc_google_iam_v1-0.14.2-py3-none-any.whl", hash = "sha256:a3171468459770907926d56a440b2bb643eec1d7ba215f48f3ecece42b4d8351", size = 19242, upload-time = "2025-03-17T11:40:22.648Z" }, ] [[package]] name = "grpcio" version = "1.73.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/7b/ca3f561aeecf0c846d15e1b38921a60dffffd5d4113931198fbf455334ee/grpcio-1.73.0.tar.gz", hash = "sha256:3af4c30918a7f0d39de500d11255f8d9da4f30e94a2033e70fe2a720e184bd8e", size = 12786424 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/44/5ca479c880b9f56c9a9502873ea500c09d1087dc868217a90724c24d83d0/grpcio-1.73.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:d050197eeed50f858ef6c51ab09514856f957dba7b1f7812698260fc9cc417f6", size = 5365135 }, - { url = "https://files.pythonhosted.org/packages/8d/b7/78ff355cdb602ab01ea437d316846847e0c1f7d109596e5409402cc13156/grpcio-1.73.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:ebb8d5f4b0200916fb292a964a4d41210de92aba9007e33d8551d85800ea16cb", size = 10609627 }, - { url = "https://files.pythonhosted.org/packages/8d/92/5111235062b9da0e3010e5fd2bdceb766113fcf60520f9c23eb651089dd7/grpcio-1.73.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:c0811331b469e3f15dda5f90ab71bcd9681189a83944fd6dc908e2c9249041ef", size = 5803418 }, - { url = "https://files.pythonhosted.org/packages/76/fa/dbf3fca0b91fa044f1114b11adc3d4ccc18ab1ac278daa69d450fd9aaef2/grpcio-1.73.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12787c791c3993d0ea1cc8bf90393647e9a586066b3b322949365d2772ba965b", size = 6444741 }, - { url = "https://files.pythonhosted.org/packages/44/e1/e7c830c1a29abd13f0e7e861c8db57a67db5cb8a1edc6b9d9cd44c26a1e5/grpcio-1.73.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c17771e884fddf152f2a0df12478e8d02853e5b602a10a9a9f1f52fa02b1d32", size = 6040755 }, - { url = "https://files.pythonhosted.org/packages/b4/57/2eaccbfdd8298ab6bb4504600a4283260983a9db7378eb79c922fd559883/grpcio-1.73.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:275e23d4c428c26b51857bbd95fcb8e528783597207ec592571e4372b300a29f", size = 6132216 }, - { url = "https://files.pythonhosted.org/packages/81/a4/1bd2c59d7426ab640b121f42acb820ff7cd5c561d03e9c9164cb8431128e/grpcio-1.73.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9ffc972b530bf73ef0f948f799482a1bf12d9b6f33406a8e6387c0ca2098a833", size = 6774779 }, - { url = "https://files.pythonhosted.org/packages/c6/64/70ee85055b4107acbe1af6a99ef6885e34db89083e53e5c27b8442e3aa38/grpcio-1.73.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d269df64aff092b2cec5e015d8ae09c7e90888b5c35c24fdca719a2c9f35", size = 6304223 }, - { url = "https://files.pythonhosted.org/packages/06/02/4b3c373edccf29205205a6d329a267b9337ecbbf658bc70f0a18d63d0a50/grpcio-1.73.0-cp310-cp310-win32.whl", hash = "sha256:072d8154b8f74300ed362c01d54af8b93200c1a9077aeaea79828d48598514f1", size = 3679738 }, - { url = "https://files.pythonhosted.org/packages/30/7a/d6dab939cda2129e39a872ad48f61c9951567dcda8ab419b8de446315a68/grpcio-1.73.0-cp310-cp310-win_amd64.whl", hash = "sha256:ce953d9d2100e1078a76a9dc2b7338d5415924dc59c69a15bf6e734db8a0f1ca", size = 4340441 }, - { url = "https://files.pythonhosted.org/packages/dd/31/9de81fd12f7b27e6af403531b7249d76f743d58e0654e624b3df26a43ce2/grpcio-1.73.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:51036f641f171eebe5fa7aaca5abbd6150f0c338dab3a58f9111354240fe36ec", size = 5363773 }, - { url = "https://files.pythonhosted.org/packages/32/9e/2cb78be357a7f1fc4942b81468ef3c7e5fd3df3ac010540459c10895a57b/grpcio-1.73.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:d12bbb88381ea00bdd92c55aff3da3391fd85bc902c41275c8447b86f036ce0f", size = 10621912 }, - { url = "https://files.pythonhosted.org/packages/59/2f/b43954811a2e218a2761c0813800773ac0ca187b94fd2b8494e8ef232dc8/grpcio-1.73.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:483c507c2328ed0e01bc1adb13d1eada05cc737ec301d8e5a8f4a90f387f1790", size = 5807985 }, - { url = "https://files.pythonhosted.org/packages/1b/bf/68e9f47e7ee349ffee712dcd907ee66826cf044f0dec7ab517421e56e857/grpcio-1.73.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c201a34aa960c962d0ce23fe5f423f97e9d4b518ad605eae6d0a82171809caaa", size = 6448218 }, - { url = "https://files.pythonhosted.org/packages/af/dd/38ae43dd58480d609350cf1411fdac5c2ebb243e2c770f6f7aa3773d5e29/grpcio-1.73.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:859f70c8e435e8e1fa060e04297c6818ffc81ca9ebd4940e180490958229a45a", size = 6044343 }, - { url = "https://files.pythonhosted.org/packages/93/44/b6770b55071adb86481f36dae87d332fcad883b7f560bba9a940394ba018/grpcio-1.73.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e2459a27c6886e7e687e4e407778425f3c6a971fa17a16420227bda39574d64b", size = 6135858 }, - { url = "https://files.pythonhosted.org/packages/d3/9f/63de49fcef436932fcf0ffb978101a95c83c177058dbfb56dbf30ab81659/grpcio-1.73.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e0084d4559ee3dbdcce9395e1bc90fdd0262529b32c417a39ecbc18da8074ac7", size = 6775806 }, - { url = "https://files.pythonhosted.org/packages/4d/67/c11f1953469162e958f09690ec3a9be3fdb29dea7f5661362a664f9d609a/grpcio-1.73.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef5fff73d5f724755693a464d444ee0a448c6cdfd3c1616a9223f736c622617d", size = 6308413 }, - { url = "https://files.pythonhosted.org/packages/ba/6a/9dd04426337db07f28bd51a986b7a038ba56912c81b5bb1083c17dd63404/grpcio-1.73.0-cp311-cp311-win32.whl", hash = "sha256:965a16b71a8eeef91fc4df1dc40dc39c344887249174053814f8a8e18449c4c3", size = 3678972 }, - { url = "https://files.pythonhosted.org/packages/04/8b/8c0a8a4fdc2e7977d325eafc587c9cf468039693ac23ad707153231d3cb2/grpcio-1.73.0-cp311-cp311-win_amd64.whl", hash = "sha256:b71a7b4483d1f753bbc11089ff0f6fa63b49c97a9cc20552cded3fcad466d23b", size = 4342967 }, - { url = "https://files.pythonhosted.org/packages/9d/4d/e938f3a0e51a47f2ce7e55f12f19f316e7074770d56a7c2765e782ec76bc/grpcio-1.73.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:fb9d7c27089d9ba3746f18d2109eb530ef2a37452d2ff50f5a6696cd39167d3b", size = 5334911 }, - { url = "https://files.pythonhosted.org/packages/13/56/f09c72c43aa8d6f15a71f2c63ebdfac9cf9314363dea2598dc501d8370db/grpcio-1.73.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:128ba2ebdac41e41554d492b82c34586a90ebd0766f8ebd72160c0e3a57b9155", size = 10601460 }, - { url = "https://files.pythonhosted.org/packages/20/e3/85496edc81e41b3c44ebefffc7bce133bb531120066877df0f910eabfa19/grpcio-1.73.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:068ecc415f79408d57a7f146f54cdf9f0acb4b301a52a9e563973dc981e82f3d", size = 5759191 }, - { url = "https://files.pythonhosted.org/packages/88/cc/fef74270a6d29f35ad744bfd8e6c05183f35074ff34c655a2c80f3b422b2/grpcio-1.73.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ddc1cfb2240f84d35d559ade18f69dcd4257dbaa5ba0de1a565d903aaab2968", size = 6409961 }, - { url = "https://files.pythonhosted.org/packages/b0/e6/13cfea15e3b8f79c4ae7b676cb21fab70978b0fde1e1d28bb0e073291290/grpcio-1.73.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e53007f70d9783f53b41b4cf38ed39a8e348011437e4c287eee7dd1d39d54b2f", size = 6003948 }, - { url = "https://files.pythonhosted.org/packages/c2/ed/b1a36dad4cc0dbf1f83f6d7b58825fefd5cc9ff3a5036e46091335649473/grpcio-1.73.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4dd8d8d092efede7d6f48d695ba2592046acd04ccf421436dd7ed52677a9ad29", size = 6103788 }, - { url = "https://files.pythonhosted.org/packages/e7/c8/d381433d3d46d10f6858126d2d2245ef329e30f3752ce4514c93b95ca6fc/grpcio-1.73.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:70176093d0a95b44d24baa9c034bb67bfe2b6b5f7ebc2836f4093c97010e17fd", size = 6749508 }, - { url = "https://files.pythonhosted.org/packages/87/0a/ff0c31dbd15e63b34320efafac647270aa88c31aa19ff01154a73dc7ce86/grpcio-1.73.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:085ebe876373ca095e24ced95c8f440495ed0b574c491f7f4f714ff794bbcd10", size = 6284342 }, - { url = "https://files.pythonhosted.org/packages/fd/73/f762430c0ba867403b9d6e463afe026bf019bd9206eee753785239719273/grpcio-1.73.0-cp312-cp312-win32.whl", hash = "sha256:cfc556c1d6aef02c727ec7d0016827a73bfe67193e47c546f7cadd3ee6bf1a60", size = 3669319 }, - { url = "https://files.pythonhosted.org/packages/10/8b/3411609376b2830449cf416f457ad9d2aacb7f562e1b90fdd8bdedf26d63/grpcio-1.73.0-cp312-cp312-win_amd64.whl", hash = "sha256:bbf45d59d090bf69f1e4e1594832aaf40aa84b31659af3c5e2c3f6a35202791a", size = 4335596 }, - { url = "https://files.pythonhosted.org/packages/60/da/6f3f7a78e5455c4cbe87c85063cc6da05d65d25264f9d4aed800ece46294/grpcio-1.73.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:da1d677018ef423202aca6d73a8d3b2cb245699eb7f50eb5f74cae15a8e1f724", size = 5335867 }, - { url = "https://files.pythonhosted.org/packages/53/14/7d1f2526b98b9658d7be0bb163fd78d681587de6709d8b0c74b4b481b013/grpcio-1.73.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:36bf93f6a657f37c131d9dd2c391b867abf1426a86727c3575393e9e11dadb0d", size = 10595587 }, - { url = "https://files.pythonhosted.org/packages/02/24/a293c398ae44e741da1ed4b29638edbb002258797b07a783f65506165b4c/grpcio-1.73.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:d84000367508ade791d90c2bafbd905574b5ced8056397027a77a215d601ba15", size = 5765793 }, - { url = "https://files.pythonhosted.org/packages/e1/24/d84dbd0b5bf36fb44922798d525a85cefa2ffee7b7110e61406e9750ed15/grpcio-1.73.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c98ba1d928a178ce33f3425ff823318040a2b7ef875d30a0073565e5ceb058d9", size = 6415494 }, - { url = "https://files.pythonhosted.org/packages/5e/85/c80dc65aed8e9dce3d54688864bac45331d9c7600985541f18bd5cb301d4/grpcio-1.73.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a73c72922dfd30b396a5f25bb3a4590195ee45ecde7ee068acb0892d2900cf07", size = 6007279 }, - { url = "https://files.pythonhosted.org/packages/37/fc/207c00a4c6fa303d26e2cbd62fbdb0582facdfd08f55500fd83bf6b0f8db/grpcio-1.73.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:10e8edc035724aba0346a432060fd192b42bd03675d083c01553cab071a28da5", size = 6105505 }, - { url = "https://files.pythonhosted.org/packages/72/35/8fe69af820667b87ebfcb24214e42a1d53da53cb39edd6b4f84f6b36da86/grpcio-1.73.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f5cdc332b503c33b1643b12ea933582c7b081957c8bc2ea4cc4bc58054a09288", size = 6753792 }, - { url = "https://files.pythonhosted.org/packages/e2/d8/738c77c1e821e350da4a048849f695ff88a02b291f8c69db23908867aea6/grpcio-1.73.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:07ad7c57233c2109e4ac999cb9c2710c3b8e3f491a73b058b0ce431f31ed8145", size = 6287593 }, - { url = "https://files.pythonhosted.org/packages/09/ec/8498eabc018fa39ae8efe5e47e3f4c1bc9ed6281056713871895dc998807/grpcio-1.73.0-cp313-cp313-win32.whl", hash = "sha256:0eb5df4f41ea10bda99a802b2a292d85be28958ede2a50f2beb8c7fc9a738419", size = 3668637 }, - { url = "https://files.pythonhosted.org/packages/d7/35/347db7d2e7674b621afd21b12022e7f48c7b0861b5577134b4e939536141/grpcio-1.73.0-cp313-cp313-win_amd64.whl", hash = "sha256:38cf518cc54cd0c47c9539cefa8888549fcc067db0b0c66a46535ca8032020c4", size = 4335872 }, +sdist = { url = "https://files.pythonhosted.org/packages/8e/7b/ca3f561aeecf0c846d15e1b38921a60dffffd5d4113931198fbf455334ee/grpcio-1.73.0.tar.gz", hash = "sha256:3af4c30918a7f0d39de500d11255f8d9da4f30e94a2033e70fe2a720e184bd8e", size = 12786424, upload-time = "2025-06-09T10:08:23.365Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/44/5ca479c880b9f56c9a9502873ea500c09d1087dc868217a90724c24d83d0/grpcio-1.73.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:d050197eeed50f858ef6c51ab09514856f957dba7b1f7812698260fc9cc417f6", size = 5365135, upload-time = "2025-06-09T10:02:44.243Z" }, + { url = "https://files.pythonhosted.org/packages/8d/b7/78ff355cdb602ab01ea437d316846847e0c1f7d109596e5409402cc13156/grpcio-1.73.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:ebb8d5f4b0200916fb292a964a4d41210de92aba9007e33d8551d85800ea16cb", size = 10609627, upload-time = "2025-06-09T10:02:46.678Z" }, + { url = "https://files.pythonhosted.org/packages/8d/92/5111235062b9da0e3010e5fd2bdceb766113fcf60520f9c23eb651089dd7/grpcio-1.73.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:c0811331b469e3f15dda5f90ab71bcd9681189a83944fd6dc908e2c9249041ef", size = 5803418, upload-time = "2025-06-09T10:02:49.047Z" }, + { url = "https://files.pythonhosted.org/packages/76/fa/dbf3fca0b91fa044f1114b11adc3d4ccc18ab1ac278daa69d450fd9aaef2/grpcio-1.73.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12787c791c3993d0ea1cc8bf90393647e9a586066b3b322949365d2772ba965b", size = 6444741, upload-time = "2025-06-09T10:02:51.763Z" }, + { url = "https://files.pythonhosted.org/packages/44/e1/e7c830c1a29abd13f0e7e861c8db57a67db5cb8a1edc6b9d9cd44c26a1e5/grpcio-1.73.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c17771e884fddf152f2a0df12478e8d02853e5b602a10a9a9f1f52fa02b1d32", size = 6040755, upload-time = "2025-06-09T10:02:54.379Z" }, + { url = "https://files.pythonhosted.org/packages/b4/57/2eaccbfdd8298ab6bb4504600a4283260983a9db7378eb79c922fd559883/grpcio-1.73.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:275e23d4c428c26b51857bbd95fcb8e528783597207ec592571e4372b300a29f", size = 6132216, upload-time = "2025-06-09T10:02:56.932Z" }, + { url = "https://files.pythonhosted.org/packages/81/a4/1bd2c59d7426ab640b121f42acb820ff7cd5c561d03e9c9164cb8431128e/grpcio-1.73.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9ffc972b530bf73ef0f948f799482a1bf12d9b6f33406a8e6387c0ca2098a833", size = 6774779, upload-time = "2025-06-09T10:02:59.683Z" }, + { url = "https://files.pythonhosted.org/packages/c6/64/70ee85055b4107acbe1af6a99ef6885e34db89083e53e5c27b8442e3aa38/grpcio-1.73.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d269df64aff092b2cec5e015d8ae09c7e90888b5c35c24fdca719a2c9f35", size = 6304223, upload-time = "2025-06-09T10:03:01.794Z" }, + { url = "https://files.pythonhosted.org/packages/06/02/4b3c373edccf29205205a6d329a267b9337ecbbf658bc70f0a18d63d0a50/grpcio-1.73.0-cp310-cp310-win32.whl", hash = "sha256:072d8154b8f74300ed362c01d54af8b93200c1a9077aeaea79828d48598514f1", size = 3679738, upload-time = "2025-06-09T10:03:03.675Z" }, + { url = "https://files.pythonhosted.org/packages/30/7a/d6dab939cda2129e39a872ad48f61c9951567dcda8ab419b8de446315a68/grpcio-1.73.0-cp310-cp310-win_amd64.whl", hash = "sha256:ce953d9d2100e1078a76a9dc2b7338d5415924dc59c69a15bf6e734db8a0f1ca", size = 4340441, upload-time = "2025-06-09T10:03:05.942Z" }, + { url = "https://files.pythonhosted.org/packages/dd/31/9de81fd12f7b27e6af403531b7249d76f743d58e0654e624b3df26a43ce2/grpcio-1.73.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:51036f641f171eebe5fa7aaca5abbd6150f0c338dab3a58f9111354240fe36ec", size = 5363773, upload-time = "2025-06-09T10:03:08.056Z" }, + { url = "https://files.pythonhosted.org/packages/32/9e/2cb78be357a7f1fc4942b81468ef3c7e5fd3df3ac010540459c10895a57b/grpcio-1.73.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:d12bbb88381ea00bdd92c55aff3da3391fd85bc902c41275c8447b86f036ce0f", size = 10621912, upload-time = "2025-06-09T10:03:10.489Z" }, + { url = "https://files.pythonhosted.org/packages/59/2f/b43954811a2e218a2761c0813800773ac0ca187b94fd2b8494e8ef232dc8/grpcio-1.73.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:483c507c2328ed0e01bc1adb13d1eada05cc737ec301d8e5a8f4a90f387f1790", size = 5807985, upload-time = "2025-06-09T10:03:13.775Z" }, + { url = "https://files.pythonhosted.org/packages/1b/bf/68e9f47e7ee349ffee712dcd907ee66826cf044f0dec7ab517421e56e857/grpcio-1.73.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c201a34aa960c962d0ce23fe5f423f97e9d4b518ad605eae6d0a82171809caaa", size = 6448218, upload-time = "2025-06-09T10:03:16.042Z" }, + { url = "https://files.pythonhosted.org/packages/af/dd/38ae43dd58480d609350cf1411fdac5c2ebb243e2c770f6f7aa3773d5e29/grpcio-1.73.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:859f70c8e435e8e1fa060e04297c6818ffc81ca9ebd4940e180490958229a45a", size = 6044343, upload-time = "2025-06-09T10:03:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/93/44/b6770b55071adb86481f36dae87d332fcad883b7f560bba9a940394ba018/grpcio-1.73.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e2459a27c6886e7e687e4e407778425f3c6a971fa17a16420227bda39574d64b", size = 6135858, upload-time = "2025-06-09T10:03:21.059Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9f/63de49fcef436932fcf0ffb978101a95c83c177058dbfb56dbf30ab81659/grpcio-1.73.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e0084d4559ee3dbdcce9395e1bc90fdd0262529b32c417a39ecbc18da8074ac7", size = 6775806, upload-time = "2025-06-09T10:03:23.876Z" }, + { url = "https://files.pythonhosted.org/packages/4d/67/c11f1953469162e958f09690ec3a9be3fdb29dea7f5661362a664f9d609a/grpcio-1.73.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef5fff73d5f724755693a464d444ee0a448c6cdfd3c1616a9223f736c622617d", size = 6308413, upload-time = "2025-06-09T10:03:26.033Z" }, + { url = "https://files.pythonhosted.org/packages/ba/6a/9dd04426337db07f28bd51a986b7a038ba56912c81b5bb1083c17dd63404/grpcio-1.73.0-cp311-cp311-win32.whl", hash = "sha256:965a16b71a8eeef91fc4df1dc40dc39c344887249174053814f8a8e18449c4c3", size = 3678972, upload-time = "2025-06-09T10:03:28.433Z" }, + { url = "https://files.pythonhosted.org/packages/04/8b/8c0a8a4fdc2e7977d325eafc587c9cf468039693ac23ad707153231d3cb2/grpcio-1.73.0-cp311-cp311-win_amd64.whl", hash = "sha256:b71a7b4483d1f753bbc11089ff0f6fa63b49c97a9cc20552cded3fcad466d23b", size = 4342967, upload-time = "2025-06-09T10:03:31.215Z" }, + { url = "https://files.pythonhosted.org/packages/9d/4d/e938f3a0e51a47f2ce7e55f12f19f316e7074770d56a7c2765e782ec76bc/grpcio-1.73.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:fb9d7c27089d9ba3746f18d2109eb530ef2a37452d2ff50f5a6696cd39167d3b", size = 5334911, upload-time = "2025-06-09T10:03:33.494Z" }, + { url = "https://files.pythonhosted.org/packages/13/56/f09c72c43aa8d6f15a71f2c63ebdfac9cf9314363dea2598dc501d8370db/grpcio-1.73.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:128ba2ebdac41e41554d492b82c34586a90ebd0766f8ebd72160c0e3a57b9155", size = 10601460, upload-time = "2025-06-09T10:03:36.613Z" }, + { url = "https://files.pythonhosted.org/packages/20/e3/85496edc81e41b3c44ebefffc7bce133bb531120066877df0f910eabfa19/grpcio-1.73.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:068ecc415f79408d57a7f146f54cdf9f0acb4b301a52a9e563973dc981e82f3d", size = 5759191, upload-time = "2025-06-09T10:03:39.838Z" }, + { url = "https://files.pythonhosted.org/packages/88/cc/fef74270a6d29f35ad744bfd8e6c05183f35074ff34c655a2c80f3b422b2/grpcio-1.73.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ddc1cfb2240f84d35d559ade18f69dcd4257dbaa5ba0de1a565d903aaab2968", size = 6409961, upload-time = "2025-06-09T10:03:42.706Z" }, + { url = "https://files.pythonhosted.org/packages/b0/e6/13cfea15e3b8f79c4ae7b676cb21fab70978b0fde1e1d28bb0e073291290/grpcio-1.73.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e53007f70d9783f53b41b4cf38ed39a8e348011437e4c287eee7dd1d39d54b2f", size = 6003948, upload-time = "2025-06-09T10:03:44.96Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ed/b1a36dad4cc0dbf1f83f6d7b58825fefd5cc9ff3a5036e46091335649473/grpcio-1.73.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4dd8d8d092efede7d6f48d695ba2592046acd04ccf421436dd7ed52677a9ad29", size = 6103788, upload-time = "2025-06-09T10:03:48.053Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c8/d381433d3d46d10f6858126d2d2245ef329e30f3752ce4514c93b95ca6fc/grpcio-1.73.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:70176093d0a95b44d24baa9c034bb67bfe2b6b5f7ebc2836f4093c97010e17fd", size = 6749508, upload-time = "2025-06-09T10:03:51.185Z" }, + { url = "https://files.pythonhosted.org/packages/87/0a/ff0c31dbd15e63b34320efafac647270aa88c31aa19ff01154a73dc7ce86/grpcio-1.73.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:085ebe876373ca095e24ced95c8f440495ed0b574c491f7f4f714ff794bbcd10", size = 6284342, upload-time = "2025-06-09T10:03:54.467Z" }, + { url = "https://files.pythonhosted.org/packages/fd/73/f762430c0ba867403b9d6e463afe026bf019bd9206eee753785239719273/grpcio-1.73.0-cp312-cp312-win32.whl", hash = "sha256:cfc556c1d6aef02c727ec7d0016827a73bfe67193e47c546f7cadd3ee6bf1a60", size = 3669319, upload-time = "2025-06-09T10:03:56.751Z" }, + { url = "https://files.pythonhosted.org/packages/10/8b/3411609376b2830449cf416f457ad9d2aacb7f562e1b90fdd8bdedf26d63/grpcio-1.73.0-cp312-cp312-win_amd64.whl", hash = "sha256:bbf45d59d090bf69f1e4e1594832aaf40aa84b31659af3c5e2c3f6a35202791a", size = 4335596, upload-time = "2025-06-09T10:03:59.866Z" }, + { url = "https://files.pythonhosted.org/packages/60/da/6f3f7a78e5455c4cbe87c85063cc6da05d65d25264f9d4aed800ece46294/grpcio-1.73.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:da1d677018ef423202aca6d73a8d3b2cb245699eb7f50eb5f74cae15a8e1f724", size = 5335867, upload-time = "2025-06-09T10:04:03.153Z" }, + { url = "https://files.pythonhosted.org/packages/53/14/7d1f2526b98b9658d7be0bb163fd78d681587de6709d8b0c74b4b481b013/grpcio-1.73.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:36bf93f6a657f37c131d9dd2c391b867abf1426a86727c3575393e9e11dadb0d", size = 10595587, upload-time = "2025-06-09T10:04:05.694Z" }, + { url = "https://files.pythonhosted.org/packages/02/24/a293c398ae44e741da1ed4b29638edbb002258797b07a783f65506165b4c/grpcio-1.73.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:d84000367508ade791d90c2bafbd905574b5ced8056397027a77a215d601ba15", size = 5765793, upload-time = "2025-06-09T10:04:09.235Z" }, + { url = "https://files.pythonhosted.org/packages/e1/24/d84dbd0b5bf36fb44922798d525a85cefa2ffee7b7110e61406e9750ed15/grpcio-1.73.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c98ba1d928a178ce33f3425ff823318040a2b7ef875d30a0073565e5ceb058d9", size = 6415494, upload-time = "2025-06-09T10:04:12.377Z" }, + { url = "https://files.pythonhosted.org/packages/5e/85/c80dc65aed8e9dce3d54688864bac45331d9c7600985541f18bd5cb301d4/grpcio-1.73.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a73c72922dfd30b396a5f25bb3a4590195ee45ecde7ee068acb0892d2900cf07", size = 6007279, upload-time = "2025-06-09T10:04:14.878Z" }, + { url = "https://files.pythonhosted.org/packages/37/fc/207c00a4c6fa303d26e2cbd62fbdb0582facdfd08f55500fd83bf6b0f8db/grpcio-1.73.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:10e8edc035724aba0346a432060fd192b42bd03675d083c01553cab071a28da5", size = 6105505, upload-time = "2025-06-09T10:04:17.39Z" }, + { url = "https://files.pythonhosted.org/packages/72/35/8fe69af820667b87ebfcb24214e42a1d53da53cb39edd6b4f84f6b36da86/grpcio-1.73.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f5cdc332b503c33b1643b12ea933582c7b081957c8bc2ea4cc4bc58054a09288", size = 6753792, upload-time = "2025-06-09T10:04:19.989Z" }, + { url = "https://files.pythonhosted.org/packages/e2/d8/738c77c1e821e350da4a048849f695ff88a02b291f8c69db23908867aea6/grpcio-1.73.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:07ad7c57233c2109e4ac999cb9c2710c3b8e3f491a73b058b0ce431f31ed8145", size = 6287593, upload-time = "2025-06-09T10:04:22.878Z" }, + { url = "https://files.pythonhosted.org/packages/09/ec/8498eabc018fa39ae8efe5e47e3f4c1bc9ed6281056713871895dc998807/grpcio-1.73.0-cp313-cp313-win32.whl", hash = "sha256:0eb5df4f41ea10bda99a802b2a292d85be28958ede2a50f2beb8c7fc9a738419", size = 3668637, upload-time = "2025-06-09T10:04:25.787Z" }, + { url = "https://files.pythonhosted.org/packages/d7/35/347db7d2e7674b621afd21b12022e7f48c7b0861b5577134b4e939536141/grpcio-1.73.0-cp313-cp313-win_amd64.whl", hash = "sha256:38cf518cc54cd0c47c9539cefa8888549fcc067db0b0c66a46535ca8032020c4", size = 4335872, upload-time = "2025-06-09T10:04:29.032Z" }, ] [[package]] @@ -1381,33 +1381,107 @@ dependencies = [ { name = "grpcio" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fd/d1/b6e9877fedae3add1afdeae1f89d1927d296da9cf977eca0eb08fb8a460e/grpcio_status-1.71.2.tar.gz", hash = "sha256:c7a97e176df71cdc2c179cd1847d7fc86cca5832ad12e9798d7fed6b7a1aab50", size = 13677 } +sdist = { url = "https://files.pythonhosted.org/packages/fd/d1/b6e9877fedae3add1afdeae1f89d1927d296da9cf977eca0eb08fb8a460e/grpcio_status-1.71.2.tar.gz", hash = "sha256:c7a97e176df71cdc2c179cd1847d7fc86cca5832ad12e9798d7fed6b7a1aab50", size = 13677, upload-time = "2025-06-28T04:24:05.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/67/58/317b0134129b556a93a3b0afe00ee675b5657f0155509e22fcb853bafe2d/grpcio_status-1.71.2-py3-none-any.whl", hash = "sha256:803c98cb6a8b7dc6dbb785b1111aed739f241ab5e9da0bba96888aa74704cfd3", size = 14424 }, + { url = "https://files.pythonhosted.org/packages/67/58/317b0134129b556a93a3b0afe00ee675b5657f0155509e22fcb853bafe2d/grpcio_status-1.71.2-py3-none-any.whl", hash = "sha256:803c98cb6a8b7dc6dbb785b1111aed739f241ab5e9da0bba96888aa74704cfd3", size = 14424, upload-time = "2025-06-28T04:23:42.136Z" }, ] [[package]] name = "h11" version = "0.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] [[package]] name = "hf-xet" version = "1.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/be/58f20728a5b445f8b064e74f0618897b3439f5ef90934da1916b9dfac76f/hf_xet-1.1.2.tar.gz", hash = "sha256:3712d6d4819d3976a1c18e36db9f503e296283f9363af818f50703506ed63da3", size = 467009 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/45/ae/f1a63f75d9886f18a80220ba31a1c7b9c4752f03aae452f358f538c6a991/hf_xet-1.1.2-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:dfd1873fd648488c70735cb60f7728512bca0e459e61fcd107069143cd798469", size = 2642559 }, - { url = "https://files.pythonhosted.org/packages/50/ab/d2c83ae18f1015d926defd5bfbe94c62d15e93f900e6a192e318ee947105/hf_xet-1.1.2-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:29b584983b2d977c44157d9241dcf0fd50acde0b7bff8897fe4386912330090d", size = 2541360 }, - { url = "https://files.pythonhosted.org/packages/9f/a7/693dc9f34f979e30a378125e2150a0b2d8d166e6d83ce3950eeb81e560aa/hf_xet-1.1.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b29ac84298147fe9164cc55ad994ba47399f90b5d045b0b803b99cf5f06d8ec", size = 5183081 }, - { url = "https://files.pythonhosted.org/packages/3d/23/c48607883f692a36c0a7735f47f98bad32dbe459a32d1568c0f21576985d/hf_xet-1.1.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d921ba32615676e436a0d15e162331abc9ed43d440916b1d836dc27ce1546173", size = 5356100 }, - { url = "https://files.pythonhosted.org/packages/eb/5b/b2316c7f1076da0582b52ea228f68bea95e243c388440d1dc80297c9d813/hf_xet-1.1.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d9b03c34e13c44893ab6e8fea18ee8d2a6878c15328dd3aabedbdd83ee9f2ed3", size = 5647688 }, - { url = "https://files.pythonhosted.org/packages/2c/98/e6995f0fa579929da7795c961f403f4ee84af36c625963f52741d56f242c/hf_xet-1.1.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:01b18608955b3d826307d37da8bd38b28a46cd2d9908b3a3655d1363274f941a", size = 5322627 }, - { url = "https://files.pythonhosted.org/packages/59/40/8f1d5a44a64d8bf9e3c19576e789f716af54875b46daae65426714e75db1/hf_xet-1.1.2-cp37-abi3-win_amd64.whl", hash = "sha256:3562902c81299b09f3582ddfb324400c6a901a2f3bc854f83556495755f4954c", size = 2739542 }, +sdist = { url = "https://files.pythonhosted.org/packages/95/be/58f20728a5b445f8b064e74f0618897b3439f5ef90934da1916b9dfac76f/hf_xet-1.1.2.tar.gz", hash = "sha256:3712d6d4819d3976a1c18e36db9f503e296283f9363af818f50703506ed63da3", size = 467009, upload-time = "2025-05-16T20:44:34.944Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/ae/f1a63f75d9886f18a80220ba31a1c7b9c4752f03aae452f358f538c6a991/hf_xet-1.1.2-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:dfd1873fd648488c70735cb60f7728512bca0e459e61fcd107069143cd798469", size = 2642559, upload-time = "2025-05-16T20:44:30.217Z" }, + { url = "https://files.pythonhosted.org/packages/50/ab/d2c83ae18f1015d926defd5bfbe94c62d15e93f900e6a192e318ee947105/hf_xet-1.1.2-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:29b584983b2d977c44157d9241dcf0fd50acde0b7bff8897fe4386912330090d", size = 2541360, upload-time = "2025-05-16T20:44:29.056Z" }, + { url = "https://files.pythonhosted.org/packages/9f/a7/693dc9f34f979e30a378125e2150a0b2d8d166e6d83ce3950eeb81e560aa/hf_xet-1.1.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b29ac84298147fe9164cc55ad994ba47399f90b5d045b0b803b99cf5f06d8ec", size = 5183081, upload-time = "2025-05-16T20:44:27.505Z" }, + { url = "https://files.pythonhosted.org/packages/3d/23/c48607883f692a36c0a7735f47f98bad32dbe459a32d1568c0f21576985d/hf_xet-1.1.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d921ba32615676e436a0d15e162331abc9ed43d440916b1d836dc27ce1546173", size = 5356100, upload-time = "2025-05-16T20:44:25.681Z" }, + { url = "https://files.pythonhosted.org/packages/eb/5b/b2316c7f1076da0582b52ea228f68bea95e243c388440d1dc80297c9d813/hf_xet-1.1.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d9b03c34e13c44893ab6e8fea18ee8d2a6878c15328dd3aabedbdd83ee9f2ed3", size = 5647688, upload-time = "2025-05-16T20:44:31.867Z" }, + { url = "https://files.pythonhosted.org/packages/2c/98/e6995f0fa579929da7795c961f403f4ee84af36c625963f52741d56f242c/hf_xet-1.1.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:01b18608955b3d826307d37da8bd38b28a46cd2d9908b3a3655d1363274f941a", size = 5322627, upload-time = "2025-05-16T20:44:33.677Z" }, + { url = "https://files.pythonhosted.org/packages/59/40/8f1d5a44a64d8bf9e3c19576e789f716af54875b46daae65426714e75db1/hf_xet-1.1.2-cp37-abi3-win_amd64.whl", hash = "sha256:3562902c81299b09f3582ddfb324400c6a901a2f3bc854f83556495755f4954c", size = 2739542, upload-time = "2025-05-16T20:44:36.287Z" }, +] + +[[package]] +name = "hiredis" +version = "3.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/08/24b72f425b75e1de7442fb1740f69ca66d5820b9f9c0e2511ff9aadab3b7/hiredis-3.2.1.tar.gz", hash = "sha256:5a5f64479bf04dd829fe7029fad0ea043eac4023abc6e946668cbbec3493a78d", size = 89096, upload-time = "2025-05-23T11:41:57.227Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/12/e797b676d65b86d9ad56f434cb4548b1bd0ebf531cd2e36ef74c5cd46dcd/hiredis-3.2.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:add17efcbae46c5a6a13b244ff0b4a8fa079602ceb62290095c941b42e9d5dec", size = 82441, upload-time = "2025-05-23T11:39:36.142Z" }, + { url = "https://files.pythonhosted.org/packages/d3/04/45783d5cf6e7430b1c67d64a7919ee45381e8b98d6d4578516579c5a4420/hiredis-3.2.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:5fe955cc4f66c57df1ae8e5caf4de2925d43b5efab4e40859662311d1bcc5f54", size = 45235, upload-time = "2025-05-23T11:39:37.49Z" }, + { url = "https://files.pythonhosted.org/packages/d5/97/7f50bad0b8213a3ee7780e295cd3d5e3db2839de2a6342b3c0ceeaf8e0af/hiredis-3.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f9ad63cd9065820a43fb1efb8ed5ae85bb78f03ef5eb53f6bde47914708f5718", size = 43250, upload-time = "2025-05-23T11:39:38.518Z" }, + { url = "https://files.pythonhosted.org/packages/51/d0/38d4b5bf36bfd010fdfd460c53efc0aaef7c81d6c20f4041ca35e26a1e12/hiredis-3.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e7f9e5fdba08841d78d4e1450cae03a4dbed2eda8a4084673cafa5615ce24a", size = 168996, upload-time = "2025-05-23T11:39:39.563Z" }, + { url = "https://files.pythonhosted.org/packages/99/22/4e2e9fde2b2efcf9847a2442a21f404c4112c57cccd6a09e564524dd70f3/hiredis-3.2.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1dce2508eca5d4e47ef38bc7c0724cb45abcdb0089f95a2ef49baf52882979a8", size = 165508, upload-time = "2025-05-23T11:39:40.723Z" }, + { url = "https://files.pythonhosted.org/packages/98/d0/b05bc8d4f339abaa455a9e677fc5223e25cd97630e66a2da0ad25e67b131/hiredis-3.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:186428bf353e4819abae15aa2ad64c3f40499d596ede280fe328abb9e98e72ce", size = 180109, upload-time = "2025-05-23T11:39:41.865Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ca/6df2cf488792ace30ee525a5444e12f432cc1da4acb47756ea5de265ea80/hiredis-3.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74f2500d90a0494843aba7abcdc3e77f859c502e0892112d708c02e1dcae8f90", size = 169161, upload-time = "2025-05-23T11:39:43.432Z" }, + { url = "https://files.pythonhosted.org/packages/15/8b/afcef7a30bf5b94936264edb7daaf12a165f2b57007e384a57ac48411886/hiredis-3.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32822a94d2fdd1da96c05b22fdeef6d145d8fdbd865ba2f273f45eb949e4a805", size = 169485, upload-time = "2025-05-23T11:39:45.008Z" }, + { url = "https://files.pythonhosted.org/packages/43/14/3443dee27bd20f2ac88a759b67b29e7f3756a9a38bbe8084de049dfc5cac/hiredis-3.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ead809fb08dd4fdb5b4b6e2999c834e78c3b0c450a07c3ed88983964432d0c64", size = 163644, upload-time = "2025-05-23T11:39:46.755Z" }, + { url = "https://files.pythonhosted.org/packages/3f/24/8a3cee0f08071af0a9632ca81a057fe2b638e7b6956c9b5704a2049c1305/hiredis-3.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b90fada20301c3a257e868dd6a4694febc089b2b6d893fa96a3fc6c1f9ab4340", size = 162180, upload-time = "2025-05-23T11:39:47.939Z" }, + { url = "https://files.pythonhosted.org/packages/bd/2c/34cb6e665535dce1cbb7077cb9cc608198f254050241b5e232d62393f6a7/hiredis-3.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6d8bff53f526da3d9db86c8668011e4f7ca2958ee3a46c648edab6fe2cd1e709", size = 174369, upload-time = "2025-05-23T11:39:49.13Z" }, + { url = "https://files.pythonhosted.org/packages/f8/24/96702f71991d884412d7ac89577ad9caa28875e2e309f53751b8c5f969be/hiredis-3.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:043d929ae262d03e1db0f08616e14504a9119c1ff3de13d66f857d85cd45caff", size = 166511, upload-time = "2025-05-23T11:39:50.232Z" }, + { url = "https://files.pythonhosted.org/packages/de/d0/8d3753244bdea37ab1700db8eec220df8361d0e3f72b9b5314ce4a0471ac/hiredis-3.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8d470fef39d02dbe5c541ec345cc4ffd7d2baec7d6e59c92bd9d9545dc221829", size = 164329, upload-time = "2025-05-23T11:39:51.365Z" }, + { url = "https://files.pythonhosted.org/packages/44/2e/28b5fffd2872e51182aec94992ff34641b6aab00c135e21da1d2f6c8c99b/hiredis-3.2.1-cp310-cp310-win32.whl", hash = "sha256:efa4c76c45cc8c42228c7989b279fa974580e053b5e6a4a834098b5324b9eafa", size = 20401, upload-time = "2025-05-23T11:39:52.4Z" }, + { url = "https://files.pythonhosted.org/packages/62/14/cbad8202ca7996686d51a779a552fb9d16a59c4fe60b68b076907a8a44f0/hiredis-3.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:cbac5ec3a620b095c46ef3a8f1f06da9c86c1cdc411d44a5f538876c39a2b321", size = 22076, upload-time = "2025-05-23T11:39:53.229Z" }, + { url = "https://files.pythonhosted.org/packages/48/84/2ea9636f2ba0811d9eb3bebbbfa84f488238180ddab70c9cb7fa13419d78/hiredis-3.2.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:e4ae0be44cab5e74e6e4c4a93d04784629a45e781ff483b136cc9e1b9c23975c", size = 82425, upload-time = "2025-05-23T11:39:54.135Z" }, + { url = "https://files.pythonhosted.org/packages/fc/24/b9ebf766a99998fda3975937afa4912e98de9d7f8d0b83f48096bdd961c1/hiredis-3.2.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:24647e84c9f552934eb60b7f3d2116f8b64a7020361da9369e558935ca45914d", size = 45231, upload-time = "2025-05-23T11:39:55.455Z" }, + { url = "https://files.pythonhosted.org/packages/68/4c/c009b4d9abeb964d607f0987561892d1589907f770b9e5617552b34a4a4d/hiredis-3.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6fb3e92d1172da8decc5f836bf8b528c0fc9b6d449f1353e79ceeb9dc1801132", size = 43240, upload-time = "2025-05-23T11:39:57.8Z" }, + { url = "https://files.pythonhosted.org/packages/e9/83/d53f3ae9e4ac51b8a35afb7ccd68db871396ed1d7c8ba02ce2c30de0cf17/hiredis-3.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38ba7a32e51e518b6b3e470142e52ed2674558e04d7d73d86eb19ebcb37d7d40", size = 169624, upload-time = "2025-05-23T11:40:00.055Z" }, + { url = "https://files.pythonhosted.org/packages/91/2f/f9f091526e22a45385d45f3870204dc78aee365b6fe32e679e65674da6a7/hiredis-3.2.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4fc632be73174891d6bb71480247e57b2fd8f572059f0a1153e4d0339e919779", size = 165799, upload-time = "2025-05-23T11:40:01.194Z" }, + { url = "https://files.pythonhosted.org/packages/1c/cc/e561274438cdb19794f0638136a5a99a9ca19affcb42679b12a78016b8ad/hiredis-3.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f03e6839ff21379ad3c195e0700fc9c209e7f344946dea0f8a6d7b5137a2a141", size = 180612, upload-time = "2025-05-23T11:40:02.385Z" }, + { url = "https://files.pythonhosted.org/packages/83/ba/a8a989f465191d55672e57aea2a331bfa3a74b5cbc6f590031c9e11f7491/hiredis-3.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99983873e37c71bb71deb544670ff4f9d6920dab272aaf52365606d87a4d6c73", size = 169934, upload-time = "2025-05-23T11:40:03.524Z" }, + { url = "https://files.pythonhosted.org/packages/52/5f/1148e965df1c67b17bdcaef199f54aec3def0955d19660a39c6ee10a6f55/hiredis-3.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffd982c419f48e3a57f592678c72474429465bb4bfc96472ec805f5d836523f0", size = 170074, upload-time = "2025-05-23T11:40:04.618Z" }, + { url = "https://files.pythonhosted.org/packages/43/5e/e6846ad159a938b539fb8d472e2e68cb6758d7c9454ea0520211f335ea72/hiredis-3.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bc993f4aa4abc029347f309e722f122e05a3b8a0c279ae612849b5cc9dc69f2d", size = 164158, upload-time = "2025-05-23T11:40:05.653Z" }, + { url = "https://files.pythonhosted.org/packages/0a/a1/5891e0615f0993f194c1b51a65aaac063b0db318a70df001b28e49f0579d/hiredis-3.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dde790d420081f18b5949227649ccb3ed991459df33279419a25fcae7f97cd92", size = 162591, upload-time = "2025-05-23T11:40:07.041Z" }, + { url = "https://files.pythonhosted.org/packages/d4/da/8bce52ca81716f53c1014f689aea4c170ba6411e6848f81a1bed1fc375eb/hiredis-3.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b0c8cae7edbef860afcf3177b705aef43e10b5628f14d5baf0ec69668247d08d", size = 174808, upload-time = "2025-05-23T11:40:09.146Z" }, + { url = "https://files.pythonhosted.org/packages/84/91/fc1ef444ed4dc432b5da9b48e9bd23266c703528db7be19e2b608d67ba06/hiredis-3.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e8a90eaca7e1ce7f175584f07a2cdbbcab13f4863f9f355d7895c4d28805f65b", size = 167060, upload-time = "2025-05-23T11:40:10.757Z" }, + { url = "https://files.pythonhosted.org/packages/66/ad/beebf73a5455f232b97e00564d1e8ad095d4c6e18858c60c6cfdd893ac1e/hiredis-3.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:476031958fa44e245e803827e0787d49740daa4de708fe514370293ce519893a", size = 164833, upload-time = "2025-05-23T11:40:12.001Z" }, + { url = "https://files.pythonhosted.org/packages/75/79/a9591bdc0148c0fbdf54cf6f3d449932d3b3b8779e87f33fa100a5a8088f/hiredis-3.2.1-cp311-cp311-win32.whl", hash = "sha256:eb3f5df2a9593b4b4b676dce3cea53b9c6969fc372875188589ddf2bafc7f624", size = 20402, upload-time = "2025-05-23T11:40:13.216Z" }, + { url = "https://files.pythonhosted.org/packages/9f/05/c93cc6fab31e3c01b671126c82f44372fb211facb8bd4571fd372f50898d/hiredis-3.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:1402e763d8a9fdfcc103bbf8b2913971c0a3f7b8a73deacbda3dfe5f3a9d1e0b", size = 22085, upload-time = "2025-05-23T11:40:14.19Z" }, + { url = "https://files.pythonhosted.org/packages/60/a1/6da1578a22df1926497f7a3f6a3d2408fe1d1559f762c1640af5762a8eb6/hiredis-3.2.1-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:3742d8b17e73c198cabeab11da35f2e2a81999d406f52c6275234592256bf8e8", size = 82627, upload-time = "2025-05-23T11:40:15.362Z" }, + { url = "https://files.pythonhosted.org/packages/6c/b1/1056558ca8dc330be5bb25162fe5f268fee71571c9a535153df9f871a073/hiredis-3.2.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9c2f3176fb617a79f6cccf22cb7d2715e590acb534af6a82b41f8196ad59375d", size = 45404, upload-time = "2025-05-23T11:40:16.72Z" }, + { url = "https://files.pythonhosted.org/packages/58/4f/13d1fa1a6b02a99e9fed8f546396f2d598c3613c98e6c399a3284fa65361/hiredis-3.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a8bd46189c7fa46174e02670dc44dfecb60f5bd4b67ed88cb050d8f1fd842f09", size = 43299, upload-time = "2025-05-23T11:40:17.697Z" }, + { url = "https://files.pythonhosted.org/packages/c0/25/ddfac123ba5a32eb1f0b40ba1b2ec98a599287f7439def8856c3c7e5dd0d/hiredis-3.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f86ee4488c8575b58139cdfdddeae17f91e9a893ffee20260822add443592e2f", size = 172194, upload-time = "2025-05-23T11:40:19.143Z" }, + { url = "https://files.pythonhosted.org/packages/2c/1e/443a3703ce570b631ca43494094fbaeb051578a0ebe4bfcefde351e1ba25/hiredis-3.2.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3717832f4a557b2fe7060b9d4a7900e5de287a15595e398c3f04df69019ca69d", size = 168429, upload-time = "2025-05-23T11:40:20.329Z" }, + { url = "https://files.pythonhosted.org/packages/3b/d6/0d8c6c706ed79b2298c001b5458c055615e3166533dcee3900e821a18a3e/hiredis-3.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5cb12c21fb9e2403d28c4e6a38120164973342d34d08120f2d7009b66785644", size = 182967, upload-time = "2025-05-23T11:40:21.921Z" }, + { url = "https://files.pythonhosted.org/packages/da/68/da8dd231fbce858b5a20ab7d7bf558912cd125f08bac4c778865ef5fe2c2/hiredis-3.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:080fda1510bbd389af91f919c11a4f2aa4d92f0684afa4709236faa084a42cac", size = 172495, upload-time = "2025-05-23T11:40:23.105Z" }, + { url = "https://files.pythonhosted.org/packages/65/25/83a31420535e2778662caa95533d5c997011fa6a88331f0cdb22afea9ec3/hiredis-3.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1252e10a1f3273d1c6bf2021e461652c2e11b05b83e0915d6eb540ec7539afe2", size = 173142, upload-time = "2025-05-23T11:40:24.24Z" }, + { url = "https://files.pythonhosted.org/packages/41/d7/cb907348889eb75e2aa2e6b63e065b611459e0f21fe1e371a968e13f0d55/hiredis-3.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d9e320e99ab7d2a30dc91ff6f745ba38d39b23f43d345cdee9881329d7b511d6", size = 166433, upload-time = "2025-05-23T11:40:25.287Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/7cbc69d82af7b29a95723d50f5261555ba3d024bfbdc414bdc3d23c0defb/hiredis-3.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:641668f385f16550fdd6fdc109b0af6988b94ba2acc06770a5e06a16e88f320c", size = 164883, upload-time = "2025-05-23T11:40:26.454Z" }, + { url = "https://files.pythonhosted.org/packages/f9/00/f995b1296b1d7e0247651347aa230f3225a9800e504fdf553cf7cd001cf7/hiredis-3.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1e1f44208c39d6c345ff451f82f21e9eeda6fe9af4ac65972cc3eeb58d41f7cb", size = 177262, upload-time = "2025-05-23T11:40:27.576Z" }, + { url = "https://files.pythonhosted.org/packages/c5/f3/723a67d729e94764ce9e0d73fa5f72a0f87d3ce3c98c9a0b27cbf001cc79/hiredis-3.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f882a0d6415fffe1ffcb09e6281d0ba8b1ece470e866612bbb24425bf76cf397", size = 169619, upload-time = "2025-05-23T11:40:29.671Z" }, + { url = "https://files.pythonhosted.org/packages/45/58/f69028df00fb1b223e221403f3be2059ae86031e7885f955d26236bdfc17/hiredis-3.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b4e78719a0730ebffe335528531d154bc8867a246418f74ecd88adbc4d938c49", size = 167303, upload-time = "2025-05-23T11:40:30.902Z" }, + { url = "https://files.pythonhosted.org/packages/2b/7d/567411e65cce76cf265a9a4f837fd2ebc564bef6368dd42ac03f7a517c0a/hiredis-3.2.1-cp312-cp312-win32.whl", hash = "sha256:33c4604d9f79a13b84da79950a8255433fca7edaf292bbd3364fd620864ed7b2", size = 20551, upload-time = "2025-05-23T11:40:32.69Z" }, + { url = "https://files.pythonhosted.org/packages/90/74/b4c291eb4a4a874b3690ff9fc311a65d5292072556421b11b1d786e3e1d0/hiredis-3.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7b9749375bf9d171aab8813694f379f2cff0330d7424000f5e92890ad4932dc9", size = 22128, upload-time = "2025-05-23T11:40:33.686Z" }, + { url = "https://files.pythonhosted.org/packages/47/91/c07e737288e891c974277b9fa090f0a43c72ab6ccb5182117588f1c01269/hiredis-3.2.1-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:7cabf7f1f06be221e1cbed1f34f00891a7bdfad05b23e4d315007dd42148f3d4", size = 82636, upload-time = "2025-05-23T11:40:35.035Z" }, + { url = "https://files.pythonhosted.org/packages/92/20/02cb1820360eda419bc17eb835eca976079e2b3e48aecc5de0666b79a54c/hiredis-3.2.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:db85cb86f8114c314d0ec6d8de25b060a2590b4713135240d568da4f7dea97ac", size = 45404, upload-time = "2025-05-23T11:40:36.113Z" }, + { url = "https://files.pythonhosted.org/packages/87/51/d30a4aadab8670ed9d40df4982bc06c891ee1da5cdd88d16a74e1ecbd520/hiredis-3.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c9a592a49b7b8497e4e62c3ff40700d0c7f1a42d145b71e3e23c385df573c964", size = 43301, upload-time = "2025-05-23T11:40:37.557Z" }, + { url = "https://files.pythonhosted.org/packages/f7/7b/2c613e1bb5c2e2bac36e8befeefdd58b42816befb17e26ab600adfe337fb/hiredis-3.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0079ef1e03930b364556b78548e67236ab3def4e07e674f6adfc52944aa972dd", size = 172486, upload-time = "2025-05-23T11:40:38.659Z" }, + { url = "https://files.pythonhosted.org/packages/1e/df/8f2c4fcc28d6f5178b25ee1ba2157cc473f9908c16ce4b8e0bdd79e38b05/hiredis-3.2.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d6a290ed45d9c14f4c50b6bda07afb60f270c69b5cb626fd23a4c2fde9e3da1", size = 168532, upload-time = "2025-05-23T11:40:39.843Z" }, + { url = "https://files.pythonhosted.org/packages/88/ae/d0864ffaa0461e29a6940a11c858daf78c99476c06ed531b41ad2255ec25/hiredis-3.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79dd5fe8c0892769f82949adeb021342ca46871af26e26945eb55d044fcdf0d0", size = 183216, upload-time = "2025-05-23T11:40:41.005Z" }, + { url = "https://files.pythonhosted.org/packages/75/17/558e831b77692d73f5bcf8b493ab3eace9f11b0aa08839cdbb87995152c7/hiredis-3.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:998a82281a159f4aebbfd4fb45cfe24eb111145206df2951d95bc75327983b58", size = 172689, upload-time = "2025-05-23T11:40:42.153Z" }, + { url = "https://files.pythonhosted.org/packages/35/b9/4fccda21f930f08c5072ad51e825d85d457748138443d7b510afe77b8264/hiredis-3.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41fc3cd52368ffe7c8e489fb83af5e99f86008ed7f9d9ba33b35fec54f215c0a", size = 173319, upload-time = "2025-05-23T11:40:43.328Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8b/596d613588b0a3c58dfcf9a17edc6a886c4de6a3096e27c7142a94e2304d/hiredis-3.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8d10df3575ce09b0fa54b8582f57039dcbdafde5de698923a33f601d2e2a246c", size = 166695, upload-time = "2025-05-23T11:40:44.453Z" }, + { url = "https://files.pythonhosted.org/packages/e7/5b/6a1c266e9f6627a8be1fa0d8622e35e35c76ae40cce6d1c78a7e6021184a/hiredis-3.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1ab010d04be33735ad8e643a40af0d68a21d70a57b1d0bff9b6a66b28cca9dbf", size = 165181, upload-time = "2025-05-23T11:40:45.697Z" }, + { url = "https://files.pythonhosted.org/packages/6c/70/a9b91fa70d21763d9dfd1c27ddd378f130749a0ae4a0645552f754b3d1fc/hiredis-3.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ec3b5f9ea34f70aaba3e061cbe1fa3556fea401d41f5af321b13e326792f3017", size = 177589, upload-time = "2025-05-23T11:40:46.903Z" }, + { url = "https://files.pythonhosted.org/packages/1a/c7/31bbb015156dc4441f6e19daa9598266a61445bf3f6e14c44292764638f6/hiredis-3.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:158dfb505fff6bffd17f823a56effc0c2a7a8bc4fb659d79a52782f22eefc697", size = 169883, upload-time = "2025-05-23T11:40:48.111Z" }, + { url = "https://files.pythonhosted.org/packages/89/44/cddc23379e0ce20ad7514b2adb2aa2c9b470ffb1ca0a2d8c020748962a22/hiredis-3.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d632cd0ddd7895081be76748e6fb9286f81d2a51c371b516541c6324f2fdac9", size = 167585, upload-time = "2025-05-23T11:40:49.208Z" }, + { url = "https://files.pythonhosted.org/packages/48/92/8fc9b981ed01fc2bbac463a203455cd493482b749801bb555ebac72923f1/hiredis-3.2.1-cp313-cp313-win32.whl", hash = "sha256:e9726d03e7df068bf755f6d1ecc61f7fc35c6b20363c7b1b96f39a14083df940", size = 20554, upload-time = "2025-05-23T11:40:50.314Z" }, + { url = "https://files.pythonhosted.org/packages/e1/6e/e76341d68aa717a705a2ee3be6da9f4122a0d1e3f3ad93a7104ed7a81bea/hiredis-3.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:b5b1653ad7263a001f2e907e81a957d6087625f9700fa404f1a2268c0a4f9059", size = 22136, upload-time = "2025-05-23T11:40:51.497Z" }, + { url = "https://files.pythonhosted.org/packages/ed/f9/04a0a6c760d28e0b7d536646edacd6f5b4c979dd4c848621287bff5be9d0/hiredis-3.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:73913d2fa379e722d17ba52f21ce12dd578140941a08efd73e73b6fab1dea4d8", size = 40382, upload-time = "2025-05-23T11:41:34.425Z" }, + { url = "https://files.pythonhosted.org/packages/cd/1c/50fbce19cc5e393cf97a187462377d1c9441337684b3da1ed13ed0f20873/hiredis-3.2.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:15a3dff3eca31ecbf3d7d6d104cf1b318dc2b013bad3f4bdb2839cb9ea2e1584", size = 37760, upload-time = "2025-05-23T11:41:35.432Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e6/d147636edf44e5267f9e4c3483cd8d6b027fd6cf008a003c932f5ff888f7/hiredis-3.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c78258032c2f9fc6f39fee7b07882ce26de281e09178266ce535992572132d95", size = 48738, upload-time = "2025-05-23T11:41:36.452Z" }, + { url = "https://files.pythonhosted.org/packages/97/b0/53c33900139149a9b85878c04748984987b62ee2583d452b4e4d578067a9/hiredis-3.2.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578d6a881e64e46db065256355594e680202c3bacf3270be3140057171d2c23e", size = 56254, upload-time = "2025-05-23T11:41:38.395Z" }, + { url = "https://files.pythonhosted.org/packages/9d/af/b49debecac06674a9ccb51353f497300199d6122a7612f56930872076147/hiredis-3.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b7f34b170093c077c972b8cc0ceb15d8ff88ad0079751a8ae9733e94d77e733", size = 48905, upload-time = "2025-05-23T11:41:39.92Z" }, + { url = "https://files.pythonhosted.org/packages/c6/a2/5aacf68320bfaf531afac73f62f4fc55140742a4725bf04929671ca5d1cc/hiredis-3.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:291a18b228fc90f6720d178de2fac46522082c96330b4cc2d3dd8cb2c1cb2815", size = 22184, upload-time = "2025-05-23T11:41:41.196Z" }, ] [[package]] @@ -1418,45 +1492,45 @@ dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 } +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 }, + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, ] [[package]] name = "httptools" version = "0.6.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/6f/972f8eb0ea7d98a1c6be436e2142d51ad2a64ee18e02b0e7ff1f62171ab1/httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0", size = 198780 }, - { url = "https://files.pythonhosted.org/packages/6a/b0/17c672b4bc5c7ba7f201eada4e96c71d0a59fbc185e60e42580093a86f21/httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da", size = 103297 }, - { url = "https://files.pythonhosted.org/packages/92/5e/b4a826fe91971a0b68e8c2bd4e7db3e7519882f5a8ccdb1194be2b3ab98f/httptools-0.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1", size = 443130 }, - { url = "https://files.pythonhosted.org/packages/b0/51/ce61e531e40289a681a463e1258fa1e05e0be54540e40d91d065a264cd8f/httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50", size = 442148 }, - { url = "https://files.pythonhosted.org/packages/ea/9e/270b7d767849b0c96f275c695d27ca76c30671f8eb8cc1bab6ced5c5e1d0/httptools-0.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959", size = 415949 }, - { url = "https://files.pythonhosted.org/packages/81/86/ced96e3179c48c6f656354e106934e65c8963d48b69be78f355797f0e1b3/httptools-0.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4", size = 417591 }, - { url = "https://files.pythonhosted.org/packages/75/73/187a3f620ed3175364ddb56847d7a608a6fc42d551e133197098c0143eca/httptools-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c", size = 88344 }, - { url = "https://files.pythonhosted.org/packages/7b/26/bb526d4d14c2774fe07113ca1db7255737ffbb119315839af2065abfdac3/httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069", size = 199029 }, - { url = "https://files.pythonhosted.org/packages/a6/17/3e0d3e9b901c732987a45f4f94d4e2c62b89a041d93db89eafb262afd8d5/httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a", size = 103492 }, - { url = "https://files.pythonhosted.org/packages/b7/24/0fe235d7b69c42423c7698d086d4db96475f9b50b6ad26a718ef27a0bce6/httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975", size = 462891 }, - { url = "https://files.pythonhosted.org/packages/b1/2f/205d1f2a190b72da6ffb5f41a3736c26d6fa7871101212b15e9b5cd8f61d/httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636", size = 459788 }, - { url = "https://files.pythonhosted.org/packages/6e/4c/d09ce0eff09057a206a74575ae8f1e1e2f0364d20e2442224f9e6612c8b9/httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721", size = 433214 }, - { url = "https://files.pythonhosted.org/packages/3e/d2/84c9e23edbccc4a4c6f96a1b8d99dfd2350289e94f00e9ccc7aadde26fb5/httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988", size = 434120 }, - { url = "https://files.pythonhosted.org/packages/d0/46/4d8e7ba9581416de1c425b8264e2cadd201eb709ec1584c381f3e98f51c1/httptools-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17", size = 88565 }, - { url = "https://files.pythonhosted.org/packages/bb/0e/d0b71465c66b9185f90a091ab36389a7352985fe857e352801c39d6127c8/httptools-0.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2", size = 200683 }, - { url = "https://files.pythonhosted.org/packages/e2/b8/412a9bb28d0a8988de3296e01efa0bd62068b33856cdda47fe1b5e890954/httptools-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44", size = 104337 }, - { url = "https://files.pythonhosted.org/packages/9b/01/6fb20be3196ffdc8eeec4e653bc2a275eca7f36634c86302242c4fbb2760/httptools-0.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1", size = 508796 }, - { url = "https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2", size = 510837 }, - { url = "https://files.pythonhosted.org/packages/52/d8/254d16a31d543073a0e57f1c329ca7378d8924e7e292eda72d0064987486/httptools-0.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81", size = 485289 }, - { url = "https://files.pythonhosted.org/packages/5f/3c/4aee161b4b7a971660b8be71a92c24d6c64372c1ab3ae7f366b3680df20f/httptools-0.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f", size = 489779 }, - { url = "https://files.pythonhosted.org/packages/12/b7/5cae71a8868e555f3f67a50ee7f673ce36eac970f029c0c5e9d584352961/httptools-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970", size = 88634 }, - { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214 }, - { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431 }, - { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121 }, - { url = "https://files.pythonhosted.org/packages/af/71/ee32fd358f8a3bb199b03261f10921716990808a675d8160b5383487a317/httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071", size = 473805 }, - { url = "https://files.pythonhosted.org/packages/8a/0a/0d4df132bfca1507114198b766f1737d57580c9ad1cf93c1ff673e3387be/httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5", size = 448858 }, - { url = "https://files.pythonhosted.org/packages/1e/6a/787004fdef2cabea27bad1073bf6a33f2437b4dbd3b6fb4a9d71172b1c7c/httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0", size = 452042 }, - { url = "https://files.pythonhosted.org/packages/4d/dc/7decab5c404d1d2cdc1bb330b1bf70e83d6af0396fd4fc76fc60c0d522bf/httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8", size = 87682 }, +sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639, upload-time = "2024-10-16T19:45:08.902Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/6f/972f8eb0ea7d98a1c6be436e2142d51ad2a64ee18e02b0e7ff1f62171ab1/httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0", size = 198780, upload-time = "2024-10-16T19:44:06.882Z" }, + { url = "https://files.pythonhosted.org/packages/6a/b0/17c672b4bc5c7ba7f201eada4e96c71d0a59fbc185e60e42580093a86f21/httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da", size = 103297, upload-time = "2024-10-16T19:44:08.129Z" }, + { url = "https://files.pythonhosted.org/packages/92/5e/b4a826fe91971a0b68e8c2bd4e7db3e7519882f5a8ccdb1194be2b3ab98f/httptools-0.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1", size = 443130, upload-time = "2024-10-16T19:44:09.45Z" }, + { url = "https://files.pythonhosted.org/packages/b0/51/ce61e531e40289a681a463e1258fa1e05e0be54540e40d91d065a264cd8f/httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50", size = 442148, upload-time = "2024-10-16T19:44:11.539Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9e/270b7d767849b0c96f275c695d27ca76c30671f8eb8cc1bab6ced5c5e1d0/httptools-0.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959", size = 415949, upload-time = "2024-10-16T19:44:13.388Z" }, + { url = "https://files.pythonhosted.org/packages/81/86/ced96e3179c48c6f656354e106934e65c8963d48b69be78f355797f0e1b3/httptools-0.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4", size = 417591, upload-time = "2024-10-16T19:44:15.258Z" }, + { url = "https://files.pythonhosted.org/packages/75/73/187a3f620ed3175364ddb56847d7a608a6fc42d551e133197098c0143eca/httptools-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c", size = 88344, upload-time = "2024-10-16T19:44:16.54Z" }, + { url = "https://files.pythonhosted.org/packages/7b/26/bb526d4d14c2774fe07113ca1db7255737ffbb119315839af2065abfdac3/httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069", size = 199029, upload-time = "2024-10-16T19:44:18.427Z" }, + { url = "https://files.pythonhosted.org/packages/a6/17/3e0d3e9b901c732987a45f4f94d4e2c62b89a041d93db89eafb262afd8d5/httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a", size = 103492, upload-time = "2024-10-16T19:44:19.515Z" }, + { url = "https://files.pythonhosted.org/packages/b7/24/0fe235d7b69c42423c7698d086d4db96475f9b50b6ad26a718ef27a0bce6/httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975", size = 462891, upload-time = "2024-10-16T19:44:21.067Z" }, + { url = "https://files.pythonhosted.org/packages/b1/2f/205d1f2a190b72da6ffb5f41a3736c26d6fa7871101212b15e9b5cd8f61d/httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636", size = 459788, upload-time = "2024-10-16T19:44:22.958Z" }, + { url = "https://files.pythonhosted.org/packages/6e/4c/d09ce0eff09057a206a74575ae8f1e1e2f0364d20e2442224f9e6612c8b9/httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721", size = 433214, upload-time = "2024-10-16T19:44:24.513Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/84c9e23edbccc4a4c6f96a1b8d99dfd2350289e94f00e9ccc7aadde26fb5/httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988", size = 434120, upload-time = "2024-10-16T19:44:26.295Z" }, + { url = "https://files.pythonhosted.org/packages/d0/46/4d8e7ba9581416de1c425b8264e2cadd201eb709ec1584c381f3e98f51c1/httptools-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17", size = 88565, upload-time = "2024-10-16T19:44:29.188Z" }, + { url = "https://files.pythonhosted.org/packages/bb/0e/d0b71465c66b9185f90a091ab36389a7352985fe857e352801c39d6127c8/httptools-0.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2", size = 200683, upload-time = "2024-10-16T19:44:30.175Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b8/412a9bb28d0a8988de3296e01efa0bd62068b33856cdda47fe1b5e890954/httptools-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44", size = 104337, upload-time = "2024-10-16T19:44:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/9b/01/6fb20be3196ffdc8eeec4e653bc2a275eca7f36634c86302242c4fbb2760/httptools-0.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1", size = 508796, upload-time = "2024-10-16T19:44:32.825Z" }, + { url = "https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2", size = 510837, upload-time = "2024-10-16T19:44:33.974Z" }, + { url = "https://files.pythonhosted.org/packages/52/d8/254d16a31d543073a0e57f1c329ca7378d8924e7e292eda72d0064987486/httptools-0.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81", size = 485289, upload-time = "2024-10-16T19:44:35.111Z" }, + { url = "https://files.pythonhosted.org/packages/5f/3c/4aee161b4b7a971660b8be71a92c24d6c64372c1ab3ae7f366b3680df20f/httptools-0.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f", size = 489779, upload-time = "2024-10-16T19:44:36.253Z" }, + { url = "https://files.pythonhosted.org/packages/12/b7/5cae71a8868e555f3f67a50ee7f673ce36eac970f029c0c5e9d584352961/httptools-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970", size = 88634, upload-time = "2024-10-16T19:44:37.357Z" }, + { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214, upload-time = "2024-10-16T19:44:38.738Z" }, + { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431, upload-time = "2024-10-16T19:44:39.818Z" }, + { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121, upload-time = "2024-10-16T19:44:41.189Z" }, + { url = "https://files.pythonhosted.org/packages/af/71/ee32fd358f8a3bb199b03261f10921716990808a675d8160b5383487a317/httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071", size = 473805, upload-time = "2024-10-16T19:44:42.384Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0a/0d4df132bfca1507114198b766f1737d57580c9ad1cf93c1ff673e3387be/httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5", size = 448858, upload-time = "2024-10-16T19:44:43.959Z" }, + { url = "https://files.pythonhosted.org/packages/1e/6a/787004fdef2cabea27bad1073bf6a33f2437b4dbd3b6fb4a9d71172b1c7c/httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0", size = 452042, upload-time = "2024-10-16T19:44:45.071Z" }, + { url = "https://files.pythonhosted.org/packages/4d/dc/7decab5c404d1d2cdc1bb330b1bf70e83d6af0396fd4fc76fc60c0d522bf/httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8", size = 87682, upload-time = "2024-10-16T19:44:46.46Z" }, ] [[package]] @@ -1469,18 +1543,18 @@ dependencies = [ { 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 } +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 }, + { 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]] name = "httpx-sse" version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 } +sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624, upload-time = "2023-12-22T08:01:21.083Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 }, + { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819, upload-time = "2023-12-22T08:01:19.89Z" }, ] [[package]] @@ -1497,9 +1571,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/ca/8ee27c56ab650d9d3ea095f0ba12ceb202bc8ba7362429dc76c25438df2f/huggingface_hub-0.32.0.tar.gz", hash = "sha256:dd66c9365ea43049ec9b939bdcdb21a0051e1bd70026fc50304e4fb1bb6a15ba", size = 422255 } +sdist = { url = "https://files.pythonhosted.org/packages/f4/ca/8ee27c56ab650d9d3ea095f0ba12ceb202bc8ba7362429dc76c25438df2f/huggingface_hub-0.32.0.tar.gz", hash = "sha256:dd66c9365ea43049ec9b939bdcdb21a0051e1bd70026fc50304e4fb1bb6a15ba", size = 422255, upload-time = "2025-05-23T12:12:13.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/60/90aae898b0a9f3cd65f50718c33b1f1dbfb1527d10db754e99e14e2b0a1d/huggingface_hub-0.32.0-py3-none-any.whl", hash = "sha256:e56e94109649ce6ebdb59b4e393ee3543ec0eca2eab4f41b269e1d885c88d08c", size = 509297 }, + { url = "https://files.pythonhosted.org/packages/3a/60/90aae898b0a9f3cd65f50718c33b1f1dbfb1527d10db754e99e14e2b0a1d/huggingface_hub-0.32.0-py3-none-any.whl", hash = "sha256:e56e94109649ce6ebdb59b4e393ee3543ec0eca2eab4f41b269e1d885c88d08c", size = 509297, upload-time = "2025-05-23T12:12:11.871Z" }, ] [[package]] @@ -1509,9 +1583,9 @@ 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 } +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 }, + { 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]] @@ -1521,27 +1595,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/48/a4/c0b698a7250b7a5c2956427406560701862215c646e079a7907846608f44/hvac-2.3.0.tar.gz", hash = "sha256:1b85e3320e8642dd82f234db63253cda169a817589e823713dc5fca83119b1e2", size = 332660 } +sdist = { url = "https://files.pythonhosted.org/packages/48/a4/c0b698a7250b7a5c2956427406560701862215c646e079a7907846608f44/hvac-2.3.0.tar.gz", hash = "sha256:1b85e3320e8642dd82f234db63253cda169a817589e823713dc5fca83119b1e2", size = 332660, upload-time = "2024-06-18T14:46:09.748Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/34/56facf52e2ea14ce640f434ccf00311af6f3a1df0019d4682ba28ea09948/hvac-2.3.0-py3-none-any.whl", hash = "sha256:a3afc5710760b6ee9b3571769df87a0333da45da05a5f9f963e1d3925a84be7d", size = 155860 }, + { url = "https://files.pythonhosted.org/packages/0b/34/56facf52e2ea14ce640f434ccf00311af6f3a1df0019d4682ba28ea09948/hvac-2.3.0-py3-none-any.whl", hash = "sha256:a3afc5710760b6ee9b3571769df87a0333da45da05a5f9f963e1d3925a84be7d", size = 155860, upload-time = "2024-06-18T14:46:05.399Z" }, ] [[package]] name = "identify" version = "2.6.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/88/d193a27416618628a5eea64e3223acd800b40749a96ffb322a9b55a49ed1/identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6", size = 99254 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/88/d193a27416618628a5eea64e3223acd800b40749a96ffb322a9b55a49ed1/identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6", size = 99254, upload-time = "2025-05-23T20:37:53.3Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/cd/18f8da995b658420625f7ef13f037be53ae04ec5ad33f9b718240dcfd48c/identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2", size = 99145 }, + { url = "https://files.pythonhosted.org/packages/7a/cd/18f8da995b658420625f7ef13f037be53ae04ec5ad33f9b718240dcfd48c/identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2", size = 99145, upload-time = "2025-05-23T20:37:51.495Z" }, ] [[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 } +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 }, + { 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]] @@ -1551,27 +1625,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "zipp" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/08/c1395a292bb23fd03bdf572a1357c5a733d3eecbab877641ceacab23db6e/importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580", size = 55767 } +sdist = { url = "https://files.pythonhosted.org/packages/33/08/c1395a292bb23fd03bdf572a1357c5a733d3eecbab877641ceacab23db6e/importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580", size = 55767, upload-time = "2025-01-20T22:21:30.429Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/79/9d/0fb148dc4d6fa4a7dd1d8378168d9b4cd8d4560a6fbf6f0121c5fc34eb68/importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e", size = 26971 }, + { url = "https://files.pythonhosted.org/packages/79/9d/0fb148dc4d6fa4a7dd1d8378168d9b4cd8d4560a6fbf6f0121c5fc34eb68/importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e", size = 26971, upload-time = "2025-01-20T22:21:29.177Z" }, ] [[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 } +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 }, + { 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.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793 } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050 }, + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] [[package]] @@ -1591,9 +1665,9 @@ dependencies = [ { name = "tenacity" }, { name = "typer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/54/927c2093dc5e532195baf849f7ff1376ad673222b5d37be19e4e73af618e/instructor-1.8.3.tar.gz", hash = "sha256:04d64ebc0d6e5eee104f4715b18fac1a02c21757ae6ce76efa65d38cbd536b0b", size = 69265823 } +sdist = { url = "https://files.pythonhosted.org/packages/a9/54/927c2093dc5e532195baf849f7ff1376ad673222b5d37be19e4e73af618e/instructor-1.8.3.tar.gz", hash = "sha256:04d64ebc0d6e5eee104f4715b18fac1a02c21757ae6ce76efa65d38cbd536b0b", size = 69265823, upload-time = "2025-05-22T16:44:02.409Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/76/0e198373f182020559b0886d0d61dd2ddca109ab7a9eddf5458ff759d51a/instructor-1.8.3-py3-none-any.whl", hash = "sha256:a2c5066458132dc50ec6faa87cab9a2dd6b11b3f45c0e563a2ef704892286945", size = 94619 }, + { url = "https://files.pythonhosted.org/packages/07/76/0e198373f182020559b0886d0d61dd2ddca109ab7a9eddf5458ff759d51a/instructor-1.8.3-py3-none-any.whl", hash = "sha256:a2c5066458132dc50ec6faa87cab9a2dd6b11b3f45c0e563a2ef704892286945", size = 94619, upload-time = "2025-05-22T16:43:58.529Z" }, ] [[package]] @@ -1616,9 +1690,9 @@ dependencies = [ { name = "traitlets", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/85/31/10ac88f3357fc276dc8a64e8880c82e80e7459326ae1d0a211b40abf6665/ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216", size = 5606088 } +sdist = { url = "https://files.pythonhosted.org/packages/85/31/10ac88f3357fc276dc8a64e8880c82e80e7459326ae1d0a211b40abf6665/ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216", size = 5606088, upload-time = "2025-05-31T16:39:09.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/d0/274fbf7b0b12643cbbc001ce13e6a5b1607ac4929d1b11c72460152c9fc3/ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2", size = 831864 }, + { url = "https://files.pythonhosted.org/packages/91/d0/274fbf7b0b12643cbbc001ce13e6a5b1607ac4929d1b11c72460152c9fc3/ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2", size = 831864, upload-time = "2025-05-31T16:39:06.38Z" }, ] [[package]] @@ -1644,9 +1718,9 @@ dependencies = [ { name = "traitlets", marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version == '3.11.*'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/dc/09/4c7e06b96fbd203e06567b60fb41b06db606b6a82db6db7b2c85bb72a15c/ipython-9.3.0.tar.gz", hash = "sha256:79eb896f9f23f50ad16c3bc205f686f6e030ad246cc309c6279a242b14afe9d8", size = 4426460 } +sdist = { url = "https://files.pythonhosted.org/packages/dc/09/4c7e06b96fbd203e06567b60fb41b06db606b6a82db6db7b2c85bb72a15c/ipython-9.3.0.tar.gz", hash = "sha256:79eb896f9f23f50ad16c3bc205f686f6e030ad246cc309c6279a242b14afe9d8", size = 4426460, upload-time = "2025-05-31T16:34:55.678Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/99/9ed3d52d00f1846679e3aa12e2326ac7044b5e7f90dc822b60115fa533ca/ipython-9.3.0-py3-none-any.whl", hash = "sha256:1a0b6dd9221a1f5dddf725b57ac0cb6fddc7b5f470576231ae9162b9b3455a04", size = 605320 }, + { url = "https://files.pythonhosted.org/packages/3c/99/9ed3d52d00f1846679e3aa12e2326ac7044b5e7f90dc822b60115fa533ca/ipython-9.3.0-py3-none-any.whl", hash = "sha256:1a0b6dd9221a1f5dddf725b57ac0cb6fddc7b5f470576231ae9162b9b3455a04", size = 605320, upload-time = "2025-05-31T16:34:52.154Z" }, ] [[package]] @@ -1656,18 +1730,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pygments", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393 } +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074 }, + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, ] [[package]] name = "isodate" version = "0.7.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/4d/e940025e2ce31a8ce1202635910747e5a87cc3a6a6bb2d00973375014749/isodate-0.7.2.tar.gz", hash = "sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6", size = 29705 } +sdist = { url = "https://files.pythonhosted.org/packages/54/4d/e940025e2ce31a8ce1202635910747e5a87cc3a6a6bb2d00973375014749/isodate-0.7.2.tar.gz", hash = "sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6", size = 29705, upload-time = "2024-10-08T23:04:11.5Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl", hash = "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", size = 22320 }, + { url = "https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl", hash = "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", size = 22320, upload-time = "2024-10-08T23:04:09.501Z" }, ] [[package]] @@ -1677,9 +1751,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "parso" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287 } +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, ] [[package]] @@ -1689,104 +1763,104 @@ 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 } +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 }, + { 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.8.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/70/90bc7bd3932e651486861df5c8ffea4ca7c77d28e8532ddefe2abc561a53/jiter-0.8.2.tar.gz", hash = "sha256:cd73d3e740666d0e639f678adb176fad25c1bcbdae88d8d7b857e1783bb4212d", size = 163007 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/f3/8c11e0e87bd5934c414f9b1cfae3cbfd4a938d4669d57cb427e1c4d11a7f/jiter-0.8.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ca8577f6a413abe29b079bc30f907894d7eb07a865c4df69475e868d73e71c7b", size = 303381 }, - { url = "https://files.pythonhosted.org/packages/ea/28/4cd3f0bcbf40e946bc6a62a82c951afc386a25673d3d8d5ee461f1559bbe/jiter-0.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b25bd626bde7fb51534190c7e3cb97cee89ee76b76d7585580e22f34f5e3f393", size = 311718 }, - { url = "https://files.pythonhosted.org/packages/0d/17/57acab00507e60bd954eaec0837d9d7b119b4117ff49b8a62f2b646f32ed/jiter-0.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5c826a221851a8dc028eb6d7d6429ba03184fa3c7e83ae01cd6d3bd1d4bd17d", size = 335465 }, - { url = "https://files.pythonhosted.org/packages/74/b9/1a3ddd2bc95ae17c815b021521020f40c60b32137730126bada962ef32b4/jiter-0.8.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d35c864c2dff13dfd79fb070fc4fc6235d7b9b359efe340e1261deb21b9fcb66", size = 355570 }, - { url = "https://files.pythonhosted.org/packages/78/69/6d29e2296a934199a7d0dde673ecccf98c9c8db44caf0248b3f2b65483cb/jiter-0.8.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f557c55bc2b7676e74d39d19bcb8775ca295c7a028246175d6a8b431e70835e5", size = 381383 }, - { url = "https://files.pythonhosted.org/packages/22/d7/fbc4c3fb1bf65f9be22a32759b539f88e897aeb13fe84ab0266e4423487a/jiter-0.8.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:580ccf358539153db147e40751a0b41688a5ceb275e6f3e93d91c9467f42b2e3", size = 390454 }, - { url = "https://files.pythonhosted.org/packages/4d/a0/3993cda2e267fe679b45d0bcc2cef0b4504b0aa810659cdae9737d6bace9/jiter-0.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af102d3372e917cffce49b521e4c32c497515119dc7bd8a75665e90a718bbf08", size = 345039 }, - { url = "https://files.pythonhosted.org/packages/b9/ef/69c18562b4c09ce88fab5df1dcaf643f6b1a8b970b65216e7221169b81c4/jiter-0.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cadcc978f82397d515bb2683fc0d50103acff2a180552654bb92d6045dec2c49", size = 376200 }, - { url = "https://files.pythonhosted.org/packages/4d/17/0b5a8de46a6ab4d836f70934036278b49b8530c292b29dde3483326d4555/jiter-0.8.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ba5bdf56969cad2019d4e8ffd3f879b5fdc792624129741d3d83fc832fef8c7d", size = 511158 }, - { url = "https://files.pythonhosted.org/packages/6c/b2/c401a0a2554b36c9e6d6e4876b43790d75139cf3936f0222e675cbc23451/jiter-0.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3b94a33a241bee9e34b8481cdcaa3d5c2116f575e0226e421bed3f7a6ea71cff", size = 503956 }, - { url = "https://files.pythonhosted.org/packages/d4/02/a0291ed7d72c0ac130f172354ee3cf0b2556b69584de391463a8ee534f40/jiter-0.8.2-cp310-cp310-win32.whl", hash = "sha256:6e5337bf454abddd91bd048ce0dca5134056fc99ca0205258766db35d0a2ea43", size = 202846 }, - { url = "https://files.pythonhosted.org/packages/ad/20/8c988831ae4bf437e29f1671e198fc99ba8fe49f2895f23789acad1d1811/jiter-0.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:4a9220497ca0cb1fe94e3f334f65b9b5102a0b8147646118f020d8ce1de70105", size = 204414 }, - { url = "https://files.pythonhosted.org/packages/cb/b0/c1a7caa7f9dc5f1f6cfa08722867790fe2d3645d6e7170ca280e6e52d163/jiter-0.8.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:2dd61c5afc88a4fda7d8b2cf03ae5947c6ac7516d32b7a15bf4b49569a5c076b", size = 303666 }, - { url = "https://files.pythonhosted.org/packages/f5/97/0468bc9eeae43079aaa5feb9267964e496bf13133d469cfdc135498f8dd0/jiter-0.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a6c710d657c8d1d2adbbb5c0b0c6bfcec28fd35bd6b5f016395f9ac43e878a15", size = 311934 }, - { url = "https://files.pythonhosted.org/packages/e5/69/64058e18263d9a5f1e10f90c436853616d5f047d997c37c7b2df11b085ec/jiter-0.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9584de0cd306072635fe4b89742bf26feae858a0683b399ad0c2509011b9dc0", size = 335506 }, - { url = "https://files.pythonhosted.org/packages/9d/14/b747f9a77b8c0542141d77ca1e2a7523e854754af2c339ac89a8b66527d6/jiter-0.8.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a90a923338531b7970abb063cfc087eebae6ef8ec8139762007188f6bc69a9f", size = 355849 }, - { url = "https://files.pythonhosted.org/packages/53/e2/98a08161db7cc9d0e39bc385415890928ff09709034982f48eccfca40733/jiter-0.8.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21974d246ed0181558087cd9f76e84e8321091ebfb3a93d4c341479a736f099", size = 381700 }, - { url = "https://files.pythonhosted.org/packages/7a/38/1674672954d35bce3b1c9af99d5849f9256ac8f5b672e020ac7821581206/jiter-0.8.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32475a42b2ea7b344069dc1e81445cfc00b9d0e3ca837f0523072432332e9f74", size = 389710 }, - { url = "https://files.pythonhosted.org/packages/f8/9b/92f9da9a9e107d019bcf883cd9125fa1690079f323f5a9d5c6986eeec3c0/jiter-0.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b9931fd36ee513c26b5bf08c940b0ac875de175341cbdd4fa3be109f0492586", size = 345553 }, - { url = "https://files.pythonhosted.org/packages/44/a6/6d030003394e9659cd0d7136bbeabd82e869849ceccddc34d40abbbbb269/jiter-0.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0820f4a3a59ddced7fce696d86a096d5cc48d32a4183483a17671a61edfddc", size = 376388 }, - { url = "https://files.pythonhosted.org/packages/ad/8d/87b09e648e4aca5f9af89e3ab3cfb93db2d1e633b2f2931ede8dabd9b19a/jiter-0.8.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ffc86ae5e3e6a93765d49d1ab47b6075a9c978a2b3b80f0f32628f39caa0c88", size = 511226 }, - { url = "https://files.pythonhosted.org/packages/77/95/8008ebe4cdc82eac1c97864a8042ca7e383ed67e0ec17bfd03797045c727/jiter-0.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5127dc1abd809431172bc3fbe8168d6b90556a30bb10acd5ded41c3cfd6f43b6", size = 504134 }, - { url = "https://files.pythonhosted.org/packages/26/0d/3056a74de13e8b2562e4d526de6dac2f65d91ace63a8234deb9284a1d24d/jiter-0.8.2-cp311-cp311-win32.whl", hash = "sha256:66227a2c7b575720c1871c8800d3a0122bb8ee94edb43a5685aa9aceb2782d44", size = 203103 }, - { url = "https://files.pythonhosted.org/packages/4e/1e/7f96b798f356e531ffc0f53dd2f37185fac60fae4d6c612bbbd4639b90aa/jiter-0.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:cde031d8413842a1e7501e9129b8e676e62a657f8ec8166e18a70d94d4682855", size = 206717 }, - { url = "https://files.pythonhosted.org/packages/a1/17/c8747af8ea4e045f57d6cfd6fc180752cab9bc3de0e8a0c9ca4e8af333b1/jiter-0.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:e6ec2be506e7d6f9527dae9ff4b7f54e68ea44a0ef6b098256ddf895218a2f8f", size = 302027 }, - { url = "https://files.pythonhosted.org/packages/3c/c1/6da849640cd35a41e91085723b76acc818d4b7d92b0b6e5111736ce1dd10/jiter-0.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76e324da7b5da060287c54f2fabd3db5f76468006c811831f051942bf68c9d44", size = 310326 }, - { url = "https://files.pythonhosted.org/packages/06/99/a2bf660d8ccffee9ad7ed46b4f860d2108a148d0ea36043fd16f4dc37e94/jiter-0.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:180a8aea058f7535d1c84183c0362c710f4750bef66630c05f40c93c2b152a0f", size = 334242 }, - { url = "https://files.pythonhosted.org/packages/a7/5f/cea1c17864828731f11427b9d1ab7f24764dbd9aaf4648a7f851164d2718/jiter-0.8.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:025337859077b41548bdcbabe38698bcd93cfe10b06ff66617a48ff92c9aec60", size = 356654 }, - { url = "https://files.pythonhosted.org/packages/e9/13/62774b7e5e7f5d5043efe1d0f94ead66e6d0f894ae010adb56b3f788de71/jiter-0.8.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecff0dc14f409599bbcafa7e470c00b80f17abc14d1405d38ab02e4b42e55b57", size = 379967 }, - { url = "https://files.pythonhosted.org/packages/ec/fb/096b34c553bb0bd3f2289d5013dcad6074948b8d55212aa13a10d44c5326/jiter-0.8.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffd9fee7d0775ebaba131f7ca2e2d83839a62ad65e8e02fe2bd8fc975cedeb9e", size = 389252 }, - { url = "https://files.pythonhosted.org/packages/17/61/beea645c0bf398ced8b199e377b61eb999d8e46e053bb285c91c3d3eaab0/jiter-0.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14601dcac4889e0a1c75ccf6a0e4baf70dbc75041e51bcf8d0e9274519df6887", size = 345490 }, - { url = "https://files.pythonhosted.org/packages/d5/df/834aa17ad5dcc3cf0118821da0a0cf1589ea7db9832589278553640366bc/jiter-0.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92249669925bc1c54fcd2ec73f70f2c1d6a817928480ee1c65af5f6b81cdf12d", size = 376991 }, - { url = "https://files.pythonhosted.org/packages/67/80/87d140399d382fb4ea5b3d56e7ecaa4efdca17cd7411ff904c1517855314/jiter-0.8.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e725edd0929fa79f8349ab4ec7f81c714df51dc4e991539a578e5018fa4a7152", size = 510822 }, - { url = "https://files.pythonhosted.org/packages/5c/37/3394bb47bac1ad2cb0465601f86828a0518d07828a650722e55268cdb7e6/jiter-0.8.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bf55846c7b7a680eebaf9c3c48d630e1bf51bdf76c68a5f654b8524335b0ad29", size = 503730 }, - { url = "https://files.pythonhosted.org/packages/f9/e2/253fc1fa59103bb4e3aa0665d6ceb1818df1cd7bf3eb492c4dad229b1cd4/jiter-0.8.2-cp312-cp312-win32.whl", hash = "sha256:7efe4853ecd3d6110301665a5178b9856be7e2a9485f49d91aa4d737ad2ae49e", size = 203375 }, - { url = "https://files.pythonhosted.org/packages/41/69/6d4bbe66b3b3b4507e47aa1dd5d075919ad242b4b1115b3f80eecd443687/jiter-0.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:83c0efd80b29695058d0fd2fa8a556490dbce9804eac3e281f373bbc99045f6c", size = 204740 }, - { url = "https://files.pythonhosted.org/packages/6c/b0/bfa1f6f2c956b948802ef5a021281978bf53b7a6ca54bb126fd88a5d014e/jiter-0.8.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ca1f08b8e43dc3bd0594c992fb1fd2f7ce87f7bf0d44358198d6da8034afdf84", size = 301190 }, - { url = "https://files.pythonhosted.org/packages/a4/8f/396ddb4e292b5ea57e45ade5dc48229556b9044bad29a3b4b2dddeaedd52/jiter-0.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5672a86d55416ccd214c778efccf3266b84f87b89063b582167d803246354be4", size = 309334 }, - { url = "https://files.pythonhosted.org/packages/7f/68/805978f2f446fa6362ba0cc2e4489b945695940656edd844e110a61c98f8/jiter-0.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58dc9bc9767a1101f4e5e22db1b652161a225874d66f0e5cb8e2c7d1c438b587", size = 333918 }, - { url = "https://files.pythonhosted.org/packages/b3/99/0f71f7be667c33403fa9706e5b50583ae5106d96fab997fa7e2f38ee8347/jiter-0.8.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37b2998606d6dadbb5ccda959a33d6a5e853252d921fec1792fc902351bb4e2c", size = 356057 }, - { url = "https://files.pythonhosted.org/packages/8d/50/a82796e421a22b699ee4d2ce527e5bcb29471a2351cbdc931819d941a167/jiter-0.8.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ab9a87f3784eb0e098f84a32670cfe4a79cb6512fd8f42ae3d0709f06405d18", size = 379790 }, - { url = "https://files.pythonhosted.org/packages/3c/31/10fb012b00f6d83342ca9e2c9618869ab449f1aa78c8f1b2193a6b49647c/jiter-0.8.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79aec8172b9e3c6d05fd4b219d5de1ac616bd8da934107325a6c0d0e866a21b6", size = 388285 }, - { url = "https://files.pythonhosted.org/packages/c8/81/f15ebf7de57be488aa22944bf4274962aca8092e4f7817f92ffa50d3ee46/jiter-0.8.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:711e408732d4e9a0208008e5892c2966b485c783cd2d9a681f3eb147cf36c7ef", size = 344764 }, - { url = "https://files.pythonhosted.org/packages/b3/e8/0cae550d72b48829ba653eb348cdc25f3f06f8a62363723702ec18e7be9c/jiter-0.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:653cf462db4e8c41995e33d865965e79641ef45369d8a11f54cd30888b7e6ff1", size = 376620 }, - { url = "https://files.pythonhosted.org/packages/b8/50/e5478ff9d82534a944c03b63bc217c5f37019d4a34d288db0f079b13c10b/jiter-0.8.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:9c63eaef32b7bebac8ebebf4dabebdbc6769a09c127294db6babee38e9f405b9", size = 510402 }, - { url = "https://files.pythonhosted.org/packages/8e/1e/3de48bbebbc8f7025bd454cedc8c62378c0e32dd483dece5f4a814a5cb55/jiter-0.8.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:eb21aaa9a200d0a80dacc7a81038d2e476ffe473ffdd9c91eb745d623561de05", size = 503018 }, - { url = "https://files.pythonhosted.org/packages/d5/cd/d5a5501d72a11fe3e5fd65c78c884e5164eefe80077680533919be22d3a3/jiter-0.8.2-cp313-cp313-win32.whl", hash = "sha256:789361ed945d8d42850f919342a8665d2dc79e7e44ca1c97cc786966a21f627a", size = 203190 }, - { url = "https://files.pythonhosted.org/packages/51/bf/e5ca301245ba951447e3ad677a02a64a8845b185de2603dabd83e1e4b9c6/jiter-0.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:ab7f43235d71e03b941c1630f4b6e3055d46b6cb8728a17663eaac9d8e83a865", size = 203551 }, - { url = "https://files.pythonhosted.org/packages/2f/3c/71a491952c37b87d127790dd7a0b1ebea0514c6b6ad30085b16bbe00aee6/jiter-0.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b426f72cd77da3fec300ed3bc990895e2dd6b49e3bfe6c438592a3ba660e41ca", size = 308347 }, - { url = "https://files.pythonhosted.org/packages/a0/4c/c02408042e6a7605ec063daed138e07b982fdb98467deaaf1c90950cf2c6/jiter-0.8.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2dd880785088ff2ad21ffee205e58a8c1ddabc63612444ae41e5e4b321b39c0", size = 342875 }, - { url = "https://files.pythonhosted.org/packages/91/61/c80ef80ed8a0a21158e289ef70dac01e351d929a1c30cb0f49be60772547/jiter-0.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:3ac9f578c46f22405ff7f8b1f5848fb753cc4b8377fbec8470a7dc3997ca7566", size = 202374 }, +sdist = { url = "https://files.pythonhosted.org/packages/f8/70/90bc7bd3932e651486861df5c8ffea4ca7c77d28e8532ddefe2abc561a53/jiter-0.8.2.tar.gz", hash = "sha256:cd73d3e740666d0e639f678adb176fad25c1bcbdae88d8d7b857e1783bb4212d", size = 163007, upload-time = "2024-12-09T18:11:08.649Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/f3/8c11e0e87bd5934c414f9b1cfae3cbfd4a938d4669d57cb427e1c4d11a7f/jiter-0.8.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ca8577f6a413abe29b079bc30f907894d7eb07a865c4df69475e868d73e71c7b", size = 303381, upload-time = "2024-12-09T18:09:00.301Z" }, + { url = "https://files.pythonhosted.org/packages/ea/28/4cd3f0bcbf40e946bc6a62a82c951afc386a25673d3d8d5ee461f1559bbe/jiter-0.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b25bd626bde7fb51534190c7e3cb97cee89ee76b76d7585580e22f34f5e3f393", size = 311718, upload-time = "2024-12-09T18:09:02.53Z" }, + { url = "https://files.pythonhosted.org/packages/0d/17/57acab00507e60bd954eaec0837d9d7b119b4117ff49b8a62f2b646f32ed/jiter-0.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5c826a221851a8dc028eb6d7d6429ba03184fa3c7e83ae01cd6d3bd1d4bd17d", size = 335465, upload-time = "2024-12-09T18:09:04.044Z" }, + { url = "https://files.pythonhosted.org/packages/74/b9/1a3ddd2bc95ae17c815b021521020f40c60b32137730126bada962ef32b4/jiter-0.8.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d35c864c2dff13dfd79fb070fc4fc6235d7b9b359efe340e1261deb21b9fcb66", size = 355570, upload-time = "2024-12-09T18:09:05.445Z" }, + { url = "https://files.pythonhosted.org/packages/78/69/6d29e2296a934199a7d0dde673ecccf98c9c8db44caf0248b3f2b65483cb/jiter-0.8.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f557c55bc2b7676e74d39d19bcb8775ca295c7a028246175d6a8b431e70835e5", size = 381383, upload-time = "2024-12-09T18:09:07.499Z" }, + { url = "https://files.pythonhosted.org/packages/22/d7/fbc4c3fb1bf65f9be22a32759b539f88e897aeb13fe84ab0266e4423487a/jiter-0.8.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:580ccf358539153db147e40751a0b41688a5ceb275e6f3e93d91c9467f42b2e3", size = 390454, upload-time = "2024-12-09T18:09:09.587Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a0/3993cda2e267fe679b45d0bcc2cef0b4504b0aa810659cdae9737d6bace9/jiter-0.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af102d3372e917cffce49b521e4c32c497515119dc7bd8a75665e90a718bbf08", size = 345039, upload-time = "2024-12-09T18:09:11.045Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ef/69c18562b4c09ce88fab5df1dcaf643f6b1a8b970b65216e7221169b81c4/jiter-0.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cadcc978f82397d515bb2683fc0d50103acff2a180552654bb92d6045dec2c49", size = 376200, upload-time = "2024-12-09T18:09:13.104Z" }, + { url = "https://files.pythonhosted.org/packages/4d/17/0b5a8de46a6ab4d836f70934036278b49b8530c292b29dde3483326d4555/jiter-0.8.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ba5bdf56969cad2019d4e8ffd3f879b5fdc792624129741d3d83fc832fef8c7d", size = 511158, upload-time = "2024-12-09T18:09:15.222Z" }, + { url = "https://files.pythonhosted.org/packages/6c/b2/c401a0a2554b36c9e6d6e4876b43790d75139cf3936f0222e675cbc23451/jiter-0.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3b94a33a241bee9e34b8481cdcaa3d5c2116f575e0226e421bed3f7a6ea71cff", size = 503956, upload-time = "2024-12-09T18:09:16.595Z" }, + { url = "https://files.pythonhosted.org/packages/d4/02/a0291ed7d72c0ac130f172354ee3cf0b2556b69584de391463a8ee534f40/jiter-0.8.2-cp310-cp310-win32.whl", hash = "sha256:6e5337bf454abddd91bd048ce0dca5134056fc99ca0205258766db35d0a2ea43", size = 202846, upload-time = "2024-12-09T18:09:19.347Z" }, + { url = "https://files.pythonhosted.org/packages/ad/20/8c988831ae4bf437e29f1671e198fc99ba8fe49f2895f23789acad1d1811/jiter-0.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:4a9220497ca0cb1fe94e3f334f65b9b5102a0b8147646118f020d8ce1de70105", size = 204414, upload-time = "2024-12-09T18:09:20.904Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b0/c1a7caa7f9dc5f1f6cfa08722867790fe2d3645d6e7170ca280e6e52d163/jiter-0.8.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:2dd61c5afc88a4fda7d8b2cf03ae5947c6ac7516d32b7a15bf4b49569a5c076b", size = 303666, upload-time = "2024-12-09T18:09:23.145Z" }, + { url = "https://files.pythonhosted.org/packages/f5/97/0468bc9eeae43079aaa5feb9267964e496bf13133d469cfdc135498f8dd0/jiter-0.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a6c710d657c8d1d2adbbb5c0b0c6bfcec28fd35bd6b5f016395f9ac43e878a15", size = 311934, upload-time = "2024-12-09T18:09:25.098Z" }, + { url = "https://files.pythonhosted.org/packages/e5/69/64058e18263d9a5f1e10f90c436853616d5f047d997c37c7b2df11b085ec/jiter-0.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9584de0cd306072635fe4b89742bf26feae858a0683b399ad0c2509011b9dc0", size = 335506, upload-time = "2024-12-09T18:09:26.407Z" }, + { url = "https://files.pythonhosted.org/packages/9d/14/b747f9a77b8c0542141d77ca1e2a7523e854754af2c339ac89a8b66527d6/jiter-0.8.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a90a923338531b7970abb063cfc087eebae6ef8ec8139762007188f6bc69a9f", size = 355849, upload-time = "2024-12-09T18:09:27.686Z" }, + { url = "https://files.pythonhosted.org/packages/53/e2/98a08161db7cc9d0e39bc385415890928ff09709034982f48eccfca40733/jiter-0.8.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21974d246ed0181558087cd9f76e84e8321091ebfb3a93d4c341479a736f099", size = 381700, upload-time = "2024-12-09T18:09:28.989Z" }, + { url = "https://files.pythonhosted.org/packages/7a/38/1674672954d35bce3b1c9af99d5849f9256ac8f5b672e020ac7821581206/jiter-0.8.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32475a42b2ea7b344069dc1e81445cfc00b9d0e3ca837f0523072432332e9f74", size = 389710, upload-time = "2024-12-09T18:09:30.565Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9b/92f9da9a9e107d019bcf883cd9125fa1690079f323f5a9d5c6986eeec3c0/jiter-0.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b9931fd36ee513c26b5bf08c940b0ac875de175341cbdd4fa3be109f0492586", size = 345553, upload-time = "2024-12-09T18:09:32.735Z" }, + { url = "https://files.pythonhosted.org/packages/44/a6/6d030003394e9659cd0d7136bbeabd82e869849ceccddc34d40abbbbb269/jiter-0.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0820f4a3a59ddced7fce696d86a096d5cc48d32a4183483a17671a61edfddc", size = 376388, upload-time = "2024-12-09T18:09:34.723Z" }, + { url = "https://files.pythonhosted.org/packages/ad/8d/87b09e648e4aca5f9af89e3ab3cfb93db2d1e633b2f2931ede8dabd9b19a/jiter-0.8.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ffc86ae5e3e6a93765d49d1ab47b6075a9c978a2b3b80f0f32628f39caa0c88", size = 511226, upload-time = "2024-12-09T18:09:36.13Z" }, + { url = "https://files.pythonhosted.org/packages/77/95/8008ebe4cdc82eac1c97864a8042ca7e383ed67e0ec17bfd03797045c727/jiter-0.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5127dc1abd809431172bc3fbe8168d6b90556a30bb10acd5ded41c3cfd6f43b6", size = 504134, upload-time = "2024-12-09T18:09:37.581Z" }, + { url = "https://files.pythonhosted.org/packages/26/0d/3056a74de13e8b2562e4d526de6dac2f65d91ace63a8234deb9284a1d24d/jiter-0.8.2-cp311-cp311-win32.whl", hash = "sha256:66227a2c7b575720c1871c8800d3a0122bb8ee94edb43a5685aa9aceb2782d44", size = 203103, upload-time = "2024-12-09T18:09:38.881Z" }, + { url = "https://files.pythonhosted.org/packages/4e/1e/7f96b798f356e531ffc0f53dd2f37185fac60fae4d6c612bbbd4639b90aa/jiter-0.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:cde031d8413842a1e7501e9129b8e676e62a657f8ec8166e18a70d94d4682855", size = 206717, upload-time = "2024-12-09T18:09:41.064Z" }, + { url = "https://files.pythonhosted.org/packages/a1/17/c8747af8ea4e045f57d6cfd6fc180752cab9bc3de0e8a0c9ca4e8af333b1/jiter-0.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:e6ec2be506e7d6f9527dae9ff4b7f54e68ea44a0ef6b098256ddf895218a2f8f", size = 302027, upload-time = "2024-12-09T18:09:43.11Z" }, + { url = "https://files.pythonhosted.org/packages/3c/c1/6da849640cd35a41e91085723b76acc818d4b7d92b0b6e5111736ce1dd10/jiter-0.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76e324da7b5da060287c54f2fabd3db5f76468006c811831f051942bf68c9d44", size = 310326, upload-time = "2024-12-09T18:09:44.426Z" }, + { url = "https://files.pythonhosted.org/packages/06/99/a2bf660d8ccffee9ad7ed46b4f860d2108a148d0ea36043fd16f4dc37e94/jiter-0.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:180a8aea058f7535d1c84183c0362c710f4750bef66630c05f40c93c2b152a0f", size = 334242, upload-time = "2024-12-09T18:09:45.915Z" }, + { url = "https://files.pythonhosted.org/packages/a7/5f/cea1c17864828731f11427b9d1ab7f24764dbd9aaf4648a7f851164d2718/jiter-0.8.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:025337859077b41548bdcbabe38698bcd93cfe10b06ff66617a48ff92c9aec60", size = 356654, upload-time = "2024-12-09T18:09:47.619Z" }, + { url = "https://files.pythonhosted.org/packages/e9/13/62774b7e5e7f5d5043efe1d0f94ead66e6d0f894ae010adb56b3f788de71/jiter-0.8.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecff0dc14f409599bbcafa7e470c00b80f17abc14d1405d38ab02e4b42e55b57", size = 379967, upload-time = "2024-12-09T18:09:49.987Z" }, + { url = "https://files.pythonhosted.org/packages/ec/fb/096b34c553bb0bd3f2289d5013dcad6074948b8d55212aa13a10d44c5326/jiter-0.8.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffd9fee7d0775ebaba131f7ca2e2d83839a62ad65e8e02fe2bd8fc975cedeb9e", size = 389252, upload-time = "2024-12-09T18:09:51.329Z" }, + { url = "https://files.pythonhosted.org/packages/17/61/beea645c0bf398ced8b199e377b61eb999d8e46e053bb285c91c3d3eaab0/jiter-0.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14601dcac4889e0a1c75ccf6a0e4baf70dbc75041e51bcf8d0e9274519df6887", size = 345490, upload-time = "2024-12-09T18:09:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/d5/df/834aa17ad5dcc3cf0118821da0a0cf1589ea7db9832589278553640366bc/jiter-0.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92249669925bc1c54fcd2ec73f70f2c1d6a817928480ee1c65af5f6b81cdf12d", size = 376991, upload-time = "2024-12-09T18:09:53.972Z" }, + { url = "https://files.pythonhosted.org/packages/67/80/87d140399d382fb4ea5b3d56e7ecaa4efdca17cd7411ff904c1517855314/jiter-0.8.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e725edd0929fa79f8349ab4ec7f81c714df51dc4e991539a578e5018fa4a7152", size = 510822, upload-time = "2024-12-09T18:09:55.439Z" }, + { url = "https://files.pythonhosted.org/packages/5c/37/3394bb47bac1ad2cb0465601f86828a0518d07828a650722e55268cdb7e6/jiter-0.8.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bf55846c7b7a680eebaf9c3c48d630e1bf51bdf76c68a5f654b8524335b0ad29", size = 503730, upload-time = "2024-12-09T18:09:59.494Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e2/253fc1fa59103bb4e3aa0665d6ceb1818df1cd7bf3eb492c4dad229b1cd4/jiter-0.8.2-cp312-cp312-win32.whl", hash = "sha256:7efe4853ecd3d6110301665a5178b9856be7e2a9485f49d91aa4d737ad2ae49e", size = 203375, upload-time = "2024-12-09T18:10:00.814Z" }, + { url = "https://files.pythonhosted.org/packages/41/69/6d4bbe66b3b3b4507e47aa1dd5d075919ad242b4b1115b3f80eecd443687/jiter-0.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:83c0efd80b29695058d0fd2fa8a556490dbce9804eac3e281f373bbc99045f6c", size = 204740, upload-time = "2024-12-09T18:10:02.146Z" }, + { url = "https://files.pythonhosted.org/packages/6c/b0/bfa1f6f2c956b948802ef5a021281978bf53b7a6ca54bb126fd88a5d014e/jiter-0.8.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ca1f08b8e43dc3bd0594c992fb1fd2f7ce87f7bf0d44358198d6da8034afdf84", size = 301190, upload-time = "2024-12-09T18:10:03.463Z" }, + { url = "https://files.pythonhosted.org/packages/a4/8f/396ddb4e292b5ea57e45ade5dc48229556b9044bad29a3b4b2dddeaedd52/jiter-0.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5672a86d55416ccd214c778efccf3266b84f87b89063b582167d803246354be4", size = 309334, upload-time = "2024-12-09T18:10:05.774Z" }, + { url = "https://files.pythonhosted.org/packages/7f/68/805978f2f446fa6362ba0cc2e4489b945695940656edd844e110a61c98f8/jiter-0.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58dc9bc9767a1101f4e5e22db1b652161a225874d66f0e5cb8e2c7d1c438b587", size = 333918, upload-time = "2024-12-09T18:10:07.158Z" }, + { url = "https://files.pythonhosted.org/packages/b3/99/0f71f7be667c33403fa9706e5b50583ae5106d96fab997fa7e2f38ee8347/jiter-0.8.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37b2998606d6dadbb5ccda959a33d6a5e853252d921fec1792fc902351bb4e2c", size = 356057, upload-time = "2024-12-09T18:10:09.341Z" }, + { url = "https://files.pythonhosted.org/packages/8d/50/a82796e421a22b699ee4d2ce527e5bcb29471a2351cbdc931819d941a167/jiter-0.8.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ab9a87f3784eb0e098f84a32670cfe4a79cb6512fd8f42ae3d0709f06405d18", size = 379790, upload-time = "2024-12-09T18:10:10.702Z" }, + { url = "https://files.pythonhosted.org/packages/3c/31/10fb012b00f6d83342ca9e2c9618869ab449f1aa78c8f1b2193a6b49647c/jiter-0.8.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79aec8172b9e3c6d05fd4b219d5de1ac616bd8da934107325a6c0d0e866a21b6", size = 388285, upload-time = "2024-12-09T18:10:12.721Z" }, + { url = "https://files.pythonhosted.org/packages/c8/81/f15ebf7de57be488aa22944bf4274962aca8092e4f7817f92ffa50d3ee46/jiter-0.8.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:711e408732d4e9a0208008e5892c2966b485c783cd2d9a681f3eb147cf36c7ef", size = 344764, upload-time = "2024-12-09T18:10:14.075Z" }, + { url = "https://files.pythonhosted.org/packages/b3/e8/0cae550d72b48829ba653eb348cdc25f3f06f8a62363723702ec18e7be9c/jiter-0.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:653cf462db4e8c41995e33d865965e79641ef45369d8a11f54cd30888b7e6ff1", size = 376620, upload-time = "2024-12-09T18:10:15.487Z" }, + { url = "https://files.pythonhosted.org/packages/b8/50/e5478ff9d82534a944c03b63bc217c5f37019d4a34d288db0f079b13c10b/jiter-0.8.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:9c63eaef32b7bebac8ebebf4dabebdbc6769a09c127294db6babee38e9f405b9", size = 510402, upload-time = "2024-12-09T18:10:17.499Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1e/3de48bbebbc8f7025bd454cedc8c62378c0e32dd483dece5f4a814a5cb55/jiter-0.8.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:eb21aaa9a200d0a80dacc7a81038d2e476ffe473ffdd9c91eb745d623561de05", size = 503018, upload-time = "2024-12-09T18:10:18.92Z" }, + { url = "https://files.pythonhosted.org/packages/d5/cd/d5a5501d72a11fe3e5fd65c78c884e5164eefe80077680533919be22d3a3/jiter-0.8.2-cp313-cp313-win32.whl", hash = "sha256:789361ed945d8d42850f919342a8665d2dc79e7e44ca1c97cc786966a21f627a", size = 203190, upload-time = "2024-12-09T18:10:20.801Z" }, + { url = "https://files.pythonhosted.org/packages/51/bf/e5ca301245ba951447e3ad677a02a64a8845b185de2603dabd83e1e4b9c6/jiter-0.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:ab7f43235d71e03b941c1630f4b6e3055d46b6cb8728a17663eaac9d8e83a865", size = 203551, upload-time = "2024-12-09T18:10:22.822Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3c/71a491952c37b87d127790dd7a0b1ebea0514c6b6ad30085b16bbe00aee6/jiter-0.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b426f72cd77da3fec300ed3bc990895e2dd6b49e3bfe6c438592a3ba660e41ca", size = 308347, upload-time = "2024-12-09T18:10:24.139Z" }, + { url = "https://files.pythonhosted.org/packages/a0/4c/c02408042e6a7605ec063daed138e07b982fdb98467deaaf1c90950cf2c6/jiter-0.8.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2dd880785088ff2ad21ffee205e58a8c1ddabc63612444ae41e5e4b321b39c0", size = 342875, upload-time = "2024-12-09T18:10:25.553Z" }, + { url = "https://files.pythonhosted.org/packages/91/61/c80ef80ed8a0a21158e289ef70dac01e351d929a1c30cb0f49be60772547/jiter-0.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:3ac9f578c46f22405ff7f8b1f5848fb753cc4b8377fbec8470a7dc3997ca7566", size = 202374, upload-time = "2024-12-09T18:10:26.958Z" }, ] [[package]] name = "jmespath" version = "1.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843 } +sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843, upload-time = "2022-06-17T18:00:12.224Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256 }, + { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256, upload-time = "2022-06-17T18:00:10.251Z" }, ] [[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 } +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 }, + { 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 = "json-repair" version = "0.46.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cb/74/f8e4eb4ce31be034c08fd3da37328c9ab7a7503831cf6f41d2121699cc88/json_repair-0.46.2.tar.gz", hash = "sha256:4c81154d61c028ca3750b451472dbb33978f2ee6f44be84c42b444b03d9f4b16", size = 33605 } +sdist = { url = "https://files.pythonhosted.org/packages/cb/74/f8e4eb4ce31be034c08fd3da37328c9ab7a7503831cf6f41d2121699cc88/json_repair-0.46.2.tar.gz", hash = "sha256:4c81154d61c028ca3750b451472dbb33978f2ee6f44be84c42b444b03d9f4b16", size = 33605, upload-time = "2025-06-06T08:05:48.46Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/d7/5f31df5ad00474f3005bbbac5f3a1e8d36535b40f1d352e6a5bd9880bf1f/json_repair-0.46.2-py3-none-any.whl", hash = "sha256:21fb339de583ab68db4272f984ec6fca9cc453d8117d9870e83c28b6b56c20e6", size = 22326 }, + { url = "https://files.pythonhosted.org/packages/8c/d7/5f31df5ad00474f3005bbbac5f3a1e8d36535b40f1d352e6a5bd9880bf1f/json_repair-0.46.2-py3-none-any.whl", hash = "sha256:21fb339de583ab68db4272f984ec6fca9cc453d8117d9870e83c28b6b56c20e6", size = 22326, upload-time = "2025-06-06T08:05:47.064Z" }, ] [[package]] name = "json5" version = "0.12.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/12/be/c6c745ec4c4539b25a278b70e29793f10382947df0d9efba2fa09120895d/json5-0.12.0.tar.gz", hash = "sha256:0b4b6ff56801a1c7dc817b0241bca4ce474a0e6a163bfef3fc594d3fd263ff3a", size = 51907 } +sdist = { url = "https://files.pythonhosted.org/packages/12/be/c6c745ec4c4539b25a278b70e29793f10382947df0d9efba2fa09120895d/json5-0.12.0.tar.gz", hash = "sha256:0b4b6ff56801a1c7dc817b0241bca4ce474a0e6a163bfef3fc594d3fd263ff3a", size = 51907, upload-time = "2025-04-03T16:33:13.201Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/9f/3500910d5a98549e3098807493851eeef2b89cdd3032227558a104dfe926/json5-0.12.0-py3-none-any.whl", hash = "sha256:6d37aa6c08b0609f16e1ec5ff94697e2cbbfbad5ac112afa05794da9ab7810db", size = 36079 }, + { url = "https://files.pythonhosted.org/packages/41/9f/3500910d5a98549e3098807493851eeef2b89cdd3032227558a104dfe926/json5-0.12.0-py3-none-any.whl", hash = "sha256:6d37aa6c08b0609f16e1ec5ff94697e2cbbfbad5ac112afa05794da9ab7810db", size = 36079, upload-time = "2025-04-03T16:33:11.927Z" }, ] [[package]] @@ -1796,36 +1870,36 @@ 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 } +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 }, + { 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 = "jsonpickle" version = "4.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e4/a6/d07afcfdef402900229bcca795f80506b207af13a838d4d99ad45abf530c/jsonpickle-4.1.1.tar.gz", hash = "sha256:f86e18f13e2b96c1c1eede0b7b90095bbb61d99fedc14813c44dc2f361dbbae1", size = 316885 } +sdist = { url = "https://files.pythonhosted.org/packages/e4/a6/d07afcfdef402900229bcca795f80506b207af13a838d4d99ad45abf530c/jsonpickle-4.1.1.tar.gz", hash = "sha256:f86e18f13e2b96c1c1eede0b7b90095bbb61d99fedc14813c44dc2f361dbbae1", size = 316885, upload-time = "2025-06-02T20:36:11.57Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/73/04df8a6fa66d43a9fd45c30f283cc4afff17da671886e451d52af60bdc7e/jsonpickle-4.1.1-py3-none-any.whl", hash = "sha256:bb141da6057898aa2438ff268362b126826c812a1721e31cf08a6e142910dc91", size = 47125 }, + { url = "https://files.pythonhosted.org/packages/c1/73/04df8a6fa66d43a9fd45c30f283cc4afff17da671886e451d52af60bdc7e/jsonpickle-4.1.1-py3-none-any.whl", hash = "sha256:bb141da6057898aa2438ff268362b126826c812a1721e31cf08a6e142910dc91", size = 47125, upload-time = "2025-06-02T20:36:08.647Z" }, ] [[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 } +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 }, + { 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 = "jsonref" version = "1.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/0d/c1f3277e90ccdb50d33ed5ba1ec5b3f0a242ed8c1b1a85d3afeb68464dca/jsonref-1.1.0.tar.gz", hash = "sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552", size = 8814 } +sdist = { url = "https://files.pythonhosted.org/packages/aa/0d/c1f3277e90ccdb50d33ed5ba1ec5b3f0a242ed8c1b1a85d3afeb68464dca/jsonref-1.1.0.tar.gz", hash = "sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552", size = 8814, upload-time = "2023-01-16T16:10:04.455Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/ec/e1db9922bceb168197a558a2b8c03a7963f1afe93517ddd3cf99f202f996/jsonref-1.1.0-py3-none-any.whl", hash = "sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9", size = 9425 }, + { url = "https://files.pythonhosted.org/packages/0c/ec/e1db9922bceb168197a558a2b8c03a7963f1afe93517ddd3cf99f202f996/jsonref-1.1.0-py3-none-any.whl", hash = "sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9", size = 9425, upload-time = "2023-01-16T16:10:02.255Z" }, ] [[package]] @@ -1838,9 +1912,9 @@ dependencies = [ { 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 } +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 }, + { 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]] @@ -1850,9 +1924,9 @@ 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 } +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 }, + { 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]] @@ -1872,9 +1946,9 @@ dependencies = [ { name = "urllib3" }, { name = "websocket-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/e8/0598f0e8b4af37cd9b10d8b87386cf3173cb8045d834ab5f6ec347a758b3/kubernetes-32.0.1.tar.gz", hash = "sha256:42f43d49abd437ada79a79a16bd48a604d3471a117a8347e87db693f2ba0ba28", size = 946691 } +sdist = { url = "https://files.pythonhosted.org/packages/b7/e8/0598f0e8b4af37cd9b10d8b87386cf3173cb8045d834ab5f6ec347a758b3/kubernetes-32.0.1.tar.gz", hash = "sha256:42f43d49abd437ada79a79a16bd48a604d3471a117a8347e87db693f2ba0ba28", size = 946691, upload-time = "2025-02-18T21:06:34.148Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/10/9f8af3e6f569685ce3af7faab51c8dd9d93b9c38eba339ca31c746119447/kubernetes-32.0.1-py2.py3-none-any.whl", hash = "sha256:35282ab8493b938b08ab5526c7ce66588232df00ef5e1dbe88a419107dc10998", size = 1988070 }, + { url = "https://files.pythonhosted.org/packages/08/10/9f8af3e6f569685ce3af7faab51c8dd9d93b9c38eba339ca31c746119447/kubernetes-32.0.1-py2.py3-none-any.whl", hash = "sha256:35282ab8493b938b08ab5526c7ce66588232df00ef5e1dbe88a419107dc10998", size = 1988070, upload-time = "2025-02-18T21:06:31.391Z" }, ] [[package]] @@ -1890,9 +1964,9 @@ dependencies = [ { name = "tenacity" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/40/89a80157f495d4adc9e5e770171806e3231600647f4ca0e89bdf743702ff/langchain_core-0.3.64.tar.gz", hash = "sha256:71b51bf77003eb57e74b8fa2a84ac380e24aa7357f173b51645c5834b9fc0d62", size = 558483 } +sdist = { url = "https://files.pythonhosted.org/packages/58/40/89a80157f495d4adc9e5e770171806e3231600647f4ca0e89bdf743702ff/langchain_core-0.3.64.tar.gz", hash = "sha256:71b51bf77003eb57e74b8fa2a84ac380e24aa7357f173b51645c5834b9fc0d62", size = 558483, upload-time = "2025-06-05T21:27:10.817Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/43/94b486eeb778443887e4eb76326e704ee0c6244f5fab6a46686e09968e9a/langchain_core-0.3.64-py3-none-any.whl", hash = "sha256:e844c425329d450cb3010001d86b61fd59a6a17691641109bae39322c85e27dd", size = 438113 }, + { url = "https://files.pythonhosted.org/packages/c3/43/94b486eeb778443887e4eb76326e704ee0c6244f5fab6a46686e09968e9a/langchain_core-0.3.64-py3-none-any.whl", hash = "sha256:e844c425329d450cb3010001d86b61fd59a6a17691641109bae39322c85e27dd", size = 438113, upload-time = "2025-06-05T21:27:07.981Z" }, ] [[package]] @@ -1908,9 +1982,9 @@ dependencies = [ { name = "requests-toolbelt" }, { name = "zstandard" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/be/86/b941012013260f95af2e90a3d9415af4a76a003a28412033fc4b09f35731/langsmith-0.3.45.tar.gz", hash = "sha256:1df3c6820c73ed210b2c7bc5cdb7bfa19ddc9126cd03fdf0da54e2e171e6094d", size = 348201 } +sdist = { url = "https://files.pythonhosted.org/packages/be/86/b941012013260f95af2e90a3d9415af4a76a003a28412033fc4b09f35731/langsmith-0.3.45.tar.gz", hash = "sha256:1df3c6820c73ed210b2c7bc5cdb7bfa19ddc9126cd03fdf0da54e2e171e6094d", size = 348201, upload-time = "2025-06-05T05:10:28.948Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/f4/c206c0888f8a506404cb4f16ad89593bdc2f70cf00de26a1a0a7a76ad7a3/langsmith-0.3.45-py3-none-any.whl", hash = "sha256:5b55f0518601fa65f3bb6b1a3100379a96aa7b3ed5e9380581615ba9c65ed8ed", size = 363002 }, + { url = "https://files.pythonhosted.org/packages/6a/f4/c206c0888f8a506404cb4f16ad89593bdc2f70cf00de26a1a0a7a76ad7a3/langsmith-0.3.45-py3-none-any.whl", hash = "sha256:5b55f0518601fa65f3bb6b1a3100379a96aa7b3ed5e9380581615ba9c65ed8ed", size = 363002, upload-time = "2025-06-05T05:10:27.228Z" }, ] [[package]] @@ -1930,9 +2004,9 @@ dependencies = [ { name = "tiktoken" }, { name = "tokenizers" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/22/138545b646303ca3f4841b69613c697b9d696322a1386083bb70bcbba60b/litellm-1.68.0.tar.gz", hash = "sha256:9fb24643db84dfda339b64bafca505a2eef857477afbc6e98fb56512c24dbbfa", size = 7314051 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/22/138545b646303ca3f4841b69613c697b9d696322a1386083bb70bcbba60b/litellm-1.68.0.tar.gz", hash = "sha256:9fb24643db84dfda339b64bafca505a2eef857477afbc6e98fb56512c24dbbfa", size = 7314051, upload-time = "2025-05-04T05:41:48.081Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/af/1e344bc8aee41445272e677d802b774b1f8b34bdc3bb5697ba30f0fb5d52/litellm-1.68.0-py3-none-any.whl", hash = "sha256:3bca38848b1a5236b11aa6b70afa4393b60880198c939e582273f51a542d4759", size = 7684460 }, + { url = "https://files.pythonhosted.org/packages/10/af/1e344bc8aee41445272e677d802b774b1f8b34bdc3bb5697ba30f0fb5d52/litellm-1.68.0-py3-none-any.whl", hash = "sha256:3bca38848b1a5236b11aa6b70afa4393b60880198c939e582273f51a542d4759", size = 7684460, upload-time = "2025-05-04T05:41:44.78Z" }, ] [[package]] @@ -1942,67 +2016,67 @@ 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 } +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 }, + { 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 = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 }, - { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 }, - { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 }, - { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 }, - { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 }, - { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 }, - { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 }, - { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 }, - { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, - { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, - { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, - { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, - { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, - { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, - { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, - { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, - { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, - { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, - { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, - { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357, upload-time = "2024-10-18T15:20:51.44Z" }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393, upload-time = "2024-10-18T15:20:52.426Z" }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732, upload-time = "2024-10-18T15:20:53.578Z" }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866, upload-time = "2024-10-18T15:20:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964, upload-time = "2024-10-18T15:20:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977, upload-time = "2024-10-18T15:20:57.189Z" }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366, upload-time = "2024-10-18T15:20:58.235Z" }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091, upload-time = "2024-10-18T15:20:59.235Z" }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065, upload-time = "2024-10-18T15:21:00.307Z" }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514, upload-time = "2024-10-18T15:21:01.122Z" }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, ] [[package]] @@ -2012,9 +2086,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159 } +sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899 }, + { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, ] [[package]] @@ -2034,9 +2108,9 @@ dependencies = [ { name = "starlette" }, { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/3c/82c400c2d50afdac4fbefb5b4031fd327e2ad1f23ccef8eee13c5909aa48/mcp-1.13.1.tar.gz", hash = "sha256:165306a8fd7991dc80334edd2de07798175a56461043b7ae907b279794a834c5", size = 438198 } +sdist = { url = "https://files.pythonhosted.org/packages/66/3c/82c400c2d50afdac4fbefb5b4031fd327e2ad1f23ccef8eee13c5909aa48/mcp-1.13.1.tar.gz", hash = "sha256:165306a8fd7991dc80334edd2de07798175a56461043b7ae907b279794a834c5", size = 438198, upload-time = "2025-08-22T09:22:16.061Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/19/3f/d085c7f49ade6d273b185d61ec9405e672b6433f710ea64a90135a8dd445/mcp-1.13.1-py3-none-any.whl", hash = "sha256:c314e7c8bd477a23ba3ef472ee5a32880316c42d03e06dcfa31a1cc7a73b65df", size = 161494 }, + { url = "https://files.pythonhosted.org/packages/19/3f/d085c7f49ade6d273b185d61ec9405e672b6433f710ea64a90135a8dd445/mcp-1.13.1-py3-none-any.whl", hash = "sha256:c314e7c8bd477a23ba3ef472ee5a32880316c42d03e06dcfa31a1cc7a73b65df", size = 161494, upload-time = "2025-08-22T09:22:14.705Z" }, ] [[package]] @@ -2105,6 +2179,9 @@ langchain = [ openai = [ { name = "openai" }, ] +redis = [ + { name = "redis", extra = ["hiredis"] }, +] temporal = [ { name = "temporalio", extra = ["opentelemetry"] }, ] @@ -2156,6 +2233,7 @@ requires-dist = [ { name = "pydantic-yaml", specifier = ">=1.5.1" }, { name = "pyjwt", marker = "extra == 'cli'", specifier = ">=2.10.1" }, { name = "pyyaml", specifier = ">=6.0.2" }, + { name = "redis", extras = ["hiredis"], marker = "extra == 'redis'", specifier = ">=5.0.4" }, { name = "rich", specifier = ">=13.9.4" }, { name = "scikit-learn", specifier = ">=1.6.0" }, { name = "temporalio", extras = ["opentelemetry"], marker = "extra == 'temporal'", specifier = ">=1.10.0" }, @@ -2164,7 +2242,7 @@ requires-dist = [ { name = "watchdog", marker = "extra == 'cli'", specifier = ">=6.0.0" }, { name = "websockets", specifier = ">=12.0" }, ] -provides-extras = ["temporal", "anthropic", "anthropic-bedrock", "anthropic-vertex", "bedrock", "openai", "azure", "google", "cohere", "langchain", "crewai", "cli"] +provides-extras = ["temporal", "anthropic", "anthropic-bedrock", "anthropic-vertex", "bedrock", "openai", "azure", "google", "cohere", "langchain", "redis", "crewai", "cli"] [package.metadata.requires-dev] dev = [ @@ -2185,99 +2263,99 @@ dev = [ 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 } +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 }, + { 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 } -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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/6f/1d/2efc3525fe6fdf8865972fcbb884bd1f4b0f923c19b80891cecf7e239fa5/mmh3-5.1.0-cp310-cp310-win32.whl", hash = "sha256:2e6c8dc3631a5e22007fbdb55e993b2dbce7985c14b25b572dd78403c2e79182", size = 40815 }, - { url = "https://files.pythonhosted.org/packages/38/b5/c8fbe707cb0fea77a6d2d58d497bc9b67aff80deb84d20feb34d8fdd8671/mmh3-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:e4e8c7ad5a4dddcfde35fd28ef96744c1ee0f9d9570108aa5f7e77cf9cfdf0bf", size = 41479 }, - { url = "https://files.pythonhosted.org/packages/a1/f1/663e16134f913fccfbcea5b300fb7dc1860d8f63dc71867b013eebc10aec/mmh3-5.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:45da549269883208912868a07d0364e1418d8292c4259ca11699ba1b2475bd26", size = 38883 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/6d/4c/26e1222aca65769280d5427a1ce5875ef4213449718c8f03958d0bf91070/mmh3-5.1.0-cp311-cp311-win32.whl", hash = "sha256:1e3554d8792387eac73c99c6eaea0b3f884e7130eb67986e11c403e4f9b6d372", size = 40810 }, - { url = "https://files.pythonhosted.org/packages/98/d5/424ba95062d1212ea615dc8debc8d57983f2242d5e6b82e458b89a117a1e/mmh3-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8ad777a48197882492af50bf3098085424993ce850bdda406a358b6ab74be759", size = 41476 }, - { url = "https://files.pythonhosted.org/packages/bd/08/0315ccaf087ba55bb19a6dd3b1e8acd491e74ce7f5f9c4aaa06a90d66441/mmh3-5.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f29dc4efd99bdd29fe85ed6c81915b17b2ef2cf853abf7213a48ac6fb3eaabe1", size = 38880 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/29/29/831ea8d4abe96cdb3e28b79eab49cac7f04f9c6b6e36bfc686197ddba09d/mmh3-5.1.0-cp312-cp312-win32.whl", hash = "sha256:1d6508504c531ab86c4424b5a5ff07c1132d063863339cf92f6657ff7a580f76", size = 40835 }, - { url = "https://files.pythonhosted.org/packages/12/dd/7cbc30153b73f08eeac43804c1dbc770538a01979b4094edbe1a4b8eb551/mmh3-5.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:aa75981fcdf3f21759d94f2c81b6a6e04a49dfbcdad88b152ba49b8e20544776", size = 41509 }, - { url = "https://files.pythonhosted.org/packages/80/9d/627375bab4c90dd066093fc2c9a26b86f87e26d980dbf71667b44cbee3eb/mmh3-5.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:a4c1a76808dfea47f7407a0b07aaff9087447ef6280716fd0783409b3088bb3c", size = 38888 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/23/fa/cbbb7fcd0e287a715f1cd28a10de94c0535bd94164e38b852abc18da28c6/mmh3-5.1.0-cp313-cp313-win32.whl", hash = "sha256:c65dbd12885a5598b70140d24de5839551af5a99b29f9804bb2484b29ef07692", size = 40828 }, - { url = "https://files.pythonhosted.org/packages/09/33/9fb90ef822f7b734955a63851907cf72f8a3f9d8eb3c5706bfa6772a2a77/mmh3-5.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:10db7765201fc65003fa998faa067417ef6283eb5f9bba8f323c48fd9c33e91f", size = 41504 }, - { url = "https://files.pythonhosted.org/packages/16/71/4ad9a42f2772793a03cb698f0fc42499f04e6e8d2560ba2f7da0fb059a8e/mmh3-5.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:b22fe2e54be81f6c07dcb36b96fa250fb72effe08aa52fbb83eade6e1e2d5fd7", size = 38890 }, +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 = "monotonic" version = "1.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ea/ca/8e91948b782ddfbd194f323e7e7d9ba12e5877addf04fb2bf8fca38e86ac/monotonic-1.6.tar.gz", hash = "sha256:3a55207bcfed53ddd5c5bae174524062935efed17792e9de2ad0205ce9ad63f7", size = 7615 } +sdist = { url = "https://files.pythonhosted.org/packages/ea/ca/8e91948b782ddfbd194f323e7e7d9ba12e5877addf04fb2bf8fca38e86ac/monotonic-1.6.tar.gz", hash = "sha256:3a55207bcfed53ddd5c5bae174524062935efed17792e9de2ad0205ce9ad63f7", size = 7615, upload-time = "2021-08-11T14:37:28.79Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/67/7e8406a29b6c45be7af7740456f7f37025f0506ae2e05fb9009a53946860/monotonic-1.6-py2.py3-none-any.whl", hash = "sha256:68687e19a14f11f26d140dd5c86f3dba4bf5df58003000ed467e0e2a69bca96c", size = 8154 }, + { url = "https://files.pythonhosted.org/packages/9a/67/7e8406a29b6c45be7af7740456f7f37025f0506ae2e05fb9009a53946860/monotonic-1.6-py2.py3-none-any.whl", hash = "sha256:68687e19a14f11f26d140dd5c86f3dba4bf5df58003000ed467e0e2a69bca96c", size = 8154, upload-time = "2021-04-09T21:58:05.122Z" }, ] [[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 } +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 }, + { 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]] @@ -2289,9 +2367,9 @@ dependencies = [ { name = "pyjwt", extra = ["crypto"] }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3f/90/81dcc50f0be11a8c4dcbae1a9f761a26e5f905231330a7cacc9f04ec4c61/msal-1.32.3.tar.gz", hash = "sha256:5eea038689c78a5a70ca8ecbe1245458b55a857bd096efb6989c69ba15985d35", size = 151449 } +sdist = { url = "https://files.pythonhosted.org/packages/3f/90/81dcc50f0be11a8c4dcbae1a9f761a26e5f905231330a7cacc9f04ec4c61/msal-1.32.3.tar.gz", hash = "sha256:5eea038689c78a5a70ca8ecbe1245458b55a857bd096efb6989c69ba15985d35", size = 151449, upload-time = "2025-04-25T13:12:34.204Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/bf/81516b9aac7fd867709984d08eb4db1d2e3fe1df795c8e442cde9b568962/msal-1.32.3-py3-none-any.whl", hash = "sha256:b2798db57760b1961b142f027ffb7c8169536bf77316e99a0df5c4aaebb11569", size = 115358 }, + { url = "https://files.pythonhosted.org/packages/04/bf/81516b9aac7fd867709984d08eb4db1d2e3fe1df795c8e442cde9b568962/msal-1.32.3-py3-none-any.whl", hash = "sha256:b2798db57760b1961b142f027ffb7c8169536bf77316e99a0df5c4aaebb11569", size = 115358, upload-time = "2025-04-25T13:12:33.034Z" }, ] [[package]] @@ -2301,9 +2379,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "msal" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/01/99/5d239b6156eddf761a636bded1118414d161bd6b7b37a9335549ed159396/msal_extensions-1.3.1.tar.gz", hash = "sha256:c5b0fd10f65ef62b5f1d62f4251d51cbcaf003fcedae8c91b040a488614be1a4", size = 23315 } +sdist = { url = "https://files.pythonhosted.org/packages/01/99/5d239b6156eddf761a636bded1118414d161bd6b7b37a9335549ed159396/msal_extensions-1.3.1.tar.gz", hash = "sha256:c5b0fd10f65ef62b5f1d62f4251d51cbcaf003fcedae8c91b040a488614be1a4", size = 23315, upload-time = "2025-03-14T23:51:03.902Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/75/bd9b7bb966668920f06b200e84454c8f3566b102183bc55c5473d96cb2b9/msal_extensions-1.3.1-py3-none-any.whl", hash = "sha256:96d3de4d034504e969ac5e85bae8106c8373b5c6568e4c8fa7af2eca9dbe6bca", size = 20583 }, + { url = "https://files.pythonhosted.org/packages/5e/75/bd9b7bb966668920f06b200e84454c8f3566b102183bc55c5473d96cb2b9/msal_extensions-1.3.1-py3-none-any.whl", hash = "sha256:96d3de4d034504e969ac5e85bae8106c8373b5c6568e4c8fa7af2eca9dbe6bca", size = 20583, upload-time = "2025-03-14T23:51:03.016Z" }, ] [[package]] @@ -2313,94 +2391,94 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/91/2f/a3470242707058fe856fe59241eee5635d79087100b7042a867368863a27/multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8", size = 90183 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/92/0926a5baafa164b5d0ade3cd7932be39310375d7e25c9d7ceca05cb26a45/multidict-6.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8adee3ac041145ffe4488ea73fa0a622b464cc25340d98be76924d0cda8545ff", size = 66052 }, - { url = "https://files.pythonhosted.org/packages/b2/54/8a857ae4f8f643ec444d91f419fdd49cc7a90a2ca0e42d86482b604b63bd/multidict-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b61e98c3e2a861035aaccd207da585bdcacef65fe01d7a0d07478efac005e028", size = 38867 }, - { url = "https://files.pythonhosted.org/packages/9e/5f/63add9069f945c19bc8b217ea6b0f8a1ad9382eab374bb44fae4354b3baf/multidict-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75493f28dbadecdbb59130e74fe935288813301a8554dc32f0c631b6bdcdf8b0", size = 38138 }, - { url = "https://files.pythonhosted.org/packages/97/8b/fbd9c0fc13966efdb4a47f5bcffff67a4f2a3189fbeead5766eaa4250b20/multidict-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffc3c6a37e048b5395ee235e4a2a0d639c2349dffa32d9367a42fc20d399772", size = 220433 }, - { url = "https://files.pythonhosted.org/packages/a9/c4/5132b2d75b3ea2daedb14d10f91028f09f74f5b4d373b242c1b8eec47571/multidict-6.4.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87cb72263946b301570b0f63855569a24ee8758aaae2cd182aae7d95fbc92ca7", size = 218059 }, - { url = "https://files.pythonhosted.org/packages/1a/70/f1e818c7a29b908e2d7b4fafb1d7939a41c64868e79de2982eea0a13193f/multidict-6.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bbf7bd39822fd07e3609b6b4467af4c404dd2b88ee314837ad1830a7f4a8299", size = 231120 }, - { url = "https://files.pythonhosted.org/packages/b4/7e/95a194d85f27d5ef9cbe48dff9ded722fc6d12fedf641ec6e1e680890be7/multidict-6.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1f7cbd4f1f44ddf5fd86a8675b7679176eae770f2fc88115d6dddb6cefb59bc", size = 227457 }, - { url = "https://files.pythonhosted.org/packages/25/2b/590ad220968d1babb42f265debe7be5c5c616df6c5688c995a06d8a9b025/multidict-6.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5ac9e5bfce0e6282e7f59ff7b7b9a74aa8e5c60d38186a4637f5aa764046ad", size = 219111 }, - { url = "https://files.pythonhosted.org/packages/e0/f0/b07682b995d3fb5313f339b59d7de02db19ba0c02d1f77c27bdf8212d17c/multidict-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4efc31dfef8c4eeb95b6b17d799eedad88c4902daba39ce637e23a17ea078915", size = 213012 }, - { url = "https://files.pythonhosted.org/packages/24/56/c77b5f36feef2ec92f1119756e468ac9c3eebc35aa8a4c9e51df664cbbc9/multidict-6.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9fcad2945b1b91c29ef2b4050f590bfcb68d8ac8e0995a74e659aa57e8d78e01", size = 225408 }, - { url = "https://files.pythonhosted.org/packages/cc/b3/e8189b82af9b198b47bc637766208fc917189eea91d674bad417e657bbdf/multidict-6.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d877447e7368c7320832acb7159557e49b21ea10ffeb135c1077dbbc0816b598", size = 214396 }, - { url = "https://files.pythonhosted.org/packages/20/e0/200d14c84e35ae13ee99fd65dc106e1a1acb87a301f15e906fc7d5b30c17/multidict-6.4.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:33a12ebac9f380714c298cbfd3e5b9c0c4e89c75fe612ae496512ee51028915f", size = 222237 }, - { url = "https://files.pythonhosted.org/packages/13/f3/bb3df40045ca8262694a3245298732ff431dc781414a89a6a364ebac6840/multidict-6.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0f14ea68d29b43a9bf37953881b1e3eb75b2739e896ba4a6aa4ad4c5b9ffa145", size = 231425 }, - { url = "https://files.pythonhosted.org/packages/85/3b/538563dc18514384dac169bcba938753ad9ab4d4c8d49b55d6ae49fb2579/multidict-6.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0327ad2c747a6600e4797d115d3c38a220fdb28e54983abe8964fd17e95ae83c", size = 226251 }, - { url = "https://files.pythonhosted.org/packages/56/79/77e1a65513f09142358f1beb1d4cbc06898590b34a7de2e47023e3c5a3a2/multidict-6.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d1a20707492db9719a05fc62ee215fd2c29b22b47c1b1ba347f9abc831e26683", size = 220363 }, - { url = "https://files.pythonhosted.org/packages/16/57/67b0516c3e348f8daaa79c369b3de4359a19918320ab82e2e586a1c624ef/multidict-6.4.4-cp310-cp310-win32.whl", hash = "sha256:d83f18315b9fca5db2452d1881ef20f79593c4aa824095b62cb280019ef7aa3d", size = 35175 }, - { url = "https://files.pythonhosted.org/packages/86/5a/4ed8fec642d113fa653777cda30ef67aa5c8a38303c091e24c521278a6c6/multidict-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:9c17341ee04545fd962ae07330cb5a39977294c883485c8d74634669b1f7fe04", size = 38678 }, - { url = "https://files.pythonhosted.org/packages/19/1b/4c6e638195851524a63972c5773c7737bea7e47b1ba402186a37773acee2/multidict-6.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4f5f29794ac0e73d2a06ac03fd18870adc0135a9d384f4a306a951188ed02f95", size = 65515 }, - { url = "https://files.pythonhosted.org/packages/25/d5/10e6bca9a44b8af3c7f920743e5fc0c2bcf8c11bf7a295d4cfe00b08fb46/multidict-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c04157266344158ebd57b7120d9b0b35812285d26d0e78193e17ef57bfe2979a", size = 38609 }, - { url = "https://files.pythonhosted.org/packages/26/b4/91fead447ccff56247edc7f0535fbf140733ae25187a33621771ee598a18/multidict-6.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb61ffd3ab8310d93427e460f565322c44ef12769f51f77277b4abad7b6f7223", size = 37871 }, - { url = "https://files.pythonhosted.org/packages/3b/37/cbc977cae59277e99d15bbda84cc53b5e0c4929ffd91d958347200a42ad0/multidict-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e0ba18a9afd495f17c351d08ebbc4284e9c9f7971d715f196b79636a4d0de44", size = 226661 }, - { url = "https://files.pythonhosted.org/packages/15/cd/7e0b57fbd4dc2fc105169c4ecce5be1a63970f23bb4ec8c721b67e11953d/multidict-6.4.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9faf1b1dcaadf9f900d23a0e6d6c8eadd6a95795a0e57fcca73acce0eb912065", size = 223422 }, - { url = "https://files.pythonhosted.org/packages/f1/01/1de268da121bac9f93242e30cd3286f6a819e5f0b8896511162d6ed4bf8d/multidict-6.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a4d1cb1327c6082c4fce4e2a438483390964c02213bc6b8d782cf782c9b1471f", size = 235447 }, - { url = "https://files.pythonhosted.org/packages/d2/8c/8b9a5e4aaaf4f2de14e86181a3a3d7b105077f668b6a06f043ec794f684c/multidict-6.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:941f1bec2f5dbd51feeb40aea654c2747f811ab01bdd3422a48a4e4576b7d76a", size = 231455 }, - { url = "https://files.pythonhosted.org/packages/35/db/e1817dcbaa10b319c412769cf999b1016890849245d38905b73e9c286862/multidict-6.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5f8a146184da7ea12910a4cec51ef85e44f6268467fb489c3caf0cd512f29c2", size = 223666 }, - { url = "https://files.pythonhosted.org/packages/4a/e1/66e8579290ade8a00e0126b3d9a93029033ffd84f0e697d457ed1814d0fc/multidict-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:232b7237e57ec3c09be97206bfb83a0aa1c5d7d377faa019c68a210fa35831f1", size = 217392 }, - { url = "https://files.pythonhosted.org/packages/7b/6f/f8639326069c24a48c7747c2a5485d37847e142a3f741ff3340c88060a9a/multidict-6.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:55ae0721c1513e5e3210bca4fc98456b980b0c2c016679d3d723119b6b202c42", size = 228969 }, - { url = "https://files.pythonhosted.org/packages/d2/c3/3d58182f76b960eeade51c89fcdce450f93379340457a328e132e2f8f9ed/multidict-6.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:51d662c072579f63137919d7bb8fc250655ce79f00c82ecf11cab678f335062e", size = 217433 }, - { url = "https://files.pythonhosted.org/packages/e1/4b/f31a562906f3bd375f3d0e83ce314e4a660c01b16c2923e8229b53fba5d7/multidict-6.4.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0e05c39962baa0bb19a6b210e9b1422c35c093b651d64246b6c2e1a7e242d9fd", size = 225418 }, - { url = "https://files.pythonhosted.org/packages/99/89/78bb95c89c496d64b5798434a3deee21996114d4d2c28dd65850bf3a691e/multidict-6.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5b1cc3ab8c31d9ebf0faa6e3540fb91257590da330ffe6d2393d4208e638925", size = 235042 }, - { url = "https://files.pythonhosted.org/packages/74/91/8780a6e5885a8770442a8f80db86a0887c4becca0e5a2282ba2cae702bc4/multidict-6.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93ec84488a384cd7b8a29c2c7f467137d8a73f6fe38bb810ecf29d1ade011a7c", size = 230280 }, - { url = "https://files.pythonhosted.org/packages/68/c1/fcf69cabd542eb6f4b892469e033567ee6991d361d77abdc55e3a0f48349/multidict-6.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b308402608493638763abc95f9dc0030bbd6ac6aff784512e8ac3da73a88af08", size = 223322 }, - { url = "https://files.pythonhosted.org/packages/b8/85/5b80bf4b83d8141bd763e1d99142a9cdfd0db83f0739b4797172a4508014/multidict-6.4.4-cp311-cp311-win32.whl", hash = "sha256:343892a27d1a04d6ae455ecece12904d242d299ada01633d94c4f431d68a8c49", size = 35070 }, - { url = "https://files.pythonhosted.org/packages/09/66/0bed198ffd590ab86e001f7fa46b740d58cf8ff98c2f254e4a36bf8861ad/multidict-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:73484a94f55359780c0f458bbd3c39cb9cf9c182552177d2136e828269dee529", size = 38667 }, - { url = "https://files.pythonhosted.org/packages/d2/b5/5675377da23d60875fe7dae6be841787755878e315e2f517235f22f59e18/multidict-6.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc388f75a1c00000824bf28b7633e40854f4127ede80512b44c3cfeeea1839a2", size = 64293 }, - { url = "https://files.pythonhosted.org/packages/34/a7/be384a482754bb8c95d2bbe91717bf7ccce6dc38c18569997a11f95aa554/multidict-6.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:98af87593a666f739d9dba5d0ae86e01b0e1a9cfcd2e30d2d361fbbbd1a9162d", size = 38096 }, - { url = "https://files.pythonhosted.org/packages/66/6d/d59854bb4352306145bdfd1704d210731c1bb2c890bfee31fb7bbc1c4c7f/multidict-6.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aff4cafea2d120327d55eadd6b7f1136a8e5a0ecf6fb3b6863e8aca32cd8e50a", size = 37214 }, - { url = "https://files.pythonhosted.org/packages/99/e0/c29d9d462d7cfc5fc8f9bf24f9c6843b40e953c0b55e04eba2ad2cf54fba/multidict-6.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169c4ba7858176b797fe551d6e99040c531c775d2d57b31bcf4de6d7a669847f", size = 224686 }, - { url = "https://files.pythonhosted.org/packages/dc/4a/da99398d7fd8210d9de068f9a1b5f96dfaf67d51e3f2521f17cba4ee1012/multidict-6.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9eb4c59c54421a32b3273d4239865cb14ead53a606db066d7130ac80cc8ec93", size = 231061 }, - { url = "https://files.pythonhosted.org/packages/21/f5/ac11add39a0f447ac89353e6ca46666847051103649831c08a2800a14455/multidict-6.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cf3bd54c56aa16fdb40028d545eaa8d051402b61533c21e84046e05513d5780", size = 232412 }, - { url = "https://files.pythonhosted.org/packages/d9/11/4b551e2110cded705a3c13a1d4b6a11f73891eb5a1c449f1b2b6259e58a6/multidict-6.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f682c42003c7264134bfe886376299db4cc0c6cd06a3295b41b347044bcb5482", size = 231563 }, - { url = "https://files.pythonhosted.org/packages/4c/02/751530c19e78fe73b24c3da66618eda0aa0d7f6e7aa512e46483de6be210/multidict-6.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920f9cf2abdf6e493c519492d892c362007f113c94da4c239ae88429835bad1", size = 223811 }, - { url = "https://files.pythonhosted.org/packages/c7/cb/2be8a214643056289e51ca356026c7b2ce7225373e7a1f8c8715efee8988/multidict-6.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:530d86827a2df6504526106b4c104ba19044594f8722d3e87714e847c74a0275", size = 216524 }, - { url = "https://files.pythonhosted.org/packages/19/f3/6d5011ec375c09081f5250af58de85f172bfcaafebff286d8089243c4bd4/multidict-6.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecde56ea2439b96ed8a8d826b50c57364612ddac0438c39e473fafad7ae1c23b", size = 229012 }, - { url = "https://files.pythonhosted.org/packages/67/9c/ca510785df5cf0eaf5b2a8132d7d04c1ce058dcf2c16233e596ce37a7f8e/multidict-6.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:dc8c9736d8574b560634775ac0def6bdc1661fc63fa27ffdfc7264c565bcb4f2", size = 226765 }, - { url = "https://files.pythonhosted.org/packages/36/c8/ca86019994e92a0f11e642bda31265854e6ea7b235642f0477e8c2e25c1f/multidict-6.4.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7f3d3b3c34867579ea47cbd6c1f2ce23fbfd20a273b6f9e3177e256584f1eacc", size = 222888 }, - { url = "https://files.pythonhosted.org/packages/c6/67/bc25a8e8bd522935379066950ec4e2277f9b236162a73548a2576d4b9587/multidict-6.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87a728af265e08f96b6318ebe3c0f68b9335131f461efab2fc64cc84a44aa6ed", size = 234041 }, - { url = "https://files.pythonhosted.org/packages/f1/a0/70c4c2d12857fccbe607b334b7ee28b6b5326c322ca8f73ee54e70d76484/multidict-6.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9f193eeda1857f8e8d3079a4abd258f42ef4a4bc87388452ed1e1c4d2b0c8740", size = 231046 }, - { url = "https://files.pythonhosted.org/packages/c1/0f/52954601d02d39742aab01d6b92f53c1dd38b2392248154c50797b4df7f1/multidict-6.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be06e73c06415199200e9a2324a11252a3d62030319919cde5e6950ffeccf72e", size = 227106 }, - { url = "https://files.pythonhosted.org/packages/af/24/679d83ec4379402d28721790dce818e5d6b9f94ce1323a556fb17fa9996c/multidict-6.4.4-cp312-cp312-win32.whl", hash = "sha256:622f26ea6a7e19b7c48dd9228071f571b2fbbd57a8cd71c061e848f281550e6b", size = 35351 }, - { url = "https://files.pythonhosted.org/packages/52/ef/40d98bc5f986f61565f9b345f102409534e29da86a6454eb6b7c00225a13/multidict-6.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:5e2bcda30d5009996ff439e02a9f2b5c3d64a20151d34898c000a6281faa3781", size = 38791 }, - { url = "https://files.pythonhosted.org/packages/df/2a/e166d2ffbf4b10131b2d5b0e458f7cee7d986661caceae0de8753042d4b2/multidict-6.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:82ffabefc8d84c2742ad19c37f02cde5ec2a1ee172d19944d380f920a340e4b9", size = 64123 }, - { url = "https://files.pythonhosted.org/packages/8c/96/e200e379ae5b6f95cbae472e0199ea98913f03d8c9a709f42612a432932c/multidict-6.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6a2f58a66fe2c22615ad26156354005391e26a2f3721c3621504cd87c1ea87bf", size = 38049 }, - { url = "https://files.pythonhosted.org/packages/75/fb/47afd17b83f6a8c7fa863c6d23ac5ba6a0e6145ed8a6bcc8da20b2b2c1d2/multidict-6.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5883d6ee0fd9d8a48e9174df47540b7545909841ac82354c7ae4cbe9952603bd", size = 37078 }, - { url = "https://files.pythonhosted.org/packages/fa/70/1af3143000eddfb19fd5ca5e78393985ed988ac493bb859800fe0914041f/multidict-6.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9abcf56a9511653fa1d052bfc55fbe53dbee8f34e68bd6a5a038731b0ca42d15", size = 224097 }, - { url = "https://files.pythonhosted.org/packages/b1/39/d570c62b53d4fba844e0378ffbcd02ac25ca423d3235047013ba2f6f60f8/multidict-6.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6ed5ae5605d4ad5a049fad2a28bb7193400700ce2f4ae484ab702d1e3749c3f9", size = 230768 }, - { url = "https://files.pythonhosted.org/packages/fd/f8/ed88f2c4d06f752b015933055eb291d9bc184936903752c66f68fb3c95a7/multidict-6.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbfcb60396f9bcfa63e017a180c3105b8c123a63e9d1428a36544e7d37ca9e20", size = 231331 }, - { url = "https://files.pythonhosted.org/packages/9c/6f/8e07cffa32f483ab887b0d56bbd8747ac2c1acd00dc0af6fcf265f4a121e/multidict-6.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0f1987787f5f1e2076b59692352ab29a955b09ccc433c1f6b8e8e18666f608b", size = 230169 }, - { url = "https://files.pythonhosted.org/packages/e6/2b/5dcf173be15e42f330110875a2668ddfc208afc4229097312212dc9c1236/multidict-6.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0121ccce8c812047d8d43d691a1ad7641f72c4f730474878a5aeae1b8ead8c", size = 222947 }, - { url = "https://files.pythonhosted.org/packages/39/75/4ddcbcebe5ebcd6faa770b629260d15840a5fc07ce8ad295a32e14993726/multidict-6.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ec4967114295b8afd120a8eec579920c882831a3e4c3331d591a8e5bfbbc0f", size = 215761 }, - { url = "https://files.pythonhosted.org/packages/6a/c9/55e998ae45ff15c5608e384206aa71a11e1b7f48b64d166db400b14a3433/multidict-6.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:995f985e2e268deaf17867801b859a282e0448633f1310e3704b30616d269d69", size = 227605 }, - { url = "https://files.pythonhosted.org/packages/04/49/c2404eac74497503c77071bd2e6f88c7e94092b8a07601536b8dbe99be50/multidict-6.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d832c608f94b9f92a0ec8b7e949be7792a642b6e535fcf32f3e28fab69eeb046", size = 226144 }, - { url = "https://files.pythonhosted.org/packages/62/c5/0cd0c3c6f18864c40846aa2252cd69d308699cb163e1c0d989ca301684da/multidict-6.4.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d21c1212171cf7da703c5b0b7a0e85be23b720818aef502ad187d627316d5645", size = 221100 }, - { url = "https://files.pythonhosted.org/packages/71/7b/f2f3887bea71739a046d601ef10e689528d4f911d84da873b6be9194ffea/multidict-6.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cbebaa076aaecad3d4bb4c008ecc73b09274c952cf6a1b78ccfd689e51f5a5b0", size = 232731 }, - { url = "https://files.pythonhosted.org/packages/e5/b3/d9de808349df97fa75ec1372758701b5800ebad3c46ae377ad63058fbcc6/multidict-6.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c93a6fb06cc8e5d3628b2b5fda215a5db01e8f08fc15fadd65662d9b857acbe4", size = 229637 }, - { url = "https://files.pythonhosted.org/packages/5e/57/13207c16b615eb4f1745b44806a96026ef8e1b694008a58226c2d8f5f0a5/multidict-6.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8cd8f81f1310182362fb0c7898145ea9c9b08a71081c5963b40ee3e3cac589b1", size = 225594 }, - { url = "https://files.pythonhosted.org/packages/3a/e4/d23bec2f70221604f5565000632c305fc8f25ba953e8ce2d8a18842b9841/multidict-6.4.4-cp313-cp313-win32.whl", hash = "sha256:3e9f1cd61a0ab857154205fb0b1f3d3ace88d27ebd1409ab7af5096e409614cd", size = 35359 }, - { url = "https://files.pythonhosted.org/packages/a7/7a/cfe1a47632be861b627f46f642c1d031704cc1c0f5c0efbde2ad44aa34bd/multidict-6.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:8ffb40b74400e4455785c2fa37eba434269149ec525fc8329858c862e4b35373", size = 38903 }, - { url = "https://files.pythonhosted.org/packages/68/7b/15c259b0ab49938a0a1c8f3188572802704a779ddb294edc1b2a72252e7c/multidict-6.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6a602151dbf177be2450ef38966f4be3467d41a86c6a845070d12e17c858a156", size = 68895 }, - { url = "https://files.pythonhosted.org/packages/f1/7d/168b5b822bccd88142e0a3ce985858fea612404edd228698f5af691020c9/multidict-6.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d2b9712211b860d123815a80b859075d86a4d54787e247d7fbee9db6832cf1c", size = 40183 }, - { url = "https://files.pythonhosted.org/packages/e0/b7/d4b8d98eb850ef28a4922ba508c31d90715fd9b9da3801a30cea2967130b/multidict-6.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d2fa86af59f8fc1972e121ade052145f6da22758f6996a197d69bb52f8204e7e", size = 39592 }, - { url = "https://files.pythonhosted.org/packages/18/28/a554678898a19583548e742080cf55d169733baf57efc48c2f0273a08583/multidict-6.4.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50855d03e9e4d66eab6947ba688ffb714616f985838077bc4b490e769e48da51", size = 226071 }, - { url = "https://files.pythonhosted.org/packages/ee/dc/7ba6c789d05c310e294f85329efac1bf5b450338d2542498db1491a264df/multidict-6.4.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5bce06b83be23225be1905dcdb6b789064fae92499fbc458f59a8c0e68718601", size = 222597 }, - { url = "https://files.pythonhosted.org/packages/24/4f/34eadbbf401b03768dba439be0fb94b0d187facae9142821a3d5599ccb3b/multidict-6.4.4-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66ed0731f8e5dfd8369a883b6e564aca085fb9289aacabd9decd70568b9a30de", size = 228253 }, - { url = "https://files.pythonhosted.org/packages/c0/e6/493225a3cdb0d8d80d43a94503fc313536a07dae54a3f030d279e629a2bc/multidict-6.4.4-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329ae97fc2f56f44d91bc47fe0972b1f52d21c4b7a2ac97040da02577e2daca2", size = 226146 }, - { url = "https://files.pythonhosted.org/packages/2f/70/e411a7254dc3bff6f7e6e004303b1b0591358e9f0b7c08639941e0de8bd6/multidict-6.4.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c27e5dcf520923d6474d98b96749e6805f7677e93aaaf62656005b8643f907ab", size = 220585 }, - { url = "https://files.pythonhosted.org/packages/08/8f/beb3ae7406a619100d2b1fb0022c3bb55a8225ab53c5663648ba50dfcd56/multidict-6.4.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:058cc59b9e9b143cc56715e59e22941a5d868c322242278d28123a5d09cdf6b0", size = 212080 }, - { url = "https://files.pythonhosted.org/packages/9c/ec/355124e9d3d01cf8edb072fd14947220f357e1c5bc79c88dff89297e9342/multidict-6.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:69133376bc9a03f8c47343d33f91f74a99c339e8b58cea90433d8e24bb298031", size = 226558 }, - { url = "https://files.pythonhosted.org/packages/fd/22/d2b95cbebbc2ada3be3812ea9287dcc9712d7f1a012fad041770afddb2ad/multidict-6.4.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d6b15c55721b1b115c5ba178c77104123745b1417527ad9641a4c5e2047450f0", size = 212168 }, - { url = "https://files.pythonhosted.org/packages/4d/c5/62bfc0b2f9ce88326dbe7179f9824a939c6c7775b23b95de777267b9725c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a887b77f51d3d41e6e1a63cf3bc7ddf24de5939d9ff69441387dfefa58ac2e26", size = 217970 }, - { url = "https://files.pythonhosted.org/packages/79/74/977cea1aadc43ff1c75d23bd5bc4768a8fac98c14e5878d6ee8d6bab743c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:632a3bf8f1787f7ef7d3c2f68a7bde5be2f702906f8b5842ad6da9d974d0aab3", size = 226980 }, - { url = "https://files.pythonhosted.org/packages/48/fc/cc4a1a2049df2eb84006607dc428ff237af38e0fcecfdb8a29ca47b1566c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a145c550900deb7540973c5cdb183b0d24bed6b80bf7bddf33ed8f569082535e", size = 220641 }, - { url = "https://files.pythonhosted.org/packages/3b/6a/a7444d113ab918701988d4abdde373dbdfd2def7bd647207e2bf645c7eac/multidict-6.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc5d83c6619ca5c9672cb78b39ed8542f1975a803dee2cda114ff73cbb076edd", size = 221728 }, - { url = "https://files.pythonhosted.org/packages/2b/b0/fdf4c73ad1c55e0f4dbbf2aa59dd37037334091f9a4961646d2b7ac91a86/multidict-6.4.4-cp313-cp313t-win32.whl", hash = "sha256:3312f63261b9df49be9d57aaa6abf53a6ad96d93b24f9cc16cf979956355ce6e", size = 41913 }, - { url = "https://files.pythonhosted.org/packages/8e/92/27989ecca97e542c0d01d05a98a5ae12198a243a9ee12563a0313291511f/multidict-6.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:ba852168d814b2c73333073e1c7116d9395bea69575a01b0b3c89d2d5a87c8fb", size = 46112 }, - { url = "https://files.pythonhosted.org/packages/84/5d/e17845bb0fa76334477d5de38654d27946d5b5d3695443987a094a71b440/multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac", size = 10481 }, +sdist = { url = "https://files.pythonhosted.org/packages/91/2f/a3470242707058fe856fe59241eee5635d79087100b7042a867368863a27/multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8", size = 90183, upload-time = "2025-05-19T14:16:37.381Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/92/0926a5baafa164b5d0ade3cd7932be39310375d7e25c9d7ceca05cb26a45/multidict-6.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8adee3ac041145ffe4488ea73fa0a622b464cc25340d98be76924d0cda8545ff", size = 66052, upload-time = "2025-05-19T14:13:49.944Z" }, + { url = "https://files.pythonhosted.org/packages/b2/54/8a857ae4f8f643ec444d91f419fdd49cc7a90a2ca0e42d86482b604b63bd/multidict-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b61e98c3e2a861035aaccd207da585bdcacef65fe01d7a0d07478efac005e028", size = 38867, upload-time = "2025-05-19T14:13:51.92Z" }, + { url = "https://files.pythonhosted.org/packages/9e/5f/63add9069f945c19bc8b217ea6b0f8a1ad9382eab374bb44fae4354b3baf/multidict-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75493f28dbadecdbb59130e74fe935288813301a8554dc32f0c631b6bdcdf8b0", size = 38138, upload-time = "2025-05-19T14:13:53.778Z" }, + { url = "https://files.pythonhosted.org/packages/97/8b/fbd9c0fc13966efdb4a47f5bcffff67a4f2a3189fbeead5766eaa4250b20/multidict-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffc3c6a37e048b5395ee235e4a2a0d639c2349dffa32d9367a42fc20d399772", size = 220433, upload-time = "2025-05-19T14:13:55.346Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c4/5132b2d75b3ea2daedb14d10f91028f09f74f5b4d373b242c1b8eec47571/multidict-6.4.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87cb72263946b301570b0f63855569a24ee8758aaae2cd182aae7d95fbc92ca7", size = 218059, upload-time = "2025-05-19T14:13:56.993Z" }, + { url = "https://files.pythonhosted.org/packages/1a/70/f1e818c7a29b908e2d7b4fafb1d7939a41c64868e79de2982eea0a13193f/multidict-6.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bbf7bd39822fd07e3609b6b4467af4c404dd2b88ee314837ad1830a7f4a8299", size = 231120, upload-time = "2025-05-19T14:13:58.333Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/95a194d85f27d5ef9cbe48dff9ded722fc6d12fedf641ec6e1e680890be7/multidict-6.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1f7cbd4f1f44ddf5fd86a8675b7679176eae770f2fc88115d6dddb6cefb59bc", size = 227457, upload-time = "2025-05-19T14:13:59.663Z" }, + { url = "https://files.pythonhosted.org/packages/25/2b/590ad220968d1babb42f265debe7be5c5c616df6c5688c995a06d8a9b025/multidict-6.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5ac9e5bfce0e6282e7f59ff7b7b9a74aa8e5c60d38186a4637f5aa764046ad", size = 219111, upload-time = "2025-05-19T14:14:01.019Z" }, + { url = "https://files.pythonhosted.org/packages/e0/f0/b07682b995d3fb5313f339b59d7de02db19ba0c02d1f77c27bdf8212d17c/multidict-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4efc31dfef8c4eeb95b6b17d799eedad88c4902daba39ce637e23a17ea078915", size = 213012, upload-time = "2025-05-19T14:14:02.396Z" }, + { url = "https://files.pythonhosted.org/packages/24/56/c77b5f36feef2ec92f1119756e468ac9c3eebc35aa8a4c9e51df664cbbc9/multidict-6.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9fcad2945b1b91c29ef2b4050f590bfcb68d8ac8e0995a74e659aa57e8d78e01", size = 225408, upload-time = "2025-05-19T14:14:04.826Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b3/e8189b82af9b198b47bc637766208fc917189eea91d674bad417e657bbdf/multidict-6.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d877447e7368c7320832acb7159557e49b21ea10ffeb135c1077dbbc0816b598", size = 214396, upload-time = "2025-05-19T14:14:06.187Z" }, + { url = "https://files.pythonhosted.org/packages/20/e0/200d14c84e35ae13ee99fd65dc106e1a1acb87a301f15e906fc7d5b30c17/multidict-6.4.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:33a12ebac9f380714c298cbfd3e5b9c0c4e89c75fe612ae496512ee51028915f", size = 222237, upload-time = "2025-05-19T14:14:07.778Z" }, + { url = "https://files.pythonhosted.org/packages/13/f3/bb3df40045ca8262694a3245298732ff431dc781414a89a6a364ebac6840/multidict-6.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0f14ea68d29b43a9bf37953881b1e3eb75b2739e896ba4a6aa4ad4c5b9ffa145", size = 231425, upload-time = "2025-05-19T14:14:09.516Z" }, + { url = "https://files.pythonhosted.org/packages/85/3b/538563dc18514384dac169bcba938753ad9ab4d4c8d49b55d6ae49fb2579/multidict-6.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0327ad2c747a6600e4797d115d3c38a220fdb28e54983abe8964fd17e95ae83c", size = 226251, upload-time = "2025-05-19T14:14:10.82Z" }, + { url = "https://files.pythonhosted.org/packages/56/79/77e1a65513f09142358f1beb1d4cbc06898590b34a7de2e47023e3c5a3a2/multidict-6.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d1a20707492db9719a05fc62ee215fd2c29b22b47c1b1ba347f9abc831e26683", size = 220363, upload-time = "2025-05-19T14:14:12.638Z" }, + { url = "https://files.pythonhosted.org/packages/16/57/67b0516c3e348f8daaa79c369b3de4359a19918320ab82e2e586a1c624ef/multidict-6.4.4-cp310-cp310-win32.whl", hash = "sha256:d83f18315b9fca5db2452d1881ef20f79593c4aa824095b62cb280019ef7aa3d", size = 35175, upload-time = "2025-05-19T14:14:14.805Z" }, + { url = "https://files.pythonhosted.org/packages/86/5a/4ed8fec642d113fa653777cda30ef67aa5c8a38303c091e24c521278a6c6/multidict-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:9c17341ee04545fd962ae07330cb5a39977294c883485c8d74634669b1f7fe04", size = 38678, upload-time = "2025-05-19T14:14:16.949Z" }, + { url = "https://files.pythonhosted.org/packages/19/1b/4c6e638195851524a63972c5773c7737bea7e47b1ba402186a37773acee2/multidict-6.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4f5f29794ac0e73d2a06ac03fd18870adc0135a9d384f4a306a951188ed02f95", size = 65515, upload-time = "2025-05-19T14:14:19.767Z" }, + { url = "https://files.pythonhosted.org/packages/25/d5/10e6bca9a44b8af3c7f920743e5fc0c2bcf8c11bf7a295d4cfe00b08fb46/multidict-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c04157266344158ebd57b7120d9b0b35812285d26d0e78193e17ef57bfe2979a", size = 38609, upload-time = "2025-05-19T14:14:21.538Z" }, + { url = "https://files.pythonhosted.org/packages/26/b4/91fead447ccff56247edc7f0535fbf140733ae25187a33621771ee598a18/multidict-6.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb61ffd3ab8310d93427e460f565322c44ef12769f51f77277b4abad7b6f7223", size = 37871, upload-time = "2025-05-19T14:14:22.666Z" }, + { url = "https://files.pythonhosted.org/packages/3b/37/cbc977cae59277e99d15bbda84cc53b5e0c4929ffd91d958347200a42ad0/multidict-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e0ba18a9afd495f17c351d08ebbc4284e9c9f7971d715f196b79636a4d0de44", size = 226661, upload-time = "2025-05-19T14:14:24.124Z" }, + { url = "https://files.pythonhosted.org/packages/15/cd/7e0b57fbd4dc2fc105169c4ecce5be1a63970f23bb4ec8c721b67e11953d/multidict-6.4.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9faf1b1dcaadf9f900d23a0e6d6c8eadd6a95795a0e57fcca73acce0eb912065", size = 223422, upload-time = "2025-05-19T14:14:25.437Z" }, + { url = "https://files.pythonhosted.org/packages/f1/01/1de268da121bac9f93242e30cd3286f6a819e5f0b8896511162d6ed4bf8d/multidict-6.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a4d1cb1327c6082c4fce4e2a438483390964c02213bc6b8d782cf782c9b1471f", size = 235447, upload-time = "2025-05-19T14:14:26.793Z" }, + { url = "https://files.pythonhosted.org/packages/d2/8c/8b9a5e4aaaf4f2de14e86181a3a3d7b105077f668b6a06f043ec794f684c/multidict-6.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:941f1bec2f5dbd51feeb40aea654c2747f811ab01bdd3422a48a4e4576b7d76a", size = 231455, upload-time = "2025-05-19T14:14:28.149Z" }, + { url = "https://files.pythonhosted.org/packages/35/db/e1817dcbaa10b319c412769cf999b1016890849245d38905b73e9c286862/multidict-6.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5f8a146184da7ea12910a4cec51ef85e44f6268467fb489c3caf0cd512f29c2", size = 223666, upload-time = "2025-05-19T14:14:29.584Z" }, + { url = "https://files.pythonhosted.org/packages/4a/e1/66e8579290ade8a00e0126b3d9a93029033ffd84f0e697d457ed1814d0fc/multidict-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:232b7237e57ec3c09be97206bfb83a0aa1c5d7d377faa019c68a210fa35831f1", size = 217392, upload-time = "2025-05-19T14:14:30.961Z" }, + { url = "https://files.pythonhosted.org/packages/7b/6f/f8639326069c24a48c7747c2a5485d37847e142a3f741ff3340c88060a9a/multidict-6.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:55ae0721c1513e5e3210bca4fc98456b980b0c2c016679d3d723119b6b202c42", size = 228969, upload-time = "2025-05-19T14:14:32.672Z" }, + { url = "https://files.pythonhosted.org/packages/d2/c3/3d58182f76b960eeade51c89fcdce450f93379340457a328e132e2f8f9ed/multidict-6.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:51d662c072579f63137919d7bb8fc250655ce79f00c82ecf11cab678f335062e", size = 217433, upload-time = "2025-05-19T14:14:34.016Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/f31a562906f3bd375f3d0e83ce314e4a660c01b16c2923e8229b53fba5d7/multidict-6.4.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0e05c39962baa0bb19a6b210e9b1422c35c093b651d64246b6c2e1a7e242d9fd", size = 225418, upload-time = "2025-05-19T14:14:35.376Z" }, + { url = "https://files.pythonhosted.org/packages/99/89/78bb95c89c496d64b5798434a3deee21996114d4d2c28dd65850bf3a691e/multidict-6.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5b1cc3ab8c31d9ebf0faa6e3540fb91257590da330ffe6d2393d4208e638925", size = 235042, upload-time = "2025-05-19T14:14:36.723Z" }, + { url = "https://files.pythonhosted.org/packages/74/91/8780a6e5885a8770442a8f80db86a0887c4becca0e5a2282ba2cae702bc4/multidict-6.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93ec84488a384cd7b8a29c2c7f467137d8a73f6fe38bb810ecf29d1ade011a7c", size = 230280, upload-time = "2025-05-19T14:14:38.194Z" }, + { url = "https://files.pythonhosted.org/packages/68/c1/fcf69cabd542eb6f4b892469e033567ee6991d361d77abdc55e3a0f48349/multidict-6.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b308402608493638763abc95f9dc0030bbd6ac6aff784512e8ac3da73a88af08", size = 223322, upload-time = "2025-05-19T14:14:40.015Z" }, + { url = "https://files.pythonhosted.org/packages/b8/85/5b80bf4b83d8141bd763e1d99142a9cdfd0db83f0739b4797172a4508014/multidict-6.4.4-cp311-cp311-win32.whl", hash = "sha256:343892a27d1a04d6ae455ecece12904d242d299ada01633d94c4f431d68a8c49", size = 35070, upload-time = "2025-05-19T14:14:41.904Z" }, + { url = "https://files.pythonhosted.org/packages/09/66/0bed198ffd590ab86e001f7fa46b740d58cf8ff98c2f254e4a36bf8861ad/multidict-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:73484a94f55359780c0f458bbd3c39cb9cf9c182552177d2136e828269dee529", size = 38667, upload-time = "2025-05-19T14:14:43.534Z" }, + { url = "https://files.pythonhosted.org/packages/d2/b5/5675377da23d60875fe7dae6be841787755878e315e2f517235f22f59e18/multidict-6.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc388f75a1c00000824bf28b7633e40854f4127ede80512b44c3cfeeea1839a2", size = 64293, upload-time = "2025-05-19T14:14:44.724Z" }, + { url = "https://files.pythonhosted.org/packages/34/a7/be384a482754bb8c95d2bbe91717bf7ccce6dc38c18569997a11f95aa554/multidict-6.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:98af87593a666f739d9dba5d0ae86e01b0e1a9cfcd2e30d2d361fbbbd1a9162d", size = 38096, upload-time = "2025-05-19T14:14:45.95Z" }, + { url = "https://files.pythonhosted.org/packages/66/6d/d59854bb4352306145bdfd1704d210731c1bb2c890bfee31fb7bbc1c4c7f/multidict-6.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aff4cafea2d120327d55eadd6b7f1136a8e5a0ecf6fb3b6863e8aca32cd8e50a", size = 37214, upload-time = "2025-05-19T14:14:47.158Z" }, + { url = "https://files.pythonhosted.org/packages/99/e0/c29d9d462d7cfc5fc8f9bf24f9c6843b40e953c0b55e04eba2ad2cf54fba/multidict-6.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169c4ba7858176b797fe551d6e99040c531c775d2d57b31bcf4de6d7a669847f", size = 224686, upload-time = "2025-05-19T14:14:48.366Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4a/da99398d7fd8210d9de068f9a1b5f96dfaf67d51e3f2521f17cba4ee1012/multidict-6.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9eb4c59c54421a32b3273d4239865cb14ead53a606db066d7130ac80cc8ec93", size = 231061, upload-time = "2025-05-19T14:14:49.952Z" }, + { url = "https://files.pythonhosted.org/packages/21/f5/ac11add39a0f447ac89353e6ca46666847051103649831c08a2800a14455/multidict-6.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cf3bd54c56aa16fdb40028d545eaa8d051402b61533c21e84046e05513d5780", size = 232412, upload-time = "2025-05-19T14:14:51.812Z" }, + { url = "https://files.pythonhosted.org/packages/d9/11/4b551e2110cded705a3c13a1d4b6a11f73891eb5a1c449f1b2b6259e58a6/multidict-6.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f682c42003c7264134bfe886376299db4cc0c6cd06a3295b41b347044bcb5482", size = 231563, upload-time = "2025-05-19T14:14:53.262Z" }, + { url = "https://files.pythonhosted.org/packages/4c/02/751530c19e78fe73b24c3da66618eda0aa0d7f6e7aa512e46483de6be210/multidict-6.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920f9cf2abdf6e493c519492d892c362007f113c94da4c239ae88429835bad1", size = 223811, upload-time = "2025-05-19T14:14:55.232Z" }, + { url = "https://files.pythonhosted.org/packages/c7/cb/2be8a214643056289e51ca356026c7b2ce7225373e7a1f8c8715efee8988/multidict-6.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:530d86827a2df6504526106b4c104ba19044594f8722d3e87714e847c74a0275", size = 216524, upload-time = "2025-05-19T14:14:57.226Z" }, + { url = "https://files.pythonhosted.org/packages/19/f3/6d5011ec375c09081f5250af58de85f172bfcaafebff286d8089243c4bd4/multidict-6.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecde56ea2439b96ed8a8d826b50c57364612ddac0438c39e473fafad7ae1c23b", size = 229012, upload-time = "2025-05-19T14:14:58.597Z" }, + { url = "https://files.pythonhosted.org/packages/67/9c/ca510785df5cf0eaf5b2a8132d7d04c1ce058dcf2c16233e596ce37a7f8e/multidict-6.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:dc8c9736d8574b560634775ac0def6bdc1661fc63fa27ffdfc7264c565bcb4f2", size = 226765, upload-time = "2025-05-19T14:15:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/36/c8/ca86019994e92a0f11e642bda31265854e6ea7b235642f0477e8c2e25c1f/multidict-6.4.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7f3d3b3c34867579ea47cbd6c1f2ce23fbfd20a273b6f9e3177e256584f1eacc", size = 222888, upload-time = "2025-05-19T14:15:01.568Z" }, + { url = "https://files.pythonhosted.org/packages/c6/67/bc25a8e8bd522935379066950ec4e2277f9b236162a73548a2576d4b9587/multidict-6.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87a728af265e08f96b6318ebe3c0f68b9335131f461efab2fc64cc84a44aa6ed", size = 234041, upload-time = "2025-05-19T14:15:03.759Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a0/70c4c2d12857fccbe607b334b7ee28b6b5326c322ca8f73ee54e70d76484/multidict-6.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9f193eeda1857f8e8d3079a4abd258f42ef4a4bc87388452ed1e1c4d2b0c8740", size = 231046, upload-time = "2025-05-19T14:15:05.698Z" }, + { url = "https://files.pythonhosted.org/packages/c1/0f/52954601d02d39742aab01d6b92f53c1dd38b2392248154c50797b4df7f1/multidict-6.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be06e73c06415199200e9a2324a11252a3d62030319919cde5e6950ffeccf72e", size = 227106, upload-time = "2025-05-19T14:15:07.124Z" }, + { url = "https://files.pythonhosted.org/packages/af/24/679d83ec4379402d28721790dce818e5d6b9f94ce1323a556fb17fa9996c/multidict-6.4.4-cp312-cp312-win32.whl", hash = "sha256:622f26ea6a7e19b7c48dd9228071f571b2fbbd57a8cd71c061e848f281550e6b", size = 35351, upload-time = "2025-05-19T14:15:08.556Z" }, + { url = "https://files.pythonhosted.org/packages/52/ef/40d98bc5f986f61565f9b345f102409534e29da86a6454eb6b7c00225a13/multidict-6.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:5e2bcda30d5009996ff439e02a9f2b5c3d64a20151d34898c000a6281faa3781", size = 38791, upload-time = "2025-05-19T14:15:09.825Z" }, + { url = "https://files.pythonhosted.org/packages/df/2a/e166d2ffbf4b10131b2d5b0e458f7cee7d986661caceae0de8753042d4b2/multidict-6.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:82ffabefc8d84c2742ad19c37f02cde5ec2a1ee172d19944d380f920a340e4b9", size = 64123, upload-time = "2025-05-19T14:15:11.044Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/e200e379ae5b6f95cbae472e0199ea98913f03d8c9a709f42612a432932c/multidict-6.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6a2f58a66fe2c22615ad26156354005391e26a2f3721c3621504cd87c1ea87bf", size = 38049, upload-time = "2025-05-19T14:15:12.902Z" }, + { url = "https://files.pythonhosted.org/packages/75/fb/47afd17b83f6a8c7fa863c6d23ac5ba6a0e6145ed8a6bcc8da20b2b2c1d2/multidict-6.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5883d6ee0fd9d8a48e9174df47540b7545909841ac82354c7ae4cbe9952603bd", size = 37078, upload-time = "2025-05-19T14:15:14.282Z" }, + { url = "https://files.pythonhosted.org/packages/fa/70/1af3143000eddfb19fd5ca5e78393985ed988ac493bb859800fe0914041f/multidict-6.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9abcf56a9511653fa1d052bfc55fbe53dbee8f34e68bd6a5a038731b0ca42d15", size = 224097, upload-time = "2025-05-19T14:15:15.566Z" }, + { url = "https://files.pythonhosted.org/packages/b1/39/d570c62b53d4fba844e0378ffbcd02ac25ca423d3235047013ba2f6f60f8/multidict-6.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6ed5ae5605d4ad5a049fad2a28bb7193400700ce2f4ae484ab702d1e3749c3f9", size = 230768, upload-time = "2025-05-19T14:15:17.308Z" }, + { url = "https://files.pythonhosted.org/packages/fd/f8/ed88f2c4d06f752b015933055eb291d9bc184936903752c66f68fb3c95a7/multidict-6.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbfcb60396f9bcfa63e017a180c3105b8c123a63e9d1428a36544e7d37ca9e20", size = 231331, upload-time = "2025-05-19T14:15:18.73Z" }, + { url = "https://files.pythonhosted.org/packages/9c/6f/8e07cffa32f483ab887b0d56bbd8747ac2c1acd00dc0af6fcf265f4a121e/multidict-6.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0f1987787f5f1e2076b59692352ab29a955b09ccc433c1f6b8e8e18666f608b", size = 230169, upload-time = "2025-05-19T14:15:20.179Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2b/5dcf173be15e42f330110875a2668ddfc208afc4229097312212dc9c1236/multidict-6.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0121ccce8c812047d8d43d691a1ad7641f72c4f730474878a5aeae1b8ead8c", size = 222947, upload-time = "2025-05-19T14:15:21.714Z" }, + { url = "https://files.pythonhosted.org/packages/39/75/4ddcbcebe5ebcd6faa770b629260d15840a5fc07ce8ad295a32e14993726/multidict-6.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ec4967114295b8afd120a8eec579920c882831a3e4c3331d591a8e5bfbbc0f", size = 215761, upload-time = "2025-05-19T14:15:23.242Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c9/55e998ae45ff15c5608e384206aa71a11e1b7f48b64d166db400b14a3433/multidict-6.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:995f985e2e268deaf17867801b859a282e0448633f1310e3704b30616d269d69", size = 227605, upload-time = "2025-05-19T14:15:24.763Z" }, + { url = "https://files.pythonhosted.org/packages/04/49/c2404eac74497503c77071bd2e6f88c7e94092b8a07601536b8dbe99be50/multidict-6.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d832c608f94b9f92a0ec8b7e949be7792a642b6e535fcf32f3e28fab69eeb046", size = 226144, upload-time = "2025-05-19T14:15:26.249Z" }, + { url = "https://files.pythonhosted.org/packages/62/c5/0cd0c3c6f18864c40846aa2252cd69d308699cb163e1c0d989ca301684da/multidict-6.4.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d21c1212171cf7da703c5b0b7a0e85be23b720818aef502ad187d627316d5645", size = 221100, upload-time = "2025-05-19T14:15:28.303Z" }, + { url = "https://files.pythonhosted.org/packages/71/7b/f2f3887bea71739a046d601ef10e689528d4f911d84da873b6be9194ffea/multidict-6.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cbebaa076aaecad3d4bb4c008ecc73b09274c952cf6a1b78ccfd689e51f5a5b0", size = 232731, upload-time = "2025-05-19T14:15:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/e5/b3/d9de808349df97fa75ec1372758701b5800ebad3c46ae377ad63058fbcc6/multidict-6.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c93a6fb06cc8e5d3628b2b5fda215a5db01e8f08fc15fadd65662d9b857acbe4", size = 229637, upload-time = "2025-05-19T14:15:33.337Z" }, + { url = "https://files.pythonhosted.org/packages/5e/57/13207c16b615eb4f1745b44806a96026ef8e1b694008a58226c2d8f5f0a5/multidict-6.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8cd8f81f1310182362fb0c7898145ea9c9b08a71081c5963b40ee3e3cac589b1", size = 225594, upload-time = "2025-05-19T14:15:34.832Z" }, + { url = "https://files.pythonhosted.org/packages/3a/e4/d23bec2f70221604f5565000632c305fc8f25ba953e8ce2d8a18842b9841/multidict-6.4.4-cp313-cp313-win32.whl", hash = "sha256:3e9f1cd61a0ab857154205fb0b1f3d3ace88d27ebd1409ab7af5096e409614cd", size = 35359, upload-time = "2025-05-19T14:15:36.246Z" }, + { url = "https://files.pythonhosted.org/packages/a7/7a/cfe1a47632be861b627f46f642c1d031704cc1c0f5c0efbde2ad44aa34bd/multidict-6.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:8ffb40b74400e4455785c2fa37eba434269149ec525fc8329858c862e4b35373", size = 38903, upload-time = "2025-05-19T14:15:37.507Z" }, + { url = "https://files.pythonhosted.org/packages/68/7b/15c259b0ab49938a0a1c8f3188572802704a779ddb294edc1b2a72252e7c/multidict-6.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6a602151dbf177be2450ef38966f4be3467d41a86c6a845070d12e17c858a156", size = 68895, upload-time = "2025-05-19T14:15:38.856Z" }, + { url = "https://files.pythonhosted.org/packages/f1/7d/168b5b822bccd88142e0a3ce985858fea612404edd228698f5af691020c9/multidict-6.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d2b9712211b860d123815a80b859075d86a4d54787e247d7fbee9db6832cf1c", size = 40183, upload-time = "2025-05-19T14:15:40.197Z" }, + { url = "https://files.pythonhosted.org/packages/e0/b7/d4b8d98eb850ef28a4922ba508c31d90715fd9b9da3801a30cea2967130b/multidict-6.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d2fa86af59f8fc1972e121ade052145f6da22758f6996a197d69bb52f8204e7e", size = 39592, upload-time = "2025-05-19T14:15:41.508Z" }, + { url = "https://files.pythonhosted.org/packages/18/28/a554678898a19583548e742080cf55d169733baf57efc48c2f0273a08583/multidict-6.4.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50855d03e9e4d66eab6947ba688ffb714616f985838077bc4b490e769e48da51", size = 226071, upload-time = "2025-05-19T14:15:42.877Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dc/7ba6c789d05c310e294f85329efac1bf5b450338d2542498db1491a264df/multidict-6.4.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5bce06b83be23225be1905dcdb6b789064fae92499fbc458f59a8c0e68718601", size = 222597, upload-time = "2025-05-19T14:15:44.412Z" }, + { url = "https://files.pythonhosted.org/packages/24/4f/34eadbbf401b03768dba439be0fb94b0d187facae9142821a3d5599ccb3b/multidict-6.4.4-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66ed0731f8e5dfd8369a883b6e564aca085fb9289aacabd9decd70568b9a30de", size = 228253, upload-time = "2025-05-19T14:15:46.474Z" }, + { url = "https://files.pythonhosted.org/packages/c0/e6/493225a3cdb0d8d80d43a94503fc313536a07dae54a3f030d279e629a2bc/multidict-6.4.4-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329ae97fc2f56f44d91bc47fe0972b1f52d21c4b7a2ac97040da02577e2daca2", size = 226146, upload-time = "2025-05-19T14:15:48.003Z" }, + { url = "https://files.pythonhosted.org/packages/2f/70/e411a7254dc3bff6f7e6e004303b1b0591358e9f0b7c08639941e0de8bd6/multidict-6.4.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c27e5dcf520923d6474d98b96749e6805f7677e93aaaf62656005b8643f907ab", size = 220585, upload-time = "2025-05-19T14:15:49.546Z" }, + { url = "https://files.pythonhosted.org/packages/08/8f/beb3ae7406a619100d2b1fb0022c3bb55a8225ab53c5663648ba50dfcd56/multidict-6.4.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:058cc59b9e9b143cc56715e59e22941a5d868c322242278d28123a5d09cdf6b0", size = 212080, upload-time = "2025-05-19T14:15:51.151Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ec/355124e9d3d01cf8edb072fd14947220f357e1c5bc79c88dff89297e9342/multidict-6.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:69133376bc9a03f8c47343d33f91f74a99c339e8b58cea90433d8e24bb298031", size = 226558, upload-time = "2025-05-19T14:15:52.665Z" }, + { url = "https://files.pythonhosted.org/packages/fd/22/d2b95cbebbc2ada3be3812ea9287dcc9712d7f1a012fad041770afddb2ad/multidict-6.4.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d6b15c55721b1b115c5ba178c77104123745b1417527ad9641a4c5e2047450f0", size = 212168, upload-time = "2025-05-19T14:15:55.279Z" }, + { url = "https://files.pythonhosted.org/packages/4d/c5/62bfc0b2f9ce88326dbe7179f9824a939c6c7775b23b95de777267b9725c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a887b77f51d3d41e6e1a63cf3bc7ddf24de5939d9ff69441387dfefa58ac2e26", size = 217970, upload-time = "2025-05-19T14:15:56.806Z" }, + { url = "https://files.pythonhosted.org/packages/79/74/977cea1aadc43ff1c75d23bd5bc4768a8fac98c14e5878d6ee8d6bab743c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:632a3bf8f1787f7ef7d3c2f68a7bde5be2f702906f8b5842ad6da9d974d0aab3", size = 226980, upload-time = "2025-05-19T14:15:58.313Z" }, + { url = "https://files.pythonhosted.org/packages/48/fc/cc4a1a2049df2eb84006607dc428ff237af38e0fcecfdb8a29ca47b1566c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a145c550900deb7540973c5cdb183b0d24bed6b80bf7bddf33ed8f569082535e", size = 220641, upload-time = "2025-05-19T14:15:59.866Z" }, + { url = "https://files.pythonhosted.org/packages/3b/6a/a7444d113ab918701988d4abdde373dbdfd2def7bd647207e2bf645c7eac/multidict-6.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc5d83c6619ca5c9672cb78b39ed8542f1975a803dee2cda114ff73cbb076edd", size = 221728, upload-time = "2025-05-19T14:16:01.535Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b0/fdf4c73ad1c55e0f4dbbf2aa59dd37037334091f9a4961646d2b7ac91a86/multidict-6.4.4-cp313-cp313t-win32.whl", hash = "sha256:3312f63261b9df49be9d57aaa6abf53a6ad96d93b24f9cc16cf979956355ce6e", size = 41913, upload-time = "2025-05-19T14:16:03.199Z" }, + { url = "https://files.pythonhosted.org/packages/8e/92/27989ecca97e542c0d01d05a98a5ae12198a243a9ee12563a0313291511f/multidict-6.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:ba852168d814b2c73333073e1c7116d9395bea69575a01b0b3c89d2d5a87c8fb", size = 46112, upload-time = "2025-05-19T14:16:04.909Z" }, + { url = "https://files.pythonhosted.org/packages/84/5d/e17845bb0fa76334477d5de38654d27946d5b5d3695443987a094a71b440/multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac", size = 10481, upload-time = "2025-05-19T14:16:36.024Z" }, ] [[package]] @@ -2410,9 +2488,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/55/56ce6f23d7fb98ce5b8a4261f089890bc94250666ea7089539dab55f6c25/mypy_boto3_bedrock_runtime-1.38.4.tar.gz", hash = "sha256:315a5f84c014c54e5406fdb80b030aba5cc79eb27982aff3d09ef331fb2cdd4d", size = 26169 } +sdist = { url = "https://files.pythonhosted.org/packages/7d/55/56ce6f23d7fb98ce5b8a4261f089890bc94250666ea7089539dab55f6c25/mypy_boto3_bedrock_runtime-1.38.4.tar.gz", hash = "sha256:315a5f84c014c54e5406fdb80b030aba5cc79eb27982aff3d09ef331fb2cdd4d", size = 26169, upload-time = "2025-04-28T19:26:13.437Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/eb/3015c6504540ca4888789ee14f47590c0340b748a33b059eeb6a48b406bb/mypy_boto3_bedrock_runtime-1.38.4-py3-none-any.whl", hash = "sha256:af14320532e9b798095129a3307f4b186ba80258917bb31410cda7f423592d72", size = 31858 }, + { url = "https://files.pythonhosted.org/packages/43/eb/3015c6504540ca4888789ee14f47590c0340b748a33b059eeb6a48b406bb/mypy_boto3_bedrock_runtime-1.38.4-py3-none-any.whl", hash = "sha256:af14320532e9b798095129a3307f4b186ba80258917bb31410cda7f423592d72", size = 31858, upload-time = "2025-04-28T19:26:09.667Z" }, ] [[package]] @@ -2422,9 +2500,9 @@ 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 } +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 }, + { 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]] @@ -2437,89 +2515,89 @@ resolution-markers = [ "python_full_version >= '3.12' and python_full_version < '3.12.4'", "python_full_version == '3.11.*'", ] -sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065 } +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 }, + { 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 = "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 } +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 }, + { 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" } -sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440 } -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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149 }, - { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866 }, - { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506 }, - { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532 }, - { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225 }, - { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666 }, +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 = "oauthlib" version = "3.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/fa/fbf4001037904031639e6bfbfc02badfc7e12f137a8afa254df6c4c8a670/oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918", size = 177352 } +sdist = { url = "https://files.pythonhosted.org/packages/6d/fa/fbf4001037904031639e6bfbfc02badfc7e12f137a8afa254df6c4c8a670/oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918", size = 177352, upload-time = "2022-10-17T20:04:27.471Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/80/cab10959dc1faead58dc8384a781dfbf93cb4d33d50988f7a69f1b7c9bbe/oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", size = 151688 }, + { url = "https://files.pythonhosted.org/packages/7e/80/cab10959dc1faead58dc8384a781dfbf93cb4d33d50988f7a69f1b7c9bbe/oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", size = 151688, upload-time = "2022-10-17T20:04:24.037Z" }, ] [[package]] @@ -2535,24 +2613,24 @@ dependencies = [ { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/6d/6b/8267490476e8d4dd1883632c7e46a4634384c7ff1c35ae44edc8ab0bb7a9/onnxruntime-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:20bca6495d06925631e201f2b257cc37086752e8fe7b6c83a67c6509f4759bc9", size = 12689974 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/89/a5/1c6c10322201566015183b52ef011dfa932f5dd1b278de8d75c3b948411d/onnxruntime-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:03d3ef7fb11adf154149d6e767e21057e0e577b947dd3f66190b212528e1db31", size = 12691517 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/36/b4/3f1c71ce1d3d21078a6a74c5483bfa2b07e41a8d2b8fb1e9993e6a26d8d3/onnxruntime-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0d534a43d1264d1273c2d4f00a5a588fa98d21117a3345b7104fa0bbcaadb9a", size = 12692233 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/3e/89/2f64e250945fa87140fb917ba377d6d0e9122e029c8512f389a9b7f953f4/onnxruntime-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:5a31d84ef82b4b05d794a4ce8ba37b0d9deb768fd580e36e17b39e0b4840253b", size = 12691777 }, - { 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 }, - { 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 }, + { 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]] @@ -2569,9 +2647,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/b1/318f5d4c482f19c5fcbcde190801bfaaaec23413cda0b88a29f6897448ff/openai-1.75.0.tar.gz", hash = "sha256:fb3ea907efbdb1bcfd0c44507ad9c961afd7dce3147292b54505ecfd17be8fd1", size = 429492 } +sdist = { url = "https://files.pythonhosted.org/packages/99/b1/318f5d4c482f19c5fcbcde190801bfaaaec23413cda0b88a29f6897448ff/openai-1.75.0.tar.gz", hash = "sha256:fb3ea907efbdb1bcfd0c44507ad9c961afd7dce3147292b54505ecfd17be8fd1", size = 429492, upload-time = "2025-04-16T16:49:29.25Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/80/9a/f34f163294345f123673ed03e77c33dee2534f3ac1f9d18120384457304d/openai-1.75.0-py3-none-any.whl", hash = "sha256:fe6f932d2ded3b429ff67cc9ad118c71327db32eb9d32dd723de3acfca337125", size = 646972 }, + { url = "https://files.pythonhosted.org/packages/80/9a/f34f163294345f123673ed03e77c33dee2534f3ac1f9d18120384457304d/openai-1.75.0-py3-none-any.whl", hash = "sha256:fe6f932d2ded3b429ff67cc9ad118c71327db32eb9d32dd723de3acfca337125", size = 646972, upload-time = "2025-04-16T16:49:27.196Z" }, ] [[package]] @@ -2581,9 +2659,9 @@ 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 } +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 }, + { 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]] @@ -2594,9 +2672,9 @@ dependencies = [ { name = "deprecated" }, { name = "importlib-metadata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9a/8d/1f5a45fbcb9a7d87809d460f09dc3399e3fbd31d7f3e14888345e9d29951/opentelemetry_api-1.33.1.tar.gz", hash = "sha256:1c6055fc0a2d3f23a50c7e17e16ef75ad489345fd3df1f8b8af7c0bbf8a109e8", size = 65002 } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8d/1f5a45fbcb9a7d87809d460f09dc3399e3fbd31d7f3e14888345e9d29951/opentelemetry_api-1.33.1.tar.gz", hash = "sha256:1c6055fc0a2d3f23a50c7e17e16ef75ad489345fd3df1f8b8af7c0bbf8a109e8", size = 65002, upload-time = "2025-05-16T18:52:41.146Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/44/4c45a34def3506122ae61ad684139f0bbc4e00c39555d4f7e20e0e001c8a/opentelemetry_api-1.33.1-py3-none-any.whl", hash = "sha256:4db83ebcf7ea93e64637ec6ee6fabee45c5cbe4abd9cf3da95c43828ddb50b83", size = 65771 }, + { url = "https://files.pythonhosted.org/packages/05/44/4c45a34def3506122ae61ad684139f0bbc4e00c39555d4f7e20e0e001c8a/opentelemetry_api-1.33.1-py3-none-any.whl", hash = "sha256:4db83ebcf7ea93e64637ec6ee6fabee45c5cbe4abd9cf3da95c43828ddb50b83", size = 65771, upload-time = "2025-05-16T18:52:17.419Z" }, ] [[package]] @@ -2608,9 +2686,9 @@ dependencies = [ { name = "opentelemetry-instrumentation" }, { name = "opentelemetry-sdk" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/dd/0b/0012cb5947c255d6755cb91e3b9fd9bb1876b7e14d5ab67131c030fd90b2/opentelemetry_distro-0.54b1.tar.gz", hash = "sha256:61d6b97bb7a245fddbb829345bb4ad18be39eb52f770fab89a127107fca3149f", size = 2593 } +sdist = { url = "https://files.pythonhosted.org/packages/dd/0b/0012cb5947c255d6755cb91e3b9fd9bb1876b7e14d5ab67131c030fd90b2/opentelemetry_distro-0.54b1.tar.gz", hash = "sha256:61d6b97bb7a245fddbb829345bb4ad18be39eb52f770fab89a127107fca3149f", size = 2593, upload-time = "2025-05-16T19:03:19.71Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/b1/5f008a2909d59c02c7b88aa595502d438ca21c15e88edd7620c697a56ce8/opentelemetry_distro-0.54b1-py3-none-any.whl", hash = "sha256:009486513b32b703e275bb2f9ccaf5791676bbf5e2dcfdd90201ddc8f56f122b", size = 3348 }, + { url = "https://files.pythonhosted.org/packages/12/b1/5f008a2909d59c02c7b88aa595502d438ca21c15e88edd7620c697a56ce8/opentelemetry_distro-0.54b1-py3-none-any.whl", hash = "sha256:009486513b32b703e275bb2f9ccaf5791676bbf5e2dcfdd90201ddc8f56f122b", size = 3348, upload-time = "2025-05-16T19:02:11.624Z" }, ] [[package]] @@ -2620,9 +2698,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-proto" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7a/18/a1ec9dcb6713a48b4bdd10f1c1e4d5d2489d3912b80d2bcc059a9a842836/opentelemetry_exporter_otlp_proto_common-1.33.1.tar.gz", hash = "sha256:c57b3fa2d0595a21c4ed586f74f948d259d9949b58258f11edb398f246bec131", size = 20828 } +sdist = { url = "https://files.pythonhosted.org/packages/7a/18/a1ec9dcb6713a48b4bdd10f1c1e4d5d2489d3912b80d2bcc059a9a842836/opentelemetry_exporter_otlp_proto_common-1.33.1.tar.gz", hash = "sha256:c57b3fa2d0595a21c4ed586f74f948d259d9949b58258f11edb398f246bec131", size = 20828, upload-time = "2025-05-16T18:52:43.795Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/09/52/9bcb17e2c29c1194a28e521b9d3f2ced09028934c3c52a8205884c94b2df/opentelemetry_exporter_otlp_proto_common-1.33.1-py3-none-any.whl", hash = "sha256:b81c1de1ad349785e601d02715b2d29d6818aed2c809c20219f3d1f20b038c36", size = 18839 }, + { url = "https://files.pythonhosted.org/packages/09/52/9bcb17e2c29c1194a28e521b9d3f2ced09028934c3c52a8205884c94b2df/opentelemetry_exporter_otlp_proto_common-1.33.1-py3-none-any.whl", hash = "sha256:b81c1de1ad349785e601d02715b2d29d6818aed2c809c20219f3d1f20b038c36", size = 18839, upload-time = "2025-05-16T18:52:22.447Z" }, ] [[package]] @@ -2638,9 +2716,9 @@ dependencies = [ { name = "opentelemetry-proto" }, { name = "opentelemetry-sdk" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/5f/75ef5a2a917bd0e6e7b83d3fb04c99236ee958f6352ba3019ea9109ae1a6/opentelemetry_exporter_otlp_proto_grpc-1.33.1.tar.gz", hash = "sha256:345696af8dc19785fac268c8063f3dc3d5e274c774b308c634f39d9c21955728", size = 22556 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/5f/75ef5a2a917bd0e6e7b83d3fb04c99236ee958f6352ba3019ea9109ae1a6/opentelemetry_exporter_otlp_proto_grpc-1.33.1.tar.gz", hash = "sha256:345696af8dc19785fac268c8063f3dc3d5e274c774b308c634f39d9c21955728", size = 22556, upload-time = "2025-05-16T18:52:44.76Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/ec/6047e230bb6d092c304511315b13893b1c9d9260044dd1228c9d48b6ae0e/opentelemetry_exporter_otlp_proto_grpc-1.33.1-py3-none-any.whl", hash = "sha256:7e8da32c7552b756e75b4f9e9c768a61eb47dee60b6550b37af541858d669ce1", size = 18591 }, + { url = "https://files.pythonhosted.org/packages/ba/ec/6047e230bb6d092c304511315b13893b1c9d9260044dd1228c9d48b6ae0e/opentelemetry_exporter_otlp_proto_grpc-1.33.1-py3-none-any.whl", hash = "sha256:7e8da32c7552b756e75b4f9e9c768a61eb47dee60b6550b37af541858d669ce1", size = 18591, upload-time = "2025-05-16T18:52:23.772Z" }, ] [[package]] @@ -2656,9 +2734,9 @@ dependencies = [ { name = "opentelemetry-sdk" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/48/e4314ac0ed2ad043c07693d08c9c4bf5633857f5b72f2fefc64fd2b114f6/opentelemetry_exporter_otlp_proto_http-1.33.1.tar.gz", hash = "sha256:46622d964a441acb46f463ebdc26929d9dec9efb2e54ef06acdc7305e8593c38", size = 15353 } +sdist = { url = "https://files.pythonhosted.org/packages/60/48/e4314ac0ed2ad043c07693d08c9c4bf5633857f5b72f2fefc64fd2b114f6/opentelemetry_exporter_otlp_proto_http-1.33.1.tar.gz", hash = "sha256:46622d964a441acb46f463ebdc26929d9dec9efb2e54ef06acdc7305e8593c38", size = 15353, upload-time = "2025-05-16T18:52:45.522Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/63/ba/5a4ad007588016fe37f8d36bf08f325fe684494cc1e88ca8fa064a4c8f57/opentelemetry_exporter_otlp_proto_http-1.33.1-py3-none-any.whl", hash = "sha256:ebd6c523b89a2ecba0549adb92537cc2bf647b4ee61afbbd5a4c6535aa3da7cf", size = 17733 }, + { url = "https://files.pythonhosted.org/packages/63/ba/5a4ad007588016fe37f8d36bf08f325fe684494cc1e88ca8fa064a4c8f57/opentelemetry_exporter_otlp_proto_http-1.33.1-py3-none-any.whl", hash = "sha256:ebd6c523b89a2ecba0549adb92537cc2bf647b4ee61afbbd5a4c6535aa3da7cf", size = 17733, upload-time = "2025-05-16T18:52:25.137Z" }, ] [[package]] @@ -2671,9 +2749,9 @@ dependencies = [ { name = "packaging" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c3/fd/5756aea3fdc5651b572d8aef7d94d22a0a36e49c8b12fcb78cb905ba8896/opentelemetry_instrumentation-0.54b1.tar.gz", hash = "sha256:7658bf2ff914b02f246ec14779b66671508125c0e4227361e56b5ebf6cef0aec", size = 28436 } +sdist = { url = "https://files.pythonhosted.org/packages/c3/fd/5756aea3fdc5651b572d8aef7d94d22a0a36e49c8b12fcb78cb905ba8896/opentelemetry_instrumentation-0.54b1.tar.gz", hash = "sha256:7658bf2ff914b02f246ec14779b66671508125c0e4227361e56b5ebf6cef0aec", size = 28436, upload-time = "2025-05-16T19:03:22.223Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/89/0790abc5d9c4fc74bd3e03cb87afe2c820b1d1a112a723c1163ef32453ee/opentelemetry_instrumentation-0.54b1-py3-none-any.whl", hash = "sha256:a4ae45f4a90c78d7006c51524f57cd5aa1231aef031eae905ee34d5423f5b198", size = 31019 }, + { url = "https://files.pythonhosted.org/packages/f4/89/0790abc5d9c4fc74bd3e03cb87afe2c820b1d1a112a723c1163ef32453ee/opentelemetry_instrumentation-0.54b1-py3-none-any.whl", hash = "sha256:a4ae45f4a90c78d7006c51524f57cd5aa1231aef031eae905ee34d5423f5b198", size = 31019, upload-time = "2025-05-16T19:02:15.611Z" }, ] [[package]] @@ -2686,9 +2764,9 @@ dependencies = [ { name = "opentelemetry-semantic-conventions" }, { name = "opentelemetry-semantic-conventions-ai" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/89/d4/cc19d3fd0dd4f196f539db971b5cd7a4e4297494e2d9782153660e1e665e/opentelemetry_instrumentation_anthropic-0.40.7.tar.gz", hash = "sha256:8680797dbaa2808e4e2831de500e2dd2c6f9064eb4c887857b3b562c9d583673", size = 8970 } +sdist = { url = "https://files.pythonhosted.org/packages/89/d4/cc19d3fd0dd4f196f539db971b5cd7a4e4297494e2d9782153660e1e665e/opentelemetry_instrumentation_anthropic-0.40.7.tar.gz", hash = "sha256:8680797dbaa2808e4e2831de500e2dd2c6f9064eb4c887857b3b562c9d583673", size = 8970, upload-time = "2025-05-20T15:04:47.625Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/0e/1aeb4d0b26081885127afbdfcefbf4fc108fb9ced66a1bfbc05b13ebdcb0/opentelemetry_instrumentation_anthropic-0.40.7-py3-none-any.whl", hash = "sha256:7e1f379e1b710d403efbde40c98095607d9178bf4730289562b6c71677d89dac", size = 11507 }, + { url = "https://files.pythonhosted.org/packages/4e/0e/1aeb4d0b26081885127afbdfcefbf4fc108fb9ced66a1bfbc05b13ebdcb0/opentelemetry_instrumentation_anthropic-0.40.7-py3-none-any.whl", hash = "sha256:7e1f379e1b710d403efbde40c98095607d9178bf4730289562b6c71677d89dac", size = 11507, upload-time = "2025-05-20T15:04:11.797Z" }, ] [[package]] @@ -2702,9 +2780,9 @@ dependencies = [ { name = "opentelemetry-semantic-conventions" }, { name = "opentelemetry-util-http" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/20/f7/a3377f9771947f4d3d59c96841d3909274f446c030dbe8e4af871695ddee/opentelemetry_instrumentation_asgi-0.54b1.tar.gz", hash = "sha256:ab4df9776b5f6d56a78413c2e8bbe44c90694c67c844a1297865dc1bd926ed3c", size = 24230 } +sdist = { url = "https://files.pythonhosted.org/packages/20/f7/a3377f9771947f4d3d59c96841d3909274f446c030dbe8e4af871695ddee/opentelemetry_instrumentation_asgi-0.54b1.tar.gz", hash = "sha256:ab4df9776b5f6d56a78413c2e8bbe44c90694c67c844a1297865dc1bd926ed3c", size = 24230, upload-time = "2025-05-16T19:03:30.234Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/24/7a6f0ae79cae49927f528ecee2db55a5bddd87b550e310ce03451eae7491/opentelemetry_instrumentation_asgi-0.54b1-py3-none-any.whl", hash = "sha256:84674e822b89af563b283a5283c2ebb9ed585d1b80a1c27fb3ac20b562e9f9fc", size = 16338 }, + { url = "https://files.pythonhosted.org/packages/20/24/7a6f0ae79cae49927f528ecee2db55a5bddd87b550e310ce03451eae7491/opentelemetry_instrumentation_asgi-0.54b1-py3-none-any.whl", hash = "sha256:84674e822b89af563b283a5283c2ebb9ed585d1b80a1c27fb3ac20b562e9f9fc", size = 16338, upload-time = "2025-05-16T19:02:22.808Z" }, ] [[package]] @@ -2718,9 +2796,9 @@ dependencies = [ { name = "opentelemetry-semantic-conventions" }, { name = "opentelemetry-util-http" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/98/3b/9a262cdc1a4defef0e52afebdde3e8add658cc6f922e39e9dcee0da98349/opentelemetry_instrumentation_fastapi-0.54b1.tar.gz", hash = "sha256:1fcad19cef0db7092339b571a59e6f3045c9b58b7fd4670183f7addc459d78df", size = 19325 } +sdist = { url = "https://files.pythonhosted.org/packages/98/3b/9a262cdc1a4defef0e52afebdde3e8add658cc6f922e39e9dcee0da98349/opentelemetry_instrumentation_fastapi-0.54b1.tar.gz", hash = "sha256:1fcad19cef0db7092339b571a59e6f3045c9b58b7fd4670183f7addc459d78df", size = 19325, upload-time = "2025-05-16T19:03:45.359Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/9c/6b2b0f9d6c5dea7528ae0bf4e461dd765b0ae35f13919cd452970bb0d0b3/opentelemetry_instrumentation_fastapi-0.54b1-py3-none-any.whl", hash = "sha256:fb247781cfa75fd09d3d8713c65e4a02bd1e869b00e2c322cc516d4b5429860c", size = 12125 }, + { url = "https://files.pythonhosted.org/packages/df/9c/6b2b0f9d6c5dea7528ae0bf4e461dd765b0ae35f13919cd452970bb0d0b3/opentelemetry_instrumentation_fastapi-0.54b1-py3-none-any.whl", hash = "sha256:fb247781cfa75fd09d3d8713c65e4a02bd1e869b00e2c322cc516d4b5429860c", size = 12125, upload-time = "2025-05-16T19:02:41.172Z" }, ] [[package]] @@ -2734,9 +2812,9 @@ dependencies = [ { name = "opentelemetry-semantic-conventions-ai" }, { name = "tiktoken" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/af/b7/1e17d5e0ee4b03f5e571dee5f4687b9fabac5f6d4aa6c8d482cafdd451ff/opentelemetry_instrumentation_openai-0.40.7.tar.gz", hash = "sha256:c99a1ef20e6060122712785206aa7e8a511f46659fa2feaf5dda3764587e9afc", size = 15095 } +sdist = { url = "https://files.pythonhosted.org/packages/af/b7/1e17d5e0ee4b03f5e571dee5f4687b9fabac5f6d4aa6c8d482cafdd451ff/opentelemetry_instrumentation_openai-0.40.7.tar.gz", hash = "sha256:c99a1ef20e6060122712785206aa7e8a511f46659fa2feaf5dda3764587e9afc", size = 15095, upload-time = "2025-05-20T15:05:02.82Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/11/bf3ff69ecb76f6e3f69cb4f34ece246608115812e7077c34bf97da75ad4c/opentelemetry_instrumentation_openai-0.40.7-py3-none-any.whl", hash = "sha256:41308d17894ccc698955073ac732c61c4695991edb8674e2b588aefe4f773568", size = 23106 }, + { url = "https://files.pythonhosted.org/packages/da/11/bf3ff69ecb76f6e3f69cb4f34ece246608115812e7077c34bf97da75ad4c/opentelemetry_instrumentation_openai-0.40.7-py3-none-any.whl", hash = "sha256:41308d17894ccc698955073ac732c61c4695991edb8674e2b588aefe4f773568", size = 23106, upload-time = "2025-05-20T15:04:33.516Z" }, ] [[package]] @@ -2746,9 +2824,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f6/dc/791f3d60a1ad8235930de23eea735ae1084be1c6f96fdadf38710662a7e5/opentelemetry_proto-1.33.1.tar.gz", hash = "sha256:9627b0a5c90753bf3920c398908307063e4458b287bb890e5c1d6fa11ad50b68", size = 34363 } +sdist = { url = "https://files.pythonhosted.org/packages/f6/dc/791f3d60a1ad8235930de23eea735ae1084be1c6f96fdadf38710662a7e5/opentelemetry_proto-1.33.1.tar.gz", hash = "sha256:9627b0a5c90753bf3920c398908307063e4458b287bb890e5c1d6fa11ad50b68", size = 34363, upload-time = "2025-05-16T18:52:52.141Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/29/48609f4c875c2b6c80930073c82dd1cafd36b6782244c01394007b528960/opentelemetry_proto-1.33.1-py3-none-any.whl", hash = "sha256:243d285d9f29663fc7ea91a7171fcc1ccbbfff43b48df0774fd64a37d98eda70", size = 55854 }, + { url = "https://files.pythonhosted.org/packages/c4/29/48609f4c875c2b6c80930073c82dd1cafd36b6782244c01394007b528960/opentelemetry_proto-1.33.1-py3-none-any.whl", hash = "sha256:243d285d9f29663fc7ea91a7171fcc1ccbbfff43b48df0774fd64a37d98eda70", size = 55854, upload-time = "2025-05-16T18:52:36.269Z" }, ] [[package]] @@ -2760,9 +2838,9 @@ dependencies = [ { name = "opentelemetry-semantic-conventions" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/67/12/909b98a7d9b110cce4b28d49b2e311797cffdce180371f35eba13a72dd00/opentelemetry_sdk-1.33.1.tar.gz", hash = "sha256:85b9fcf7c3d23506fbc9692fd210b8b025a1920535feec50bd54ce203d57a531", size = 161885 } +sdist = { url = "https://files.pythonhosted.org/packages/67/12/909b98a7d9b110cce4b28d49b2e311797cffdce180371f35eba13a72dd00/opentelemetry_sdk-1.33.1.tar.gz", hash = "sha256:85b9fcf7c3d23506fbc9692fd210b8b025a1920535feec50bd54ce203d57a531", size = 161885, upload-time = "2025-05-16T18:52:52.832Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/8e/ae2d0742041e0bd7fe0d2dcc5e7cce51dcf7d3961a26072d5b43cc8fa2a7/opentelemetry_sdk-1.33.1-py3-none-any.whl", hash = "sha256:19ea73d9a01be29cacaa5d6c8ce0adc0b7f7b4d58cc52f923e4413609f670112", size = 118950 }, + { url = "https://files.pythonhosted.org/packages/df/8e/ae2d0742041e0bd7fe0d2dcc5e7cce51dcf7d3961a26072d5b43cc8fa2a7/opentelemetry_sdk-1.33.1-py3-none-any.whl", hash = "sha256:19ea73d9a01be29cacaa5d6c8ce0adc0b7f7b4d58cc52f923e4413609f670112", size = 118950, upload-time = "2025-05-16T18:52:37.297Z" }, ] [[package]] @@ -2773,93 +2851,93 @@ dependencies = [ { name = "deprecated" }, { name = "opentelemetry-api" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/2c/d7990fc1ffc82889d466e7cd680788ace44a26789809924813b164344393/opentelemetry_semantic_conventions-0.54b1.tar.gz", hash = "sha256:d1cecedae15d19bdaafca1e56b29a66aa286f50b5d08f036a145c7f3e9ef9cee", size = 118642 } +sdist = { url = "https://files.pythonhosted.org/packages/5b/2c/d7990fc1ffc82889d466e7cd680788ace44a26789809924813b164344393/opentelemetry_semantic_conventions-0.54b1.tar.gz", hash = "sha256:d1cecedae15d19bdaafca1e56b29a66aa286f50b5d08f036a145c7f3e9ef9cee", size = 118642, upload-time = "2025-05-16T18:52:53.962Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/80/08b1698c52ff76d96ba440bf15edc2f4bc0a279868778928e947c1004bdd/opentelemetry_semantic_conventions-0.54b1-py3-none-any.whl", hash = "sha256:29dab644a7e435b58d3a3918b58c333c92686236b30f7891d5e51f02933ca60d", size = 194938 }, + { url = "https://files.pythonhosted.org/packages/0a/80/08b1698c52ff76d96ba440bf15edc2f4bc0a279868778928e947c1004bdd/opentelemetry_semantic_conventions-0.54b1-py3-none-any.whl", hash = "sha256:29dab644a7e435b58d3a3918b58c333c92686236b30f7891d5e51f02933ca60d", size = 194938, upload-time = "2025-05-16T18:52:38.796Z" }, ] [[package]] name = "opentelemetry-semantic-conventions-ai" version = "0.4.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/ba/2405abde825cf654d09ba16bfcfb8c863156bccdc47d1f2a86df6331e7bb/opentelemetry_semantic_conventions_ai-0.4.9.tar.gz", hash = "sha256:54a0b901959e2de5124384925846bac2ea0a6dab3de7e501ba6aecf5e293fe04", size = 4920 } +sdist = { url = "https://files.pythonhosted.org/packages/8c/ba/2405abde825cf654d09ba16bfcfb8c863156bccdc47d1f2a86df6331e7bb/opentelemetry_semantic_conventions_ai-0.4.9.tar.gz", hash = "sha256:54a0b901959e2de5124384925846bac2ea0a6dab3de7e501ba6aecf5e293fe04", size = 4920, upload-time = "2025-05-16T10:20:54.611Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/34/98/f5196ba0f4105a4790cec8c6671cf676c96dfa29bfedfe3c4f112bf4e6ad/opentelemetry_semantic_conventions_ai-0.4.9-py3-none-any.whl", hash = "sha256:71149e46a72554ae17de46bca6c11ba540c19c89904bd4cc3111aac6edf10315", size = 5617 }, + { url = "https://files.pythonhosted.org/packages/34/98/f5196ba0f4105a4790cec8c6671cf676c96dfa29bfedfe3c4f112bf4e6ad/opentelemetry_semantic_conventions_ai-0.4.9-py3-none-any.whl", hash = "sha256:71149e46a72554ae17de46bca6c11ba540c19c89904bd4cc3111aac6edf10315", size = 5617, upload-time = "2025-05-16T10:20:53.062Z" }, ] [[package]] name = "opentelemetry-util-http" version = "0.54b1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a8/9f/1d8a1d1f34b9f62f2b940b388bf07b8167a8067e70870055bd05db354e5c/opentelemetry_util_http-0.54b1.tar.gz", hash = "sha256:f0b66868c19fbaf9c9d4e11f4a7599fa15d5ea50b884967a26ccd9d72c7c9d15", size = 8044 } +sdist = { url = "https://files.pythonhosted.org/packages/a8/9f/1d8a1d1f34b9f62f2b940b388bf07b8167a8067e70870055bd05db354e5c/opentelemetry_util_http-0.54b1.tar.gz", hash = "sha256:f0b66868c19fbaf9c9d4e11f4a7599fa15d5ea50b884967a26ccd9d72c7c9d15", size = 8044, upload-time = "2025-05-16T19:04:10.79Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/ef/c5aa08abca6894792beed4c0405e85205b35b8e73d653571c9ff13a8e34e/opentelemetry_util_http-0.54b1-py3-none-any.whl", hash = "sha256:b1c91883f980344a1c3c486cffd47ae5c9c1dd7323f9cbe9fdb7cadb401c87c9", size = 7301 }, + { url = "https://files.pythonhosted.org/packages/a4/ef/c5aa08abca6894792beed4c0405e85205b35b8e73d653571c9ff13a8e34e/opentelemetry_util_http-0.54b1-py3-none-any.whl", hash = "sha256:b1c91883f980344a1c3c486cffd47ae5c9c1dd7323f9cbe9fdb7cadb401c87c9", size = 7301, upload-time = "2025-05-16T19:03:18.18Z" }, ] [[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 } -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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/bf/8c/daba0ac1b8690011d9242a0f37235f7d17df6d0ad941021048523b76674e/orjson-3.10.18-cp310-cp310-win32.whl", hash = "sha256:607eb3ae0909d47280c1fc657c4284c34b785bae371d007595633f4b1a2bbe06", size = 142694 }, - { url = "https://files.pythonhosted.org/packages/16/62/8b687724143286b63e1d0fab3ad4214d54566d80b0ba9d67c26aaf28a2f8/orjson-3.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:8770432524ce0eca50b7efc2a9a5f486ee0113a5fbb4231526d414e6254eba92", size = 134600 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/a9/a3/6ea878e7b4a0dc5c888d0370d7752dcb23f402747d10e2257478d69b5e63/orjson-3.10.18-cp311-cp311-win32.whl", hash = "sha256:fdba703c722bd868c04702cac4cb8c6b8ff137af2623bc0ddb3b3e6a2c8996c1", size = 142695 }, - { url = "https://files.pythonhosted.org/packages/79/2a/4048700a3233d562f0e90d5572a849baa18ae4e5ce4c3ba6247e4ece57b0/orjson-3.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:c28082933c71ff4bc6ccc82a454a2bffcef6e1d7379756ca567c772e4fb3278a", size = 134603 }, - { url = "https://files.pythonhosted.org/packages/03/45/10d934535a4993d27e1c84f1810e79ccf8b1b7418cef12151a22fe9bb1e1/orjson-3.10.18-cp311-cp311-win_arm64.whl", hash = "sha256:a6c7c391beaedd3fa63206e5c2b7b554196f14debf1ec9deb54b5d279b1b46f5", size = 131400 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/57/4d/fe17581cf81fb70dfcef44e966aa4003360e4194d15a3f38cbffe873333a/orjson-3.10.18-cp312-cp312-win32.whl", hash = "sha256:187ec33bbec58c76dbd4066340067d9ece6e10067bb0cc074a21ae3300caa84e", size = 142683 }, - { url = "https://files.pythonhosted.org/packages/e6/22/469f62d25ab5f0f3aee256ea732e72dc3aab6d73bac777bd6277955bceef/orjson-3.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:f9f94cf6d3f9cd720d641f8399e390e7411487e493962213390d1ae45c7814fc", size = 134754 }, - { url = "https://files.pythonhosted.org/packages/10/b0/1040c447fac5b91bc1e9c004b69ee50abb0c1ffd0d24406e1350c58a7fcb/orjson-3.10.18-cp312-cp312-win_arm64.whl", hash = "sha256:3d600be83fe4514944500fa8c2a0a77099025ec6482e8087d7659e891f23058a", size = 131218 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/ad/fd/7f1d3edd4ffcd944a6a40e9f88af2197b619c931ac4d3cfba4798d4d3815/orjson-3.10.18-cp313-cp313-win32.whl", hash = "sha256:ad8eacbb5d904d5591f27dee4031e2c1db43d559edb8f91778efd642d70e6bea", size = 142687 }, - { url = "https://files.pythonhosted.org/packages/4b/03/c75c6ad46be41c16f4cfe0352a2d1450546f3c09ad2c9d341110cd87b025/orjson-3.10.18-cp313-cp313-win_amd64.whl", hash = "sha256:aed411bcb68bf62e85588f2a7e03a6082cc42e5a2796e06e72a962d7c6310b52", size = 134794 }, - { url = "https://files.pythonhosted.org/packages/c2/28/f53038a5a72cc4fd0b56c1eafb4ef64aec9685460d5ac34de98ca78b6e29/orjson-3.10.18-cp313-cp313-win_arm64.whl", hash = "sha256:f54c1385a0e6aba2f15a40d703b858bedad36ded0491e55d35d905b2c34a4cc3", size = 131186 }, +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]] @@ -2869,45 +2947,45 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/98/df/77698abfac98571e65ffeb0c1fba8ffd692ab8458d617a0eed7d9a8d38f2/outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", size = 21060 } +sdist = { url = "https://files.pythonhosted.org/packages/98/df/77698abfac98571e65ffeb0c1fba8ffd692ab8458d617a0eed7d9a8d38f2/outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", size = 21060, upload-time = "2023-10-26T04:26:04.361Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/55/8b/5ab7257531a5d830fc8000c476e63c935488d74609b50f9384a643ec0a62/outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b", size = 10692 }, + { url = "https://files.pythonhosted.org/packages/55/8b/5ab7257531a5d830fc8000c476e63c935488d74609b50f9384a643ec0a62/outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b", size = 10692, upload-time = "2023-10-26T04:26:02.532Z" }, ] [[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 } +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 }, + { 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.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] [[package]] name = "parso" version = "0.8.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609 } +sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609, upload-time = "2024-04-05T09:43:55.897Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650 }, + { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650, upload-time = "2024-04-05T09:43:53.299Z" }, ] [[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 } +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 }, + { 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]] @@ -2918,9 +2996,9 @@ dependencies = [ { name = "charset-normalizer" }, { name = "cryptography" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/e9/4688ff2dd985f21380b9c8cd2fa8004bc0f2691f2c301082d767caea7136/pdfminer_six-20250327.tar.gz", hash = "sha256:57f6c34c2702df04cfa3191622a3db0a922ced686d35283232b00094f8914aa1", size = 7381506 } +sdist = { url = "https://files.pythonhosted.org/packages/08/e9/4688ff2dd985f21380b9c8cd2fa8004bc0f2691f2c301082d767caea7136/pdfminer_six-20250327.tar.gz", hash = "sha256:57f6c34c2702df04cfa3191622a3db0a922ced686d35283232b00094f8914aa1", size = 7381506, upload-time = "2025-03-27T07:51:57.78Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/2f/409e174b5a0195aa6a814c7359a1285f1c887a4c84aff17ed03f607c06ba/pdfminer_six-20250327-py3-none-any.whl", hash = "sha256:5af494c85b1ecb7c28df5e3a26bb5234a8226a307503d9a09f4958bc154b16a9", size = 5617445 }, + { url = "https://files.pythonhosted.org/packages/29/2f/409e174b5a0195aa6a814c7359a1285f1c887a4c84aff17ed03f607c06ba/pdfminer_six-20250327-py3-none-any.whl", hash = "sha256:5af494c85b1ecb7c28df5e3a26bb5234a8226a307503d9a09f4958bc154b16a9", size = 5617445, upload-time = "2025-03-27T07:51:55.502Z" }, ] [[package]] @@ -2932,9 +3010,9 @@ dependencies = [ { name = "pillow" }, { name = "pypdfium2" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/37/dca4c8290c252f530e52e758f58e211bb047b34e15d52703355a357524f4/pdfplumber-0.11.6.tar.gz", hash = "sha256:d0f419e031641d9eac70dc18c60e1fc3ca2ec28cce7e149644923c030a0003ff", size = 115611 } +sdist = { url = "https://files.pythonhosted.org/packages/ce/37/dca4c8290c252f530e52e758f58e211bb047b34e15d52703355a357524f4/pdfplumber-0.11.6.tar.gz", hash = "sha256:d0f419e031641d9eac70dc18c60e1fc3ca2ec28cce7e149644923c030a0003ff", size = 115611, upload-time = "2025-03-28T03:19:02.353Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/c4/d2e09fbc937d1f76baae34e526662cc718e23a904321bf4a40282d190033/pdfplumber-0.11.6-py3-none-any.whl", hash = "sha256:169fc2b8dbf328c81a4e9bab30af0c304ad4b472fd7816616eabdb79dc5d9d17", size = 60233 }, + { url = "https://files.pythonhosted.org/packages/e6/c4/d2e09fbc937d1f76baae34e526662cc718e23a904321bf4a40282d190033/pdfplumber-0.11.6-py3-none-any.whl", hash = "sha256:169fc2b8dbf328c81a4e9bab30af0c304ad4b472fd7816616eabdb79dc5d9d17", size = 60233, upload-time = "2025-03-28T03:19:00.929Z" }, ] [[package]] @@ -2944,104 +3022,104 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ptyprocess" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, ] [[package]] name = "pillow" version = "11.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/cb/bb5c01fcd2a69335b86c22142b2bccfc3464087efb7fd382eee5ffc7fdf7/pillow-11.2.1.tar.gz", hash = "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6", size = 47026707 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/8b/b158ad57ed44d3cc54db8d68ad7c0a58b8fc0e4c7a3f995f9d62d5b464a1/pillow-11.2.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:d57a75d53922fc20c165016a20d9c44f73305e67c351bbc60d1adaf662e74047", size = 3198442 }, - { url = "https://files.pythonhosted.org/packages/b1/f8/bb5d956142f86c2d6cc36704943fa761f2d2e4c48b7436fd0a85c20f1713/pillow-11.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:127bf6ac4a5b58b3d32fc8289656f77f80567d65660bc46f72c0d77e6600cc95", size = 3030553 }, - { url = "https://files.pythonhosted.org/packages/22/7f/0e413bb3e2aa797b9ca2c5c38cb2e2e45d88654e5b12da91ad446964cfae/pillow-11.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ba4be812c7a40280629e55ae0b14a0aafa150dd6451297562e1764808bbe61", size = 4405503 }, - { url = "https://files.pythonhosted.org/packages/f3/b4/cc647f4d13f3eb837d3065824aa58b9bcf10821f029dc79955ee43f793bd/pillow-11.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8bd62331e5032bc396a93609982a9ab6b411c05078a52f5fe3cc59234a3abd1", size = 4490648 }, - { url = "https://files.pythonhosted.org/packages/c2/6f/240b772a3b35cdd7384166461567aa6713799b4e78d180c555bd284844ea/pillow-11.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:562d11134c97a62fe3af29581f083033179f7ff435f78392565a1ad2d1c2c45c", size = 4508937 }, - { url = "https://files.pythonhosted.org/packages/f3/5e/7ca9c815ade5fdca18853db86d812f2f188212792780208bdb37a0a6aef4/pillow-11.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:c97209e85b5be259994eb5b69ff50c5d20cca0f458ef9abd835e262d9d88b39d", size = 4599802 }, - { url = "https://files.pythonhosted.org/packages/02/81/c3d9d38ce0c4878a77245d4cf2c46d45a4ad0f93000227910a46caff52f3/pillow-11.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0c3e6d0f59171dfa2e25d7116217543310908dfa2770aa64b8f87605f8cacc97", size = 4576717 }, - { url = "https://files.pythonhosted.org/packages/42/49/52b719b89ac7da3185b8d29c94d0e6aec8140059e3d8adcaa46da3751180/pillow-11.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc1c3bc53befb6096b84165956e886b1729634a799e9d6329a0c512ab651e579", size = 4654874 }, - { url = "https://files.pythonhosted.org/packages/5b/0b/ede75063ba6023798267023dc0d0401f13695d228194d2242d5a7ba2f964/pillow-11.2.1-cp310-cp310-win32.whl", hash = "sha256:312c77b7f07ab2139924d2639860e084ec2a13e72af54d4f08ac843a5fc9c79d", size = 2331717 }, - { url = "https://files.pythonhosted.org/packages/ed/3c/9831da3edea527c2ed9a09f31a2c04e77cd705847f13b69ca60269eec370/pillow-11.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9bc7ae48b8057a611e5fe9f853baa88093b9a76303937449397899385da06fad", size = 2676204 }, - { url = "https://files.pythonhosted.org/packages/01/97/1f66ff8a1503d8cbfc5bae4dc99d54c6ec1e22ad2b946241365320caabc2/pillow-11.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:2728567e249cdd939f6cc3d1f049595c66e4187f3c34078cbc0a7d21c47482d2", size = 2414767 }, - { url = "https://files.pythonhosted.org/packages/68/08/3fbf4b98924c73037a8e8b4c2c774784805e0fb4ebca6c5bb60795c40125/pillow-11.2.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35ca289f712ccfc699508c4658a1d14652e8033e9b69839edf83cbdd0ba39e70", size = 3198450 }, - { url = "https://files.pythonhosted.org/packages/84/92/6505b1af3d2849d5e714fc75ba9e69b7255c05ee42383a35a4d58f576b16/pillow-11.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0409af9f829f87a2dfb7e259f78f317a5351f2045158be321fd135973fff7bf", size = 3030550 }, - { url = "https://files.pythonhosted.org/packages/3c/8c/ac2f99d2a70ff966bc7eb13dacacfaab57c0549b2ffb351b6537c7840b12/pillow-11.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4e5c5edee874dce4f653dbe59db7c73a600119fbea8d31f53423586ee2aafd7", size = 4415018 }, - { url = "https://files.pythonhosted.org/packages/1f/e3/0a58b5d838687f40891fff9cbaf8669f90c96b64dc8f91f87894413856c6/pillow-11.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b93a07e76d13bff9444f1a029e0af2964e654bfc2e2c2d46bfd080df5ad5f3d8", size = 4498006 }, - { url = "https://files.pythonhosted.org/packages/21/f5/6ba14718135f08fbfa33308efe027dd02b781d3f1d5c471444a395933aac/pillow-11.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:e6def7eed9e7fa90fde255afaf08060dc4b343bbe524a8f69bdd2a2f0018f600", size = 4517773 }, - { url = "https://files.pythonhosted.org/packages/20/f2/805ad600fc59ebe4f1ba6129cd3a75fb0da126975c8579b8f57abeb61e80/pillow-11.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8f4f3724c068be008c08257207210c138d5f3731af6c155a81c2b09a9eb3a788", size = 4607069 }, - { url = "https://files.pythonhosted.org/packages/71/6b/4ef8a288b4bb2e0180cba13ca0a519fa27aa982875882392b65131401099/pillow-11.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a0a6709b47019dff32e678bc12c63008311b82b9327613f534e496dacaefb71e", size = 4583460 }, - { url = "https://files.pythonhosted.org/packages/62/ae/f29c705a09cbc9e2a456590816e5c234382ae5d32584f451c3eb41a62062/pillow-11.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f6b0c664ccb879109ee3ca702a9272d877f4fcd21e5eb63c26422fd6e415365e", size = 4661304 }, - { url = "https://files.pythonhosted.org/packages/6e/1a/c8217b6f2f73794a5e219fbad087701f412337ae6dbb956db37d69a9bc43/pillow-11.2.1-cp311-cp311-win32.whl", hash = "sha256:cc5d875d56e49f112b6def6813c4e3d3036d269c008bf8aef72cd08d20ca6df6", size = 2331809 }, - { url = "https://files.pythonhosted.org/packages/e2/72/25a8f40170dc262e86e90f37cb72cb3de5e307f75bf4b02535a61afcd519/pillow-11.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:0f5c7eda47bf8e3c8a283762cab94e496ba977a420868cb819159980b6709193", size = 2676338 }, - { url = "https://files.pythonhosted.org/packages/06/9e/76825e39efee61efea258b479391ca77d64dbd9e5804e4ad0fa453b4ba55/pillow-11.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:4d375eb838755f2528ac8cbc926c3e31cc49ca4ad0cf79cff48b20e30634a4a7", size = 2414918 }, - { url = "https://files.pythonhosted.org/packages/c7/40/052610b15a1b8961f52537cc8326ca6a881408bc2bdad0d852edeb6ed33b/pillow-11.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:78afba22027b4accef10dbd5eed84425930ba41b3ea0a86fa8d20baaf19d807f", size = 3190185 }, - { url = "https://files.pythonhosted.org/packages/e5/7e/b86dbd35a5f938632093dc40d1682874c33dcfe832558fc80ca56bfcb774/pillow-11.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78092232a4ab376a35d68c4e6d5e00dfd73454bd12b230420025fbe178ee3b0b", size = 3030306 }, - { url = "https://files.pythonhosted.org/packages/a4/5c/467a161f9ed53e5eab51a42923c33051bf8d1a2af4626ac04f5166e58e0c/pillow-11.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a5f306095c6780c52e6bbb6109624b95c5b18e40aab1c3041da3e9e0cd3e2d", size = 4416121 }, - { url = "https://files.pythonhosted.org/packages/62/73/972b7742e38ae0e2ac76ab137ca6005dcf877480da0d9d61d93b613065b4/pillow-11.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c7b29dbd4281923a2bfe562acb734cee96bbb129e96e6972d315ed9f232bef4", size = 4501707 }, - { url = "https://files.pythonhosted.org/packages/e4/3a/427e4cb0b9e177efbc1a84798ed20498c4f233abde003c06d2650a6d60cb/pillow-11.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e645b020f3209a0181a418bffe7b4a93171eef6c4ef6cc20980b30bebf17b7d", size = 4522921 }, - { url = "https://files.pythonhosted.org/packages/fe/7c/d8b1330458e4d2f3f45d9508796d7caf0c0d3764c00c823d10f6f1a3b76d/pillow-11.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2dbea1012ccb784a65349f57bbc93730b96e85b42e9bf7b01ef40443db720b4", size = 4612523 }, - { url = "https://files.pythonhosted.org/packages/b3/2f/65738384e0b1acf451de5a573d8153fe84103772d139e1e0bdf1596be2ea/pillow-11.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:da3104c57bbd72948d75f6a9389e6727d2ab6333c3617f0a89d72d4940aa0443", size = 4587836 }, - { url = "https://files.pythonhosted.org/packages/6a/c5/e795c9f2ddf3debb2dedd0df889f2fe4b053308bb59a3cc02a0cd144d641/pillow-11.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:598174aef4589af795f66f9caab87ba4ff860ce08cd5bb447c6fc553ffee603c", size = 4669390 }, - { url = "https://files.pythonhosted.org/packages/96/ae/ca0099a3995976a9fce2f423166f7bff9b12244afdc7520f6ed38911539a/pillow-11.2.1-cp312-cp312-win32.whl", hash = "sha256:1d535df14716e7f8776b9e7fee118576d65572b4aad3ed639be9e4fa88a1cad3", size = 2332309 }, - { url = "https://files.pythonhosted.org/packages/7c/18/24bff2ad716257fc03da964c5e8f05d9790a779a8895d6566e493ccf0189/pillow-11.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:14e33b28bf17c7a38eede290f77db7c664e4eb01f7869e37fa98a5aa95978941", size = 2676768 }, - { url = "https://files.pythonhosted.org/packages/da/bb/e8d656c9543276517ee40184aaa39dcb41e683bca121022f9323ae11b39d/pillow-11.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:21e1470ac9e5739ff880c211fc3af01e3ae505859392bf65458c224d0bf283eb", size = 2415087 }, - { url = "https://files.pythonhosted.org/packages/36/9c/447528ee3776e7ab8897fe33697a7ff3f0475bb490c5ac1456a03dc57956/pillow-11.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fdec757fea0b793056419bca3e9932eb2b0ceec90ef4813ea4c1e072c389eb28", size = 3190098 }, - { url = "https://files.pythonhosted.org/packages/b5/09/29d5cd052f7566a63e5b506fac9c60526e9ecc553825551333e1e18a4858/pillow-11.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0e130705d568e2f43a17bcbe74d90958e8a16263868a12c3e0d9c8162690830", size = 3030166 }, - { url = "https://files.pythonhosted.org/packages/71/5d/446ee132ad35e7600652133f9c2840b4799bbd8e4adba881284860da0a36/pillow-11.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdb5e09068332578214cadd9c05e3d64d99e0e87591be22a324bdbc18925be0", size = 4408674 }, - { url = "https://files.pythonhosted.org/packages/69/5f/cbe509c0ddf91cc3a03bbacf40e5c2339c4912d16458fcb797bb47bcb269/pillow-11.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d189ba1bebfbc0c0e529159631ec72bb9e9bc041f01ec6d3233d6d82eb823bc1", size = 4496005 }, - { url = "https://files.pythonhosted.org/packages/f9/b3/dd4338d8fb8a5f312021f2977fb8198a1184893f9b00b02b75d565c33b51/pillow-11.2.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:191955c55d8a712fab8934a42bfefbf99dd0b5875078240943f913bb66d46d9f", size = 4518707 }, - { url = "https://files.pythonhosted.org/packages/13/eb/2552ecebc0b887f539111c2cd241f538b8ff5891b8903dfe672e997529be/pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155", size = 4610008 }, - { url = "https://files.pythonhosted.org/packages/72/d1/924ce51bea494cb6e7959522d69d7b1c7e74f6821d84c63c3dc430cbbf3b/pillow-11.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:750f96efe0597382660d8b53e90dd1dd44568a8edb51cb7f9d5d918b80d4de14", size = 4585420 }, - { url = "https://files.pythonhosted.org/packages/43/ab/8f81312d255d713b99ca37479a4cb4b0f48195e530cdc1611990eb8fd04b/pillow-11.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fe15238d3798788d00716637b3d4e7bb6bde18b26e5d08335a96e88564a36b6b", size = 4667655 }, - { url = "https://files.pythonhosted.org/packages/94/86/8f2e9d2dc3d308dfd137a07fe1cc478df0a23d42a6c4093b087e738e4827/pillow-11.2.1-cp313-cp313-win32.whl", hash = "sha256:3fe735ced9a607fee4f481423a9c36701a39719252a9bb251679635f99d0f7d2", size = 2332329 }, - { url = "https://files.pythonhosted.org/packages/6d/ec/1179083b8d6067a613e4d595359b5fdea65d0a3b7ad623fee906e1b3c4d2/pillow-11.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:74ee3d7ecb3f3c05459ba95eed5efa28d6092d751ce9bf20e3e253a4e497e691", size = 2676388 }, - { url = "https://files.pythonhosted.org/packages/23/f1/2fc1e1e294de897df39fa8622d829b8828ddad938b0eaea256d65b84dd72/pillow-11.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:5119225c622403afb4b44bad4c1ca6c1f98eed79db8d3bc6e4e160fc6339d66c", size = 2414950 }, - { url = "https://files.pythonhosted.org/packages/c4/3e/c328c48b3f0ead7bab765a84b4977acb29f101d10e4ef57a5e3400447c03/pillow-11.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8ce2e8411c7aaef53e6bb29fe98f28cd4fbd9a1d9be2eeea434331aac0536b22", size = 3192759 }, - { url = "https://files.pythonhosted.org/packages/18/0e/1c68532d833fc8b9f404d3a642991441d9058eccd5606eab31617f29b6d4/pillow-11.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9ee66787e095127116d91dea2143db65c7bb1e232f617aa5957c0d9d2a3f23a7", size = 3033284 }, - { url = "https://files.pythonhosted.org/packages/b7/cb/6faf3fb1e7705fd2db74e070f3bf6f88693601b0ed8e81049a8266de4754/pillow-11.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9622e3b6c1d8b551b6e6f21873bdcc55762b4b2126633014cea1803368a9aa16", size = 4445826 }, - { url = "https://files.pythonhosted.org/packages/07/94/8be03d50b70ca47fb434a358919d6a8d6580f282bbb7af7e4aa40103461d/pillow-11.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63b5dff3a68f371ea06025a1a6966c9a1e1ee452fc8020c2cd0ea41b83e9037b", size = 4527329 }, - { url = "https://files.pythonhosted.org/packages/fd/a4/bfe78777076dc405e3bd2080bc32da5ab3945b5a25dc5d8acaa9de64a162/pillow-11.2.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:31df6e2d3d8fc99f993fd253e97fae451a8db2e7207acf97859732273e108406", size = 4549049 }, - { url = "https://files.pythonhosted.org/packages/65/4d/eaf9068dc687c24979e977ce5677e253624bd8b616b286f543f0c1b91662/pillow-11.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:062b7a42d672c45a70fa1f8b43d1d38ff76b63421cbbe7f88146b39e8a558d91", size = 4635408 }, - { url = "https://files.pythonhosted.org/packages/1d/26/0fd443365d9c63bc79feb219f97d935cd4b93af28353cba78d8e77b61719/pillow-11.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4eb92eca2711ef8be42fd3f67533765d9fd043b8c80db204f16c8ea62ee1a751", size = 4614863 }, - { url = "https://files.pythonhosted.org/packages/49/65/dca4d2506be482c2c6641cacdba5c602bc76d8ceb618fd37de855653a419/pillow-11.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f91ebf30830a48c825590aede79376cb40f110b387c17ee9bd59932c961044f9", size = 4692938 }, - { url = "https://files.pythonhosted.org/packages/b3/92/1ca0c3f09233bd7decf8f7105a1c4e3162fb9142128c74adad0fb361b7eb/pillow-11.2.1-cp313-cp313t-win32.whl", hash = "sha256:e0b55f27f584ed623221cfe995c912c61606be8513bfa0e07d2c674b4516d9dd", size = 2335774 }, - { url = "https://files.pythonhosted.org/packages/a5/ac/77525347cb43b83ae905ffe257bbe2cc6fd23acb9796639a1f56aa59d191/pillow-11.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:36d6b82164c39ce5482f649b437382c0fb2395eabc1e2b1702a6deb8ad647d6e", size = 2681895 }, - { url = "https://files.pythonhosted.org/packages/67/32/32dc030cfa91ca0fc52baebbba2e009bb001122a1daa8b6a79ad830b38d3/pillow-11.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:225c832a13326e34f212d2072982bb1adb210e0cc0b153e688743018c94a2681", size = 2417234 }, - { url = "https://files.pythonhosted.org/packages/33/49/c8c21e4255b4f4a2c0c68ac18125d7f5460b109acc6dfdef1a24f9b960ef/pillow-11.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9b7b0d4fd2635f54ad82785d56bc0d94f147096493a79985d0ab57aedd563156", size = 3181727 }, - { url = "https://files.pythonhosted.org/packages/6d/f1/f7255c0838f8c1ef6d55b625cfb286835c17e8136ce4351c5577d02c443b/pillow-11.2.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:aa442755e31c64037aa7c1cb186e0b369f8416c567381852c63444dd666fb772", size = 2999833 }, - { url = "https://files.pythonhosted.org/packages/e2/57/9968114457bd131063da98d87790d080366218f64fa2943b65ac6739abb3/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d3348c95b766f54b76116d53d4cb171b52992a1027e7ca50c81b43b9d9e363", size = 3437472 }, - { url = "https://files.pythonhosted.org/packages/b2/1b/e35d8a158e21372ecc48aac9c453518cfe23907bb82f950d6e1c72811eb0/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85d27ea4c889342f7e35f6d56e7e1cb345632ad592e8c51b693d7b7556043ce0", size = 3459976 }, - { url = "https://files.pythonhosted.org/packages/26/da/2c11d03b765efff0ccc473f1c4186dc2770110464f2177efaed9cf6fae01/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bf2c33d6791c598142f00c9c4c7d47f6476731c31081331664eb26d6ab583e01", size = 3527133 }, - { url = "https://files.pythonhosted.org/packages/79/1a/4e85bd7cadf78412c2a3069249a09c32ef3323650fd3005c97cca7aa21df/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e616e7154c37669fc1dfc14584f11e284e05d1c650e1c0f972f281c4ccc53193", size = 3571555 }, - { url = "https://files.pythonhosted.org/packages/69/03/239939915216de1e95e0ce2334bf17a7870ae185eb390fab6d706aadbfc0/pillow-11.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39ad2e0f424394e3aebc40168845fee52df1394a4673a6ee512d840d14ab3013", size = 2674713 }, - { url = "https://files.pythonhosted.org/packages/a4/ad/2613c04633c7257d9481ab21d6b5364b59fc5d75faafd7cb8693523945a3/pillow-11.2.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:80f1df8dbe9572b4b7abdfa17eb5d78dd620b1d55d9e25f834efdbee872d3aed", size = 3181734 }, - { url = "https://files.pythonhosted.org/packages/a4/fd/dcdda4471ed667de57bb5405bb42d751e6cfdd4011a12c248b455c778e03/pillow-11.2.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ea926cfbc3957090becbcbbb65ad177161a2ff2ad578b5a6ec9bb1e1cd78753c", size = 2999841 }, - { url = "https://files.pythonhosted.org/packages/ac/89/8a2536e95e77432833f0db6fd72a8d310c8e4272a04461fb833eb021bf94/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:738db0e0941ca0376804d4de6a782c005245264edaa253ffce24e5a15cbdc7bd", size = 3437470 }, - { url = "https://files.pythonhosted.org/packages/9d/8f/abd47b73c60712f88e9eda32baced7bfc3e9bd6a7619bb64b93acff28c3e/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db98ab6565c69082ec9b0d4e40dd9f6181dab0dd236d26f7a50b8b9bfbd5076", size = 3460013 }, - { url = "https://files.pythonhosted.org/packages/f6/20/5c0a0aa83b213b7a07ec01e71a3d6ea2cf4ad1d2c686cc0168173b6089e7/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:036e53f4170e270ddb8797d4c590e6dd14d28e15c7da375c18978045f7e6c37b", size = 3527165 }, - { url = "https://files.pythonhosted.org/packages/58/0e/2abab98a72202d91146abc839e10c14f7cf36166f12838ea0c4db3ca6ecb/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14f73f7c291279bd65fda51ee87affd7c1e097709f7fdd0188957a16c264601f", size = 3571586 }, - { url = "https://files.pythonhosted.org/packages/21/2c/5e05f58658cf49b6667762cca03d6e7d85cededde2caf2ab37b81f80e574/pillow-11.2.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:208653868d5c9ecc2b327f9b9ef34e0e42a4cdd172c2988fd81d62d2bc9bc044", size = 2674751 }, +sdist = { url = "https://files.pythonhosted.org/packages/af/cb/bb5c01fcd2a69335b86c22142b2bccfc3464087efb7fd382eee5ffc7fdf7/pillow-11.2.1.tar.gz", hash = "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6", size = 47026707, upload-time = "2025-04-12T17:50:03.289Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/8b/b158ad57ed44d3cc54db8d68ad7c0a58b8fc0e4c7a3f995f9d62d5b464a1/pillow-11.2.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:d57a75d53922fc20c165016a20d9c44f73305e67c351bbc60d1adaf662e74047", size = 3198442, upload-time = "2025-04-12T17:47:10.666Z" }, + { url = "https://files.pythonhosted.org/packages/b1/f8/bb5d956142f86c2d6cc36704943fa761f2d2e4c48b7436fd0a85c20f1713/pillow-11.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:127bf6ac4a5b58b3d32fc8289656f77f80567d65660bc46f72c0d77e6600cc95", size = 3030553, upload-time = "2025-04-12T17:47:13.153Z" }, + { url = "https://files.pythonhosted.org/packages/22/7f/0e413bb3e2aa797b9ca2c5c38cb2e2e45d88654e5b12da91ad446964cfae/pillow-11.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ba4be812c7a40280629e55ae0b14a0aafa150dd6451297562e1764808bbe61", size = 4405503, upload-time = "2025-04-12T17:47:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/f3/b4/cc647f4d13f3eb837d3065824aa58b9bcf10821f029dc79955ee43f793bd/pillow-11.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8bd62331e5032bc396a93609982a9ab6b411c05078a52f5fe3cc59234a3abd1", size = 4490648, upload-time = "2025-04-12T17:47:17.37Z" }, + { url = "https://files.pythonhosted.org/packages/c2/6f/240b772a3b35cdd7384166461567aa6713799b4e78d180c555bd284844ea/pillow-11.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:562d11134c97a62fe3af29581f083033179f7ff435f78392565a1ad2d1c2c45c", size = 4508937, upload-time = "2025-04-12T17:47:19.066Z" }, + { url = "https://files.pythonhosted.org/packages/f3/5e/7ca9c815ade5fdca18853db86d812f2f188212792780208bdb37a0a6aef4/pillow-11.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:c97209e85b5be259994eb5b69ff50c5d20cca0f458ef9abd835e262d9d88b39d", size = 4599802, upload-time = "2025-04-12T17:47:21.404Z" }, + { url = "https://files.pythonhosted.org/packages/02/81/c3d9d38ce0c4878a77245d4cf2c46d45a4ad0f93000227910a46caff52f3/pillow-11.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0c3e6d0f59171dfa2e25d7116217543310908dfa2770aa64b8f87605f8cacc97", size = 4576717, upload-time = "2025-04-12T17:47:23.571Z" }, + { url = "https://files.pythonhosted.org/packages/42/49/52b719b89ac7da3185b8d29c94d0e6aec8140059e3d8adcaa46da3751180/pillow-11.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc1c3bc53befb6096b84165956e886b1729634a799e9d6329a0c512ab651e579", size = 4654874, upload-time = "2025-04-12T17:47:25.783Z" }, + { url = "https://files.pythonhosted.org/packages/5b/0b/ede75063ba6023798267023dc0d0401f13695d228194d2242d5a7ba2f964/pillow-11.2.1-cp310-cp310-win32.whl", hash = "sha256:312c77b7f07ab2139924d2639860e084ec2a13e72af54d4f08ac843a5fc9c79d", size = 2331717, upload-time = "2025-04-12T17:47:28.922Z" }, + { url = "https://files.pythonhosted.org/packages/ed/3c/9831da3edea527c2ed9a09f31a2c04e77cd705847f13b69ca60269eec370/pillow-11.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9bc7ae48b8057a611e5fe9f853baa88093b9a76303937449397899385da06fad", size = 2676204, upload-time = "2025-04-12T17:47:31.283Z" }, + { url = "https://files.pythonhosted.org/packages/01/97/1f66ff8a1503d8cbfc5bae4dc99d54c6ec1e22ad2b946241365320caabc2/pillow-11.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:2728567e249cdd939f6cc3d1f049595c66e4187f3c34078cbc0a7d21c47482d2", size = 2414767, upload-time = "2025-04-12T17:47:34.655Z" }, + { url = "https://files.pythonhosted.org/packages/68/08/3fbf4b98924c73037a8e8b4c2c774784805e0fb4ebca6c5bb60795c40125/pillow-11.2.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35ca289f712ccfc699508c4658a1d14652e8033e9b69839edf83cbdd0ba39e70", size = 3198450, upload-time = "2025-04-12T17:47:37.135Z" }, + { url = "https://files.pythonhosted.org/packages/84/92/6505b1af3d2849d5e714fc75ba9e69b7255c05ee42383a35a4d58f576b16/pillow-11.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0409af9f829f87a2dfb7e259f78f317a5351f2045158be321fd135973fff7bf", size = 3030550, upload-time = "2025-04-12T17:47:39.345Z" }, + { url = "https://files.pythonhosted.org/packages/3c/8c/ac2f99d2a70ff966bc7eb13dacacfaab57c0549b2ffb351b6537c7840b12/pillow-11.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4e5c5edee874dce4f653dbe59db7c73a600119fbea8d31f53423586ee2aafd7", size = 4415018, upload-time = "2025-04-12T17:47:41.128Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e3/0a58b5d838687f40891fff9cbaf8669f90c96b64dc8f91f87894413856c6/pillow-11.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b93a07e76d13bff9444f1a029e0af2964e654bfc2e2c2d46bfd080df5ad5f3d8", size = 4498006, upload-time = "2025-04-12T17:47:42.912Z" }, + { url = "https://files.pythonhosted.org/packages/21/f5/6ba14718135f08fbfa33308efe027dd02b781d3f1d5c471444a395933aac/pillow-11.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:e6def7eed9e7fa90fde255afaf08060dc4b343bbe524a8f69bdd2a2f0018f600", size = 4517773, upload-time = "2025-04-12T17:47:44.611Z" }, + { url = "https://files.pythonhosted.org/packages/20/f2/805ad600fc59ebe4f1ba6129cd3a75fb0da126975c8579b8f57abeb61e80/pillow-11.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8f4f3724c068be008c08257207210c138d5f3731af6c155a81c2b09a9eb3a788", size = 4607069, upload-time = "2025-04-12T17:47:46.46Z" }, + { url = "https://files.pythonhosted.org/packages/71/6b/4ef8a288b4bb2e0180cba13ca0a519fa27aa982875882392b65131401099/pillow-11.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a0a6709b47019dff32e678bc12c63008311b82b9327613f534e496dacaefb71e", size = 4583460, upload-time = "2025-04-12T17:47:49.255Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/f29c705a09cbc9e2a456590816e5c234382ae5d32584f451c3eb41a62062/pillow-11.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f6b0c664ccb879109ee3ca702a9272d877f4fcd21e5eb63c26422fd6e415365e", size = 4661304, upload-time = "2025-04-12T17:47:51.067Z" }, + { url = "https://files.pythonhosted.org/packages/6e/1a/c8217b6f2f73794a5e219fbad087701f412337ae6dbb956db37d69a9bc43/pillow-11.2.1-cp311-cp311-win32.whl", hash = "sha256:cc5d875d56e49f112b6def6813c4e3d3036d269c008bf8aef72cd08d20ca6df6", size = 2331809, upload-time = "2025-04-12T17:47:54.425Z" }, + { url = "https://files.pythonhosted.org/packages/e2/72/25a8f40170dc262e86e90f37cb72cb3de5e307f75bf4b02535a61afcd519/pillow-11.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:0f5c7eda47bf8e3c8a283762cab94e496ba977a420868cb819159980b6709193", size = 2676338, upload-time = "2025-04-12T17:47:56.535Z" }, + { url = "https://files.pythonhosted.org/packages/06/9e/76825e39efee61efea258b479391ca77d64dbd9e5804e4ad0fa453b4ba55/pillow-11.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:4d375eb838755f2528ac8cbc926c3e31cc49ca4ad0cf79cff48b20e30634a4a7", size = 2414918, upload-time = "2025-04-12T17:47:58.217Z" }, + { url = "https://files.pythonhosted.org/packages/c7/40/052610b15a1b8961f52537cc8326ca6a881408bc2bdad0d852edeb6ed33b/pillow-11.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:78afba22027b4accef10dbd5eed84425930ba41b3ea0a86fa8d20baaf19d807f", size = 3190185, upload-time = "2025-04-12T17:48:00.417Z" }, + { url = "https://files.pythonhosted.org/packages/e5/7e/b86dbd35a5f938632093dc40d1682874c33dcfe832558fc80ca56bfcb774/pillow-11.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78092232a4ab376a35d68c4e6d5e00dfd73454bd12b230420025fbe178ee3b0b", size = 3030306, upload-time = "2025-04-12T17:48:02.391Z" }, + { url = "https://files.pythonhosted.org/packages/a4/5c/467a161f9ed53e5eab51a42923c33051bf8d1a2af4626ac04f5166e58e0c/pillow-11.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a5f306095c6780c52e6bbb6109624b95c5b18e40aab1c3041da3e9e0cd3e2d", size = 4416121, upload-time = "2025-04-12T17:48:04.554Z" }, + { url = "https://files.pythonhosted.org/packages/62/73/972b7742e38ae0e2ac76ab137ca6005dcf877480da0d9d61d93b613065b4/pillow-11.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c7b29dbd4281923a2bfe562acb734cee96bbb129e96e6972d315ed9f232bef4", size = 4501707, upload-time = "2025-04-12T17:48:06.831Z" }, + { url = "https://files.pythonhosted.org/packages/e4/3a/427e4cb0b9e177efbc1a84798ed20498c4f233abde003c06d2650a6d60cb/pillow-11.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e645b020f3209a0181a418bffe7b4a93171eef6c4ef6cc20980b30bebf17b7d", size = 4522921, upload-time = "2025-04-12T17:48:09.229Z" }, + { url = "https://files.pythonhosted.org/packages/fe/7c/d8b1330458e4d2f3f45d9508796d7caf0c0d3764c00c823d10f6f1a3b76d/pillow-11.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2dbea1012ccb784a65349f57bbc93730b96e85b42e9bf7b01ef40443db720b4", size = 4612523, upload-time = "2025-04-12T17:48:11.631Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2f/65738384e0b1acf451de5a573d8153fe84103772d139e1e0bdf1596be2ea/pillow-11.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:da3104c57bbd72948d75f6a9389e6727d2ab6333c3617f0a89d72d4940aa0443", size = 4587836, upload-time = "2025-04-12T17:48:13.592Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c5/e795c9f2ddf3debb2dedd0df889f2fe4b053308bb59a3cc02a0cd144d641/pillow-11.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:598174aef4589af795f66f9caab87ba4ff860ce08cd5bb447c6fc553ffee603c", size = 4669390, upload-time = "2025-04-12T17:48:15.938Z" }, + { url = "https://files.pythonhosted.org/packages/96/ae/ca0099a3995976a9fce2f423166f7bff9b12244afdc7520f6ed38911539a/pillow-11.2.1-cp312-cp312-win32.whl", hash = "sha256:1d535df14716e7f8776b9e7fee118576d65572b4aad3ed639be9e4fa88a1cad3", size = 2332309, upload-time = "2025-04-12T17:48:17.885Z" }, + { url = "https://files.pythonhosted.org/packages/7c/18/24bff2ad716257fc03da964c5e8f05d9790a779a8895d6566e493ccf0189/pillow-11.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:14e33b28bf17c7a38eede290f77db7c664e4eb01f7869e37fa98a5aa95978941", size = 2676768, upload-time = "2025-04-12T17:48:19.655Z" }, + { url = "https://files.pythonhosted.org/packages/da/bb/e8d656c9543276517ee40184aaa39dcb41e683bca121022f9323ae11b39d/pillow-11.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:21e1470ac9e5739ff880c211fc3af01e3ae505859392bf65458c224d0bf283eb", size = 2415087, upload-time = "2025-04-12T17:48:21.991Z" }, + { url = "https://files.pythonhosted.org/packages/36/9c/447528ee3776e7ab8897fe33697a7ff3f0475bb490c5ac1456a03dc57956/pillow-11.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fdec757fea0b793056419bca3e9932eb2b0ceec90ef4813ea4c1e072c389eb28", size = 3190098, upload-time = "2025-04-12T17:48:23.915Z" }, + { url = "https://files.pythonhosted.org/packages/b5/09/29d5cd052f7566a63e5b506fac9c60526e9ecc553825551333e1e18a4858/pillow-11.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0e130705d568e2f43a17bcbe74d90958e8a16263868a12c3e0d9c8162690830", size = 3030166, upload-time = "2025-04-12T17:48:25.738Z" }, + { url = "https://files.pythonhosted.org/packages/71/5d/446ee132ad35e7600652133f9c2840b4799bbd8e4adba881284860da0a36/pillow-11.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdb5e09068332578214cadd9c05e3d64d99e0e87591be22a324bdbc18925be0", size = 4408674, upload-time = "2025-04-12T17:48:27.908Z" }, + { url = "https://files.pythonhosted.org/packages/69/5f/cbe509c0ddf91cc3a03bbacf40e5c2339c4912d16458fcb797bb47bcb269/pillow-11.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d189ba1bebfbc0c0e529159631ec72bb9e9bc041f01ec6d3233d6d82eb823bc1", size = 4496005, upload-time = "2025-04-12T17:48:29.888Z" }, + { url = "https://files.pythonhosted.org/packages/f9/b3/dd4338d8fb8a5f312021f2977fb8198a1184893f9b00b02b75d565c33b51/pillow-11.2.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:191955c55d8a712fab8934a42bfefbf99dd0b5875078240943f913bb66d46d9f", size = 4518707, upload-time = "2025-04-12T17:48:31.874Z" }, + { url = "https://files.pythonhosted.org/packages/13/eb/2552ecebc0b887f539111c2cd241f538b8ff5891b8903dfe672e997529be/pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155", size = 4610008, upload-time = "2025-04-12T17:48:34.422Z" }, + { url = "https://files.pythonhosted.org/packages/72/d1/924ce51bea494cb6e7959522d69d7b1c7e74f6821d84c63c3dc430cbbf3b/pillow-11.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:750f96efe0597382660d8b53e90dd1dd44568a8edb51cb7f9d5d918b80d4de14", size = 4585420, upload-time = "2025-04-12T17:48:37.641Z" }, + { url = "https://files.pythonhosted.org/packages/43/ab/8f81312d255d713b99ca37479a4cb4b0f48195e530cdc1611990eb8fd04b/pillow-11.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fe15238d3798788d00716637b3d4e7bb6bde18b26e5d08335a96e88564a36b6b", size = 4667655, upload-time = "2025-04-12T17:48:39.652Z" }, + { url = "https://files.pythonhosted.org/packages/94/86/8f2e9d2dc3d308dfd137a07fe1cc478df0a23d42a6c4093b087e738e4827/pillow-11.2.1-cp313-cp313-win32.whl", hash = "sha256:3fe735ced9a607fee4f481423a9c36701a39719252a9bb251679635f99d0f7d2", size = 2332329, upload-time = "2025-04-12T17:48:41.765Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ec/1179083b8d6067a613e4d595359b5fdea65d0a3b7ad623fee906e1b3c4d2/pillow-11.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:74ee3d7ecb3f3c05459ba95eed5efa28d6092d751ce9bf20e3e253a4e497e691", size = 2676388, upload-time = "2025-04-12T17:48:43.625Z" }, + { url = "https://files.pythonhosted.org/packages/23/f1/2fc1e1e294de897df39fa8622d829b8828ddad938b0eaea256d65b84dd72/pillow-11.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:5119225c622403afb4b44bad4c1ca6c1f98eed79db8d3bc6e4e160fc6339d66c", size = 2414950, upload-time = "2025-04-12T17:48:45.475Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3e/c328c48b3f0ead7bab765a84b4977acb29f101d10e4ef57a5e3400447c03/pillow-11.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8ce2e8411c7aaef53e6bb29fe98f28cd4fbd9a1d9be2eeea434331aac0536b22", size = 3192759, upload-time = "2025-04-12T17:48:47.866Z" }, + { url = "https://files.pythonhosted.org/packages/18/0e/1c68532d833fc8b9f404d3a642991441d9058eccd5606eab31617f29b6d4/pillow-11.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9ee66787e095127116d91dea2143db65c7bb1e232f617aa5957c0d9d2a3f23a7", size = 3033284, upload-time = "2025-04-12T17:48:50.189Z" }, + { url = "https://files.pythonhosted.org/packages/b7/cb/6faf3fb1e7705fd2db74e070f3bf6f88693601b0ed8e81049a8266de4754/pillow-11.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9622e3b6c1d8b551b6e6f21873bdcc55762b4b2126633014cea1803368a9aa16", size = 4445826, upload-time = "2025-04-12T17:48:52.346Z" }, + { url = "https://files.pythonhosted.org/packages/07/94/8be03d50b70ca47fb434a358919d6a8d6580f282bbb7af7e4aa40103461d/pillow-11.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63b5dff3a68f371ea06025a1a6966c9a1e1ee452fc8020c2cd0ea41b83e9037b", size = 4527329, upload-time = "2025-04-12T17:48:54.403Z" }, + { url = "https://files.pythonhosted.org/packages/fd/a4/bfe78777076dc405e3bd2080bc32da5ab3945b5a25dc5d8acaa9de64a162/pillow-11.2.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:31df6e2d3d8fc99f993fd253e97fae451a8db2e7207acf97859732273e108406", size = 4549049, upload-time = "2025-04-12T17:48:56.383Z" }, + { url = "https://files.pythonhosted.org/packages/65/4d/eaf9068dc687c24979e977ce5677e253624bd8b616b286f543f0c1b91662/pillow-11.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:062b7a42d672c45a70fa1f8b43d1d38ff76b63421cbbe7f88146b39e8a558d91", size = 4635408, upload-time = "2025-04-12T17:48:58.782Z" }, + { url = "https://files.pythonhosted.org/packages/1d/26/0fd443365d9c63bc79feb219f97d935cd4b93af28353cba78d8e77b61719/pillow-11.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4eb92eca2711ef8be42fd3f67533765d9fd043b8c80db204f16c8ea62ee1a751", size = 4614863, upload-time = "2025-04-12T17:49:00.709Z" }, + { url = "https://files.pythonhosted.org/packages/49/65/dca4d2506be482c2c6641cacdba5c602bc76d8ceb618fd37de855653a419/pillow-11.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f91ebf30830a48c825590aede79376cb40f110b387c17ee9bd59932c961044f9", size = 4692938, upload-time = "2025-04-12T17:49:02.946Z" }, + { url = "https://files.pythonhosted.org/packages/b3/92/1ca0c3f09233bd7decf8f7105a1c4e3162fb9142128c74adad0fb361b7eb/pillow-11.2.1-cp313-cp313t-win32.whl", hash = "sha256:e0b55f27f584ed623221cfe995c912c61606be8513bfa0e07d2c674b4516d9dd", size = 2335774, upload-time = "2025-04-12T17:49:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ac/77525347cb43b83ae905ffe257bbe2cc6fd23acb9796639a1f56aa59d191/pillow-11.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:36d6b82164c39ce5482f649b437382c0fb2395eabc1e2b1702a6deb8ad647d6e", size = 2681895, upload-time = "2025-04-12T17:49:06.635Z" }, + { url = "https://files.pythonhosted.org/packages/67/32/32dc030cfa91ca0fc52baebbba2e009bb001122a1daa8b6a79ad830b38d3/pillow-11.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:225c832a13326e34f212d2072982bb1adb210e0cc0b153e688743018c94a2681", size = 2417234, upload-time = "2025-04-12T17:49:08.399Z" }, + { url = "https://files.pythonhosted.org/packages/33/49/c8c21e4255b4f4a2c0c68ac18125d7f5460b109acc6dfdef1a24f9b960ef/pillow-11.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9b7b0d4fd2635f54ad82785d56bc0d94f147096493a79985d0ab57aedd563156", size = 3181727, upload-time = "2025-04-12T17:49:31.898Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f1/f7255c0838f8c1ef6d55b625cfb286835c17e8136ce4351c5577d02c443b/pillow-11.2.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:aa442755e31c64037aa7c1cb186e0b369f8416c567381852c63444dd666fb772", size = 2999833, upload-time = "2025-04-12T17:49:34.2Z" }, + { url = "https://files.pythonhosted.org/packages/e2/57/9968114457bd131063da98d87790d080366218f64fa2943b65ac6739abb3/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d3348c95b766f54b76116d53d4cb171b52992a1027e7ca50c81b43b9d9e363", size = 3437472, upload-time = "2025-04-12T17:49:36.294Z" }, + { url = "https://files.pythonhosted.org/packages/b2/1b/e35d8a158e21372ecc48aac9c453518cfe23907bb82f950d6e1c72811eb0/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85d27ea4c889342f7e35f6d56e7e1cb345632ad592e8c51b693d7b7556043ce0", size = 3459976, upload-time = "2025-04-12T17:49:38.988Z" }, + { url = "https://files.pythonhosted.org/packages/26/da/2c11d03b765efff0ccc473f1c4186dc2770110464f2177efaed9cf6fae01/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bf2c33d6791c598142f00c9c4c7d47f6476731c31081331664eb26d6ab583e01", size = 3527133, upload-time = "2025-04-12T17:49:40.985Z" }, + { url = "https://files.pythonhosted.org/packages/79/1a/4e85bd7cadf78412c2a3069249a09c32ef3323650fd3005c97cca7aa21df/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e616e7154c37669fc1dfc14584f11e284e05d1c650e1c0f972f281c4ccc53193", size = 3571555, upload-time = "2025-04-12T17:49:42.964Z" }, + { url = "https://files.pythonhosted.org/packages/69/03/239939915216de1e95e0ce2334bf17a7870ae185eb390fab6d706aadbfc0/pillow-11.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39ad2e0f424394e3aebc40168845fee52df1394a4673a6ee512d840d14ab3013", size = 2674713, upload-time = "2025-04-12T17:49:44.944Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ad/2613c04633c7257d9481ab21d6b5364b59fc5d75faafd7cb8693523945a3/pillow-11.2.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:80f1df8dbe9572b4b7abdfa17eb5d78dd620b1d55d9e25f834efdbee872d3aed", size = 3181734, upload-time = "2025-04-12T17:49:46.789Z" }, + { url = "https://files.pythonhosted.org/packages/a4/fd/dcdda4471ed667de57bb5405bb42d751e6cfdd4011a12c248b455c778e03/pillow-11.2.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ea926cfbc3957090becbcbbb65ad177161a2ff2ad578b5a6ec9bb1e1cd78753c", size = 2999841, upload-time = "2025-04-12T17:49:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/ac/89/8a2536e95e77432833f0db6fd72a8d310c8e4272a04461fb833eb021bf94/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:738db0e0941ca0376804d4de6a782c005245264edaa253ffce24e5a15cbdc7bd", size = 3437470, upload-time = "2025-04-12T17:49:50.831Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8f/abd47b73c60712f88e9eda32baced7bfc3e9bd6a7619bb64b93acff28c3e/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db98ab6565c69082ec9b0d4e40dd9f6181dab0dd236d26f7a50b8b9bfbd5076", size = 3460013, upload-time = "2025-04-12T17:49:53.278Z" }, + { url = "https://files.pythonhosted.org/packages/f6/20/5c0a0aa83b213b7a07ec01e71a3d6ea2cf4ad1d2c686cc0168173b6089e7/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:036e53f4170e270ddb8797d4c590e6dd14d28e15c7da375c18978045f7e6c37b", size = 3527165, upload-time = "2025-04-12T17:49:55.164Z" }, + { url = "https://files.pythonhosted.org/packages/58/0e/2abab98a72202d91146abc839e10c14f7cf36166f12838ea0c4db3ca6ecb/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14f73f7c291279bd65fda51ee87affd7c1e097709f7fdd0188957a16c264601f", size = 3571586, upload-time = "2025-04-12T17:49:57.171Z" }, + { url = "https://files.pythonhosted.org/packages/21/2c/5e05f58658cf49b6667762cca03d6e7d85cededde2caf2ab37b81f80e574/pillow-11.2.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:208653868d5c9ecc2b327f9b9ef34e0e42a4cdd172c2988fd81d62d2bc9bc044", size = 2674751, upload-time = "2025-04-12T17:49:59.628Z" }, ] [[package]] name = "platformdirs" version = "4.3.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362 } +sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567 }, + { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, ] [[package]] name = "pluggy" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412 } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] @@ -3056,9 +3134,9 @@ dependencies = [ { name = "requests" }, { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/85/a9/ec3bbc23b6f3c23c52e0b5795b1357cca74aa5cfb254213f1e471fef9b4d/posthog-3.25.0.tar.gz", hash = "sha256:9168f3e7a0a5571b6b1065c41b3c171fbc68bfe72c3ac0bfd6e3d2fcdb7df2ca", size = 75968 } +sdist = { url = "https://files.pythonhosted.org/packages/85/a9/ec3bbc23b6f3c23c52e0b5795b1357cca74aa5cfb254213f1e471fef9b4d/posthog-3.25.0.tar.gz", hash = "sha256:9168f3e7a0a5571b6b1065c41b3c171fbc68bfe72c3ac0bfd6e3d2fcdb7df2ca", size = 75968, upload-time = "2025-04-15T21:15:45.552Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/e2/c158366e621562ef224f132e75c1d1c1fce6b078a19f7d8060451a12d4b9/posthog-3.25.0-py2.py3-none-any.whl", hash = "sha256:85db78c13d1ecb11aed06fad53759c4e8fb3633442c2f3d0336bc0ce8a585d30", size = 89115 }, + { url = "https://files.pythonhosted.org/packages/54/e2/c158366e621562ef224f132e75c1d1c1fce6b078a19f7d8060451a12d4b9/posthog-3.25.0-py2.py3-none-any.whl", hash = "sha256:85db78c13d1ecb11aed06fad53759c4e8fb3633442c2f3d0336bc0ce8a585d30", size = 89115, upload-time = "2025-04-15T21:15:43.934Z" }, ] [[package]] @@ -3072,9 +3150,9 @@ dependencies = [ { name = "pyyaml" }, { name = "virtualenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/39/679ca9b26c7bb2999ff122d50faa301e49af82ca9c066ec061cfbc0c6784/pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146", size = 193424 } +sdist = { url = "https://files.pythonhosted.org/packages/08/39/679ca9b26c7bb2999ff122d50faa301e49af82ca9c066ec061cfbc0c6784/pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146", size = 193424, upload-time = "2025-03-18T21:35:20.987Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707 }, + { url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707, upload-time = "2025-03-18T21:35:19.343Z" }, ] [[package]] @@ -3084,98 +3162,98 @@ 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 } +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 }, + { 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 = "propcache" version = "0.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/07/c8/fdc6686a986feae3541ea23dcaa661bd93972d3940460646c6bb96e21c40/propcache-0.3.1.tar.gz", hash = "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf", size = 43651 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/20/56/e27c136101addf877c8291dbda1b3b86ae848f3837ce758510a0d806c92f/propcache-0.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f27785888d2fdd918bc36de8b8739f2d6c791399552333721b58193f68ea3e98", size = 80224 }, - { url = "https://files.pythonhosted.org/packages/63/bd/88e98836544c4f04db97eefd23b037c2002fa173dd2772301c61cd3085f9/propcache-0.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4e89cde74154c7b5957f87a355bb9c8ec929c167b59c83d90654ea36aeb6180", size = 46491 }, - { url = "https://files.pythonhosted.org/packages/15/43/0b8eb2a55753c4a574fc0899885da504b521068d3b08ca56774cad0bea2b/propcache-0.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:730178f476ef03d3d4d255f0c9fa186cb1d13fd33ffe89d39f2cda4da90ceb71", size = 45927 }, - { url = "https://files.pythonhosted.org/packages/ad/6c/d01f9dfbbdc613305e0a831016844987a1fb4861dd221cd4c69b1216b43f/propcache-0.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967a8eec513dbe08330f10137eacb427b2ca52118769e82ebcfcab0fba92a649", size = 206135 }, - { url = "https://files.pythonhosted.org/packages/9a/8a/e6e1c77394088f4cfdace4a91a7328e398ebed745d59c2f6764135c5342d/propcache-0.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b9145c35cc87313b5fd480144f8078716007656093d23059e8993d3a8fa730f", size = 220517 }, - { url = "https://files.pythonhosted.org/packages/19/3b/6c44fa59d6418f4239d5db8b1ece757351e85d6f3ca126dfe37d427020c8/propcache-0.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e64e948ab41411958670f1093c0a57acfdc3bee5cf5b935671bbd5313bcf229", size = 218952 }, - { url = "https://files.pythonhosted.org/packages/7c/e4/4aeb95a1cd085e0558ab0de95abfc5187329616193a1012a6c4c930e9f7a/propcache-0.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:319fa8765bfd6a265e5fa661547556da381e53274bc05094fc9ea50da51bfd46", size = 206593 }, - { url = "https://files.pythonhosted.org/packages/da/6a/29fa75de1cbbb302f1e1d684009b969976ca603ee162282ae702287b6621/propcache-0.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66d8ccbc902ad548312b96ed8d5d266d0d2c6d006fd0f66323e9d8f2dd49be7", size = 196745 }, - { url = "https://files.pythonhosted.org/packages/19/7e/2237dad1dbffdd2162de470599fa1a1d55df493b16b71e5d25a0ac1c1543/propcache-0.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2d219b0dbabe75e15e581fc1ae796109b07c8ba7d25b9ae8d650da582bed01b0", size = 203369 }, - { url = "https://files.pythonhosted.org/packages/a4/bc/a82c5878eb3afb5c88da86e2cf06e1fe78b7875b26198dbb70fe50a010dc/propcache-0.3.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cd6a55f65241c551eb53f8cf4d2f4af33512c39da5d9777694e9d9c60872f519", size = 198723 }, - { url = "https://files.pythonhosted.org/packages/17/76/9632254479c55516f51644ddbf747a45f813031af5adcb8db91c0b824375/propcache-0.3.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9979643ffc69b799d50d3a7b72b5164a2e97e117009d7af6dfdd2ab906cb72cd", size = 200751 }, - { url = "https://files.pythonhosted.org/packages/3e/c3/a90b773cf639bd01d12a9e20c95be0ae978a5a8abe6d2d343900ae76cd71/propcache-0.3.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4cf9e93a81979f1424f1a3d155213dc928f1069d697e4353edb8a5eba67c6259", size = 210730 }, - { url = "https://files.pythonhosted.org/packages/ed/ec/ad5a952cdb9d65c351f88db7c46957edd3d65ffeee72a2f18bd6341433e0/propcache-0.3.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2fce1df66915909ff6c824bbb5eb403d2d15f98f1518e583074671a30fe0c21e", size = 213499 }, - { url = "https://files.pythonhosted.org/packages/83/c0/ea5133dda43e298cd2010ec05c2821b391e10980e64ee72c0a76cdbb813a/propcache-0.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4d0dfdd9a2ebc77b869a0b04423591ea8823f791293b527dc1bb896c1d6f1136", size = 207132 }, - { url = "https://files.pythonhosted.org/packages/79/dd/71aae9dec59333064cfdd7eb31a63fa09f64181b979802a67a90b2abfcba/propcache-0.3.1-cp310-cp310-win32.whl", hash = "sha256:1f6cc0ad7b4560e5637eb2c994e97b4fa41ba8226069c9277eb5ea7101845b42", size = 40952 }, - { url = "https://files.pythonhosted.org/packages/31/0a/49ff7e5056c17dfba62cbdcbb90a29daffd199c52f8e65e5cb09d5f53a57/propcache-0.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:47ef24aa6511e388e9894ec16f0fbf3313a53ee68402bc428744a367ec55b833", size = 45163 }, - { url = "https://files.pythonhosted.org/packages/90/0f/5a5319ee83bd651f75311fcb0c492c21322a7fc8f788e4eef23f44243427/propcache-0.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7f30241577d2fef2602113b70ef7231bf4c69a97e04693bde08ddab913ba0ce5", size = 80243 }, - { url = "https://files.pythonhosted.org/packages/ce/84/3db5537e0879942783e2256616ff15d870a11d7ac26541336fe1b673c818/propcache-0.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43593c6772aa12abc3af7784bff4a41ffa921608dd38b77cf1dfd7f5c4e71371", size = 46503 }, - { url = "https://files.pythonhosted.org/packages/e2/c8/b649ed972433c3f0d827d7f0cf9ea47162f4ef8f4fe98c5f3641a0bc63ff/propcache-0.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a75801768bbe65499495660b777e018cbe90c7980f07f8aa57d6be79ea6f71da", size = 45934 }, - { url = "https://files.pythonhosted.org/packages/59/f9/4c0a5cf6974c2c43b1a6810c40d889769cc8f84cea676cbe1e62766a45f8/propcache-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6f1324db48f001c2ca26a25fa25af60711e09b9aaf4b28488602776f4f9a744", size = 233633 }, - { url = "https://files.pythonhosted.org/packages/e7/64/66f2f4d1b4f0007c6e9078bd95b609b633d3957fe6dd23eac33ebde4b584/propcache-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cdb0f3e1eb6dfc9965d19734d8f9c481b294b5274337a8cb5cb01b462dcb7e0", size = 241124 }, - { url = "https://files.pythonhosted.org/packages/aa/bf/7b8c9fd097d511638fa9b6af3d986adbdf567598a567b46338c925144c1b/propcache-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb34d90aac9bfbced9a58b266f8946cb5935869ff01b164573a7634d39fbcb5", size = 240283 }, - { url = "https://files.pythonhosted.org/packages/fa/c9/e85aeeeaae83358e2a1ef32d6ff50a483a5d5248bc38510d030a6f4e2816/propcache-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35c7070eeec2cdaac6fd3fe245226ed2a6292d3ee8c938e5bb645b434c5f256", size = 232498 }, - { url = "https://files.pythonhosted.org/packages/8e/66/acb88e1f30ef5536d785c283af2e62931cb934a56a3ecf39105887aa8905/propcache-0.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b23c11c2c9e6d4e7300c92e022046ad09b91fd00e36e83c44483df4afa990073", size = 221486 }, - { url = "https://files.pythonhosted.org/packages/f5/f9/233ddb05ffdcaee4448508ee1d70aa7deff21bb41469ccdfcc339f871427/propcache-0.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e19ea4ea0bf46179f8a3652ac1426e6dcbaf577ce4b4f65be581e237340420d", size = 222675 }, - { url = "https://files.pythonhosted.org/packages/98/b8/eb977e28138f9e22a5a789daf608d36e05ed93093ef12a12441030da800a/propcache-0.3.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bd39c92e4c8f6cbf5f08257d6360123af72af9f4da75a690bef50da77362d25f", size = 215727 }, - { url = "https://files.pythonhosted.org/packages/89/2d/5f52d9c579f67b8ee1edd9ec073c91b23cc5b7ff7951a1e449e04ed8fdf3/propcache-0.3.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0313e8b923b3814d1c4a524c93dfecea5f39fa95601f6a9b1ac96cd66f89ea0", size = 217878 }, - { url = "https://files.pythonhosted.org/packages/7a/fd/5283e5ed8a82b00c7a989b99bb6ea173db1ad750bf0bf8dff08d3f4a4e28/propcache-0.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e861ad82892408487be144906a368ddbe2dc6297074ade2d892341b35c59844a", size = 230558 }, - { url = "https://files.pythonhosted.org/packages/90/38/ab17d75938ef7ac87332c588857422ae126b1c76253f0f5b1242032923ca/propcache-0.3.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:61014615c1274df8da5991a1e5da85a3ccb00c2d4701ac6f3383afd3ca47ab0a", size = 233754 }, - { url = "https://files.pythonhosted.org/packages/06/5d/3b921b9c60659ae464137508d3b4c2b3f52f592ceb1964aa2533b32fcf0b/propcache-0.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:71ebe3fe42656a2328ab08933d420df5f3ab121772eef78f2dc63624157f0ed9", size = 226088 }, - { url = "https://files.pythonhosted.org/packages/54/6e/30a11f4417d9266b5a464ac5a8c5164ddc9dd153dfa77bf57918165eb4ae/propcache-0.3.1-cp311-cp311-win32.whl", hash = "sha256:58aa11f4ca8b60113d4b8e32d37e7e78bd8af4d1a5b5cb4979ed856a45e62005", size = 40859 }, - { url = "https://files.pythonhosted.org/packages/1d/3a/8a68dd867da9ca2ee9dfd361093e9cb08cb0f37e5ddb2276f1b5177d7731/propcache-0.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:9532ea0b26a401264b1365146c440a6d78269ed41f83f23818d4b79497aeabe7", size = 45153 }, - { url = "https://files.pythonhosted.org/packages/41/aa/ca78d9be314d1e15ff517b992bebbed3bdfef5b8919e85bf4940e57b6137/propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723", size = 80430 }, - { url = "https://files.pythonhosted.org/packages/1a/d8/f0c17c44d1cda0ad1979af2e593ea290defdde9eaeb89b08abbe02a5e8e1/propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976", size = 46637 }, - { url = "https://files.pythonhosted.org/packages/ae/bd/c1e37265910752e6e5e8a4c1605d0129e5b7933c3dc3cf1b9b48ed83b364/propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b", size = 46123 }, - { url = "https://files.pythonhosted.org/packages/d4/b0/911eda0865f90c0c7e9f0415d40a5bf681204da5fd7ca089361a64c16b28/propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f", size = 243031 }, - { url = "https://files.pythonhosted.org/packages/0a/06/0da53397c76a74271621807265b6eb61fb011451b1ddebf43213df763669/propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70", size = 249100 }, - { url = "https://files.pythonhosted.org/packages/f1/eb/13090e05bf6b963fc1653cdc922133ced467cb4b8dab53158db5a37aa21e/propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7", size = 250170 }, - { url = "https://files.pythonhosted.org/packages/3b/4c/f72c9e1022b3b043ec7dc475a0f405d4c3e10b9b1d378a7330fecf0652da/propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25", size = 245000 }, - { url = "https://files.pythonhosted.org/packages/e8/fd/970ca0e22acc829f1adf5de3724085e778c1ad8a75bec010049502cb3a86/propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277", size = 230262 }, - { url = "https://files.pythonhosted.org/packages/c4/42/817289120c6b9194a44f6c3e6b2c3277c5b70bbad39e7df648f177cc3634/propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8", size = 236772 }, - { url = "https://files.pythonhosted.org/packages/7c/9c/3b3942b302badd589ad6b672da3ca7b660a6c2f505cafd058133ddc73918/propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e", size = 231133 }, - { url = "https://files.pythonhosted.org/packages/98/a1/75f6355f9ad039108ff000dfc2e19962c8dea0430da9a1428e7975cf24b2/propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee", size = 230741 }, - { url = "https://files.pythonhosted.org/packages/67/0c/3e82563af77d1f8731132166da69fdfd95e71210e31f18edce08a1eb11ea/propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815", size = 244047 }, - { url = "https://files.pythonhosted.org/packages/f7/50/9fb7cca01532a08c4d5186d7bb2da6c4c587825c0ae134b89b47c7d62628/propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5", size = 246467 }, - { url = "https://files.pythonhosted.org/packages/a9/02/ccbcf3e1c604c16cc525309161d57412c23cf2351523aedbb280eb7c9094/propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7", size = 241022 }, - { url = "https://files.pythonhosted.org/packages/db/19/e777227545e09ca1e77a6e21274ae9ec45de0f589f0ce3eca2a41f366220/propcache-0.3.1-cp312-cp312-win32.whl", hash = "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b", size = 40647 }, - { url = "https://files.pythonhosted.org/packages/24/bb/3b1b01da5dd04c77a204c84e538ff11f624e31431cfde7201d9110b092b1/propcache-0.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3", size = 44784 }, - { url = "https://files.pythonhosted.org/packages/58/60/f645cc8b570f99be3cf46714170c2de4b4c9d6b827b912811eff1eb8a412/propcache-0.3.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f1528ec4374617a7a753f90f20e2f551121bb558fcb35926f99e3c42367164b8", size = 77865 }, - { url = "https://files.pythonhosted.org/packages/6f/d4/c1adbf3901537582e65cf90fd9c26fde1298fde5a2c593f987112c0d0798/propcache-0.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc1915ec523b3b494933b5424980831b636fe483d7d543f7afb7b3bf00f0c10f", size = 45452 }, - { url = "https://files.pythonhosted.org/packages/d1/b5/fe752b2e63f49f727c6c1c224175d21b7d1727ce1d4873ef1c24c9216830/propcache-0.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a110205022d077da24e60b3df8bcee73971be9575dec5573dd17ae5d81751111", size = 44800 }, - { url = "https://files.pythonhosted.org/packages/62/37/fc357e345bc1971e21f76597028b059c3d795c5ca7690d7a8d9a03c9708a/propcache-0.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d249609e547c04d190e820d0d4c8ca03ed4582bcf8e4e160a6969ddfb57b62e5", size = 225804 }, - { url = "https://files.pythonhosted.org/packages/0d/f1/16e12c33e3dbe7f8b737809bad05719cff1dccb8df4dafbcff5575002c0e/propcache-0.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ced33d827625d0a589e831126ccb4f5c29dfdf6766cac441d23995a65825dcb", size = 230650 }, - { url = "https://files.pythonhosted.org/packages/3e/a2/018b9f2ed876bf5091e60153f727e8f9073d97573f790ff7cdf6bc1d1fb8/propcache-0.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4114c4ada8f3181af20808bedb250da6bae56660e4b8dfd9cd95d4549c0962f7", size = 234235 }, - { url = "https://files.pythonhosted.org/packages/45/5f/3faee66fc930dfb5da509e34c6ac7128870631c0e3582987fad161fcb4b1/propcache-0.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:975af16f406ce48f1333ec5e912fe11064605d5c5b3f6746969077cc3adeb120", size = 228249 }, - { url = "https://files.pythonhosted.org/packages/62/1e/a0d5ebda5da7ff34d2f5259a3e171a94be83c41eb1e7cd21a2105a84a02e/propcache-0.3.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a34aa3a1abc50740be6ac0ab9d594e274f59960d3ad253cd318af76b996dd654", size = 214964 }, - { url = "https://files.pythonhosted.org/packages/db/a0/d72da3f61ceab126e9be1f3bc7844b4e98c6e61c985097474668e7e52152/propcache-0.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9cec3239c85ed15bfaded997773fdad9fb5662b0a7cbc854a43f291eb183179e", size = 222501 }, - { url = "https://files.pythonhosted.org/packages/18/6d/a008e07ad7b905011253adbbd97e5b5375c33f0b961355ca0a30377504ac/propcache-0.3.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:05543250deac8e61084234d5fc54f8ebd254e8f2b39a16b1dce48904f45b744b", size = 217917 }, - { url = "https://files.pythonhosted.org/packages/98/37/02c9343ffe59e590e0e56dc5c97d0da2b8b19fa747ebacf158310f97a79a/propcache-0.3.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5cb5918253912e088edbf023788de539219718d3b10aef334476b62d2b53de53", size = 217089 }, - { url = "https://files.pythonhosted.org/packages/53/1b/d3406629a2c8a5666d4674c50f757a77be119b113eedd47b0375afdf1b42/propcache-0.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bbecd2f34d0e6d3c543fdb3b15d6b60dd69970c2b4c822379e5ec8f6f621d5", size = 228102 }, - { url = "https://files.pythonhosted.org/packages/cd/a7/3664756cf50ce739e5f3abd48febc0be1a713b1f389a502ca819791a6b69/propcache-0.3.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aca63103895c7d960a5b9b044a83f544b233c95e0dcff114389d64d762017af7", size = 230122 }, - { url = "https://files.pythonhosted.org/packages/35/36/0bbabaacdcc26dac4f8139625e930f4311864251276033a52fd52ff2a274/propcache-0.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a0a9898fdb99bf11786265468571e628ba60af80dc3f6eb89a3545540c6b0ef", size = 226818 }, - { url = "https://files.pythonhosted.org/packages/cc/27/4e0ef21084b53bd35d4dae1634b6d0bad35e9c58ed4f032511acca9d4d26/propcache-0.3.1-cp313-cp313-win32.whl", hash = "sha256:3a02a28095b5e63128bcae98eb59025924f121f048a62393db682f049bf4ac24", size = 40112 }, - { url = "https://files.pythonhosted.org/packages/a6/2c/a54614d61895ba6dd7ac8f107e2b2a0347259ab29cbf2ecc7b94fa38c4dc/propcache-0.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:813fbb8b6aea2fc9659815e585e548fe706d6f663fa73dff59a1677d4595a037", size = 44034 }, - { url = "https://files.pythonhosted.org/packages/5a/a8/0a4fd2f664fc6acc66438370905124ce62e84e2e860f2557015ee4a61c7e/propcache-0.3.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a444192f20f5ce8a5e52761a031b90f5ea6288b1eef42ad4c7e64fef33540b8f", size = 82613 }, - { url = "https://files.pythonhosted.org/packages/4d/e5/5ef30eb2cd81576256d7b6caaa0ce33cd1d2c2c92c8903cccb1af1a4ff2f/propcache-0.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0fbe94666e62ebe36cd652f5fc012abfbc2342de99b523f8267a678e4dfdee3c", size = 47763 }, - { url = "https://files.pythonhosted.org/packages/87/9a/87091ceb048efeba4d28e903c0b15bcc84b7c0bf27dc0261e62335d9b7b8/propcache-0.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f011f104db880f4e2166bcdcf7f58250f7a465bc6b068dc84c824a3d4a5c94dc", size = 47175 }, - { url = "https://files.pythonhosted.org/packages/3e/2f/854e653c96ad1161f96194c6678a41bbb38c7947d17768e8811a77635a08/propcache-0.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e584b6d388aeb0001d6d5c2bd86b26304adde6d9bb9bfa9c4889805021b96de", size = 292265 }, - { url = "https://files.pythonhosted.org/packages/40/8d/090955e13ed06bc3496ba4a9fb26c62e209ac41973cb0d6222de20c6868f/propcache-0.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a17583515a04358b034e241f952f1715243482fc2c2945fd99a1b03a0bd77d6", size = 294412 }, - { url = "https://files.pythonhosted.org/packages/39/e6/d51601342e53cc7582449e6a3c14a0479fab2f0750c1f4d22302e34219c6/propcache-0.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5aed8d8308215089c0734a2af4f2e95eeb360660184ad3912686c181e500b2e7", size = 294290 }, - { url = "https://files.pythonhosted.org/packages/3b/4d/be5f1a90abc1881884aa5878989a1acdafd379a91d9c7e5e12cef37ec0d7/propcache-0.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d8e309ff9a0503ef70dc9a0ebd3e69cf7b3894c9ae2ae81fc10943c37762458", size = 282926 }, - { url = "https://files.pythonhosted.org/packages/57/2b/8f61b998c7ea93a2b7eca79e53f3e903db1787fca9373af9e2cf8dc22f9d/propcache-0.3.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b655032b202028a582d27aeedc2e813299f82cb232f969f87a4fde491a233f11", size = 267808 }, - { url = "https://files.pythonhosted.org/packages/11/1c/311326c3dfce59c58a6098388ba984b0e5fb0381ef2279ec458ef99bd547/propcache-0.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f64d91b751df77931336b5ff7bafbe8845c5770b06630e27acd5dbb71e1931c", size = 290916 }, - { url = "https://files.pythonhosted.org/packages/4b/74/91939924b0385e54dc48eb2e4edd1e4903ffd053cf1916ebc5347ac227f7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:19a06db789a4bd896ee91ebc50d059e23b3639c25d58eb35be3ca1cbe967c3bf", size = 262661 }, - { url = "https://files.pythonhosted.org/packages/c2/d7/e6079af45136ad325c5337f5dd9ef97ab5dc349e0ff362fe5c5db95e2454/propcache-0.3.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:bef100c88d8692864651b5f98e871fb090bd65c8a41a1cb0ff2322db39c96c27", size = 264384 }, - { url = "https://files.pythonhosted.org/packages/b7/d5/ba91702207ac61ae6f1c2da81c5d0d6bf6ce89e08a2b4d44e411c0bbe867/propcache-0.3.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:87380fb1f3089d2a0b8b00f006ed12bd41bd858fabfa7330c954c70f50ed8757", size = 291420 }, - { url = "https://files.pythonhosted.org/packages/58/70/2117780ed7edcd7ba6b8134cb7802aada90b894a9810ec56b7bb6018bee7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e474fc718e73ba5ec5180358aa07f6aded0ff5f2abe700e3115c37d75c947e18", size = 290880 }, - { url = "https://files.pythonhosted.org/packages/4a/1f/ecd9ce27710021ae623631c0146719280a929d895a095f6d85efb6a0be2e/propcache-0.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:17d1c688a443355234f3c031349da69444be052613483f3e4158eef751abcd8a", size = 287407 }, - { url = "https://files.pythonhosted.org/packages/3e/66/2e90547d6b60180fb29e23dc87bd8c116517d4255240ec6d3f7dc23d1926/propcache-0.3.1-cp313-cp313t-win32.whl", hash = "sha256:359e81a949a7619802eb601d66d37072b79b79c2505e6d3fd8b945538411400d", size = 42573 }, - { url = "https://files.pythonhosted.org/packages/cb/8f/50ad8599399d1861b4d2b6b45271f0ef6af1b09b0a2386a46dbaf19c9535/propcache-0.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e7fb9a84c9abbf2b2683fa3e7b0d7da4d8ecf139a1c635732a8bda29c5214b0e", size = 46757 }, - { url = "https://files.pythonhosted.org/packages/b8/d3/c3cb8f1d6ae3b37f83e1de806713a9b3642c5895f0215a62e1a4bd6e5e34/propcache-0.3.1-py3-none-any.whl", hash = "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40", size = 12376 }, +sdist = { url = "https://files.pythonhosted.org/packages/07/c8/fdc6686a986feae3541ea23dcaa661bd93972d3940460646c6bb96e21c40/propcache-0.3.1.tar.gz", hash = "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf", size = 43651, upload-time = "2025-03-26T03:06:12.05Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/56/e27c136101addf877c8291dbda1b3b86ae848f3837ce758510a0d806c92f/propcache-0.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f27785888d2fdd918bc36de8b8739f2d6c791399552333721b58193f68ea3e98", size = 80224, upload-time = "2025-03-26T03:03:35.81Z" }, + { url = "https://files.pythonhosted.org/packages/63/bd/88e98836544c4f04db97eefd23b037c2002fa173dd2772301c61cd3085f9/propcache-0.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4e89cde74154c7b5957f87a355bb9c8ec929c167b59c83d90654ea36aeb6180", size = 46491, upload-time = "2025-03-26T03:03:38.107Z" }, + { url = "https://files.pythonhosted.org/packages/15/43/0b8eb2a55753c4a574fc0899885da504b521068d3b08ca56774cad0bea2b/propcache-0.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:730178f476ef03d3d4d255f0c9fa186cb1d13fd33ffe89d39f2cda4da90ceb71", size = 45927, upload-time = "2025-03-26T03:03:39.394Z" }, + { url = "https://files.pythonhosted.org/packages/ad/6c/d01f9dfbbdc613305e0a831016844987a1fb4861dd221cd4c69b1216b43f/propcache-0.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967a8eec513dbe08330f10137eacb427b2ca52118769e82ebcfcab0fba92a649", size = 206135, upload-time = "2025-03-26T03:03:40.757Z" }, + { url = "https://files.pythonhosted.org/packages/9a/8a/e6e1c77394088f4cfdace4a91a7328e398ebed745d59c2f6764135c5342d/propcache-0.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b9145c35cc87313b5fd480144f8078716007656093d23059e8993d3a8fa730f", size = 220517, upload-time = "2025-03-26T03:03:42.657Z" }, + { url = "https://files.pythonhosted.org/packages/19/3b/6c44fa59d6418f4239d5db8b1ece757351e85d6f3ca126dfe37d427020c8/propcache-0.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e64e948ab41411958670f1093c0a57acfdc3bee5cf5b935671bbd5313bcf229", size = 218952, upload-time = "2025-03-26T03:03:44.549Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e4/4aeb95a1cd085e0558ab0de95abfc5187329616193a1012a6c4c930e9f7a/propcache-0.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:319fa8765bfd6a265e5fa661547556da381e53274bc05094fc9ea50da51bfd46", size = 206593, upload-time = "2025-03-26T03:03:46.114Z" }, + { url = "https://files.pythonhosted.org/packages/da/6a/29fa75de1cbbb302f1e1d684009b969976ca603ee162282ae702287b6621/propcache-0.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66d8ccbc902ad548312b96ed8d5d266d0d2c6d006fd0f66323e9d8f2dd49be7", size = 196745, upload-time = "2025-03-26T03:03:48.02Z" }, + { url = "https://files.pythonhosted.org/packages/19/7e/2237dad1dbffdd2162de470599fa1a1d55df493b16b71e5d25a0ac1c1543/propcache-0.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2d219b0dbabe75e15e581fc1ae796109b07c8ba7d25b9ae8d650da582bed01b0", size = 203369, upload-time = "2025-03-26T03:03:49.63Z" }, + { url = "https://files.pythonhosted.org/packages/a4/bc/a82c5878eb3afb5c88da86e2cf06e1fe78b7875b26198dbb70fe50a010dc/propcache-0.3.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cd6a55f65241c551eb53f8cf4d2f4af33512c39da5d9777694e9d9c60872f519", size = 198723, upload-time = "2025-03-26T03:03:51.091Z" }, + { url = "https://files.pythonhosted.org/packages/17/76/9632254479c55516f51644ddbf747a45f813031af5adcb8db91c0b824375/propcache-0.3.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9979643ffc69b799d50d3a7b72b5164a2e97e117009d7af6dfdd2ab906cb72cd", size = 200751, upload-time = "2025-03-26T03:03:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/3e/c3/a90b773cf639bd01d12a9e20c95be0ae978a5a8abe6d2d343900ae76cd71/propcache-0.3.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4cf9e93a81979f1424f1a3d155213dc928f1069d697e4353edb8a5eba67c6259", size = 210730, upload-time = "2025-03-26T03:03:54.498Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ec/ad5a952cdb9d65c351f88db7c46957edd3d65ffeee72a2f18bd6341433e0/propcache-0.3.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2fce1df66915909ff6c824bbb5eb403d2d15f98f1518e583074671a30fe0c21e", size = 213499, upload-time = "2025-03-26T03:03:56.054Z" }, + { url = "https://files.pythonhosted.org/packages/83/c0/ea5133dda43e298cd2010ec05c2821b391e10980e64ee72c0a76cdbb813a/propcache-0.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4d0dfdd9a2ebc77b869a0b04423591ea8823f791293b527dc1bb896c1d6f1136", size = 207132, upload-time = "2025-03-26T03:03:57.398Z" }, + { url = "https://files.pythonhosted.org/packages/79/dd/71aae9dec59333064cfdd7eb31a63fa09f64181b979802a67a90b2abfcba/propcache-0.3.1-cp310-cp310-win32.whl", hash = "sha256:1f6cc0ad7b4560e5637eb2c994e97b4fa41ba8226069c9277eb5ea7101845b42", size = 40952, upload-time = "2025-03-26T03:03:59.146Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/49ff7e5056c17dfba62cbdcbb90a29daffd199c52f8e65e5cb09d5f53a57/propcache-0.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:47ef24aa6511e388e9894ec16f0fbf3313a53ee68402bc428744a367ec55b833", size = 45163, upload-time = "2025-03-26T03:04:00.672Z" }, + { url = "https://files.pythonhosted.org/packages/90/0f/5a5319ee83bd651f75311fcb0c492c21322a7fc8f788e4eef23f44243427/propcache-0.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7f30241577d2fef2602113b70ef7231bf4c69a97e04693bde08ddab913ba0ce5", size = 80243, upload-time = "2025-03-26T03:04:01.912Z" }, + { url = "https://files.pythonhosted.org/packages/ce/84/3db5537e0879942783e2256616ff15d870a11d7ac26541336fe1b673c818/propcache-0.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43593c6772aa12abc3af7784bff4a41ffa921608dd38b77cf1dfd7f5c4e71371", size = 46503, upload-time = "2025-03-26T03:04:03.704Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c8/b649ed972433c3f0d827d7f0cf9ea47162f4ef8f4fe98c5f3641a0bc63ff/propcache-0.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a75801768bbe65499495660b777e018cbe90c7980f07f8aa57d6be79ea6f71da", size = 45934, upload-time = "2025-03-26T03:04:05.257Z" }, + { url = "https://files.pythonhosted.org/packages/59/f9/4c0a5cf6974c2c43b1a6810c40d889769cc8f84cea676cbe1e62766a45f8/propcache-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6f1324db48f001c2ca26a25fa25af60711e09b9aaf4b28488602776f4f9a744", size = 233633, upload-time = "2025-03-26T03:04:07.044Z" }, + { url = "https://files.pythonhosted.org/packages/e7/64/66f2f4d1b4f0007c6e9078bd95b609b633d3957fe6dd23eac33ebde4b584/propcache-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cdb0f3e1eb6dfc9965d19734d8f9c481b294b5274337a8cb5cb01b462dcb7e0", size = 241124, upload-time = "2025-03-26T03:04:08.676Z" }, + { url = "https://files.pythonhosted.org/packages/aa/bf/7b8c9fd097d511638fa9b6af3d986adbdf567598a567b46338c925144c1b/propcache-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb34d90aac9bfbced9a58b266f8946cb5935869ff01b164573a7634d39fbcb5", size = 240283, upload-time = "2025-03-26T03:04:10.172Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c9/e85aeeeaae83358e2a1ef32d6ff50a483a5d5248bc38510d030a6f4e2816/propcache-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35c7070eeec2cdaac6fd3fe245226ed2a6292d3ee8c938e5bb645b434c5f256", size = 232498, upload-time = "2025-03-26T03:04:11.616Z" }, + { url = "https://files.pythonhosted.org/packages/8e/66/acb88e1f30ef5536d785c283af2e62931cb934a56a3ecf39105887aa8905/propcache-0.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b23c11c2c9e6d4e7300c92e022046ad09b91fd00e36e83c44483df4afa990073", size = 221486, upload-time = "2025-03-26T03:04:13.102Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f9/233ddb05ffdcaee4448508ee1d70aa7deff21bb41469ccdfcc339f871427/propcache-0.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e19ea4ea0bf46179f8a3652ac1426e6dcbaf577ce4b4f65be581e237340420d", size = 222675, upload-time = "2025-03-26T03:04:14.658Z" }, + { url = "https://files.pythonhosted.org/packages/98/b8/eb977e28138f9e22a5a789daf608d36e05ed93093ef12a12441030da800a/propcache-0.3.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bd39c92e4c8f6cbf5f08257d6360123af72af9f4da75a690bef50da77362d25f", size = 215727, upload-time = "2025-03-26T03:04:16.207Z" }, + { url = "https://files.pythonhosted.org/packages/89/2d/5f52d9c579f67b8ee1edd9ec073c91b23cc5b7ff7951a1e449e04ed8fdf3/propcache-0.3.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0313e8b923b3814d1c4a524c93dfecea5f39fa95601f6a9b1ac96cd66f89ea0", size = 217878, upload-time = "2025-03-26T03:04:18.11Z" }, + { url = "https://files.pythonhosted.org/packages/7a/fd/5283e5ed8a82b00c7a989b99bb6ea173db1ad750bf0bf8dff08d3f4a4e28/propcache-0.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e861ad82892408487be144906a368ddbe2dc6297074ade2d892341b35c59844a", size = 230558, upload-time = "2025-03-26T03:04:19.562Z" }, + { url = "https://files.pythonhosted.org/packages/90/38/ab17d75938ef7ac87332c588857422ae126b1c76253f0f5b1242032923ca/propcache-0.3.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:61014615c1274df8da5991a1e5da85a3ccb00c2d4701ac6f3383afd3ca47ab0a", size = 233754, upload-time = "2025-03-26T03:04:21.065Z" }, + { url = "https://files.pythonhosted.org/packages/06/5d/3b921b9c60659ae464137508d3b4c2b3f52f592ceb1964aa2533b32fcf0b/propcache-0.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:71ebe3fe42656a2328ab08933d420df5f3ab121772eef78f2dc63624157f0ed9", size = 226088, upload-time = "2025-03-26T03:04:22.718Z" }, + { url = "https://files.pythonhosted.org/packages/54/6e/30a11f4417d9266b5a464ac5a8c5164ddc9dd153dfa77bf57918165eb4ae/propcache-0.3.1-cp311-cp311-win32.whl", hash = "sha256:58aa11f4ca8b60113d4b8e32d37e7e78bd8af4d1a5b5cb4979ed856a45e62005", size = 40859, upload-time = "2025-03-26T03:04:24.039Z" }, + { url = "https://files.pythonhosted.org/packages/1d/3a/8a68dd867da9ca2ee9dfd361093e9cb08cb0f37e5ddb2276f1b5177d7731/propcache-0.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:9532ea0b26a401264b1365146c440a6d78269ed41f83f23818d4b79497aeabe7", size = 45153, upload-time = "2025-03-26T03:04:25.211Z" }, + { url = "https://files.pythonhosted.org/packages/41/aa/ca78d9be314d1e15ff517b992bebbed3bdfef5b8919e85bf4940e57b6137/propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723", size = 80430, upload-time = "2025-03-26T03:04:26.436Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d8/f0c17c44d1cda0ad1979af2e593ea290defdde9eaeb89b08abbe02a5e8e1/propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976", size = 46637, upload-time = "2025-03-26T03:04:27.932Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bd/c1e37265910752e6e5e8a4c1605d0129e5b7933c3dc3cf1b9b48ed83b364/propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b", size = 46123, upload-time = "2025-03-26T03:04:30.659Z" }, + { url = "https://files.pythonhosted.org/packages/d4/b0/911eda0865f90c0c7e9f0415d40a5bf681204da5fd7ca089361a64c16b28/propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f", size = 243031, upload-time = "2025-03-26T03:04:31.977Z" }, + { url = "https://files.pythonhosted.org/packages/0a/06/0da53397c76a74271621807265b6eb61fb011451b1ddebf43213df763669/propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70", size = 249100, upload-time = "2025-03-26T03:04:33.45Z" }, + { url = "https://files.pythonhosted.org/packages/f1/eb/13090e05bf6b963fc1653cdc922133ced467cb4b8dab53158db5a37aa21e/propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7", size = 250170, upload-time = "2025-03-26T03:04:35.542Z" }, + { url = "https://files.pythonhosted.org/packages/3b/4c/f72c9e1022b3b043ec7dc475a0f405d4c3e10b9b1d378a7330fecf0652da/propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25", size = 245000, upload-time = "2025-03-26T03:04:37.501Z" }, + { url = "https://files.pythonhosted.org/packages/e8/fd/970ca0e22acc829f1adf5de3724085e778c1ad8a75bec010049502cb3a86/propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277", size = 230262, upload-time = "2025-03-26T03:04:39.532Z" }, + { url = "https://files.pythonhosted.org/packages/c4/42/817289120c6b9194a44f6c3e6b2c3277c5b70bbad39e7df648f177cc3634/propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8", size = 236772, upload-time = "2025-03-26T03:04:41.109Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9c/3b3942b302badd589ad6b672da3ca7b660a6c2f505cafd058133ddc73918/propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e", size = 231133, upload-time = "2025-03-26T03:04:42.544Z" }, + { url = "https://files.pythonhosted.org/packages/98/a1/75f6355f9ad039108ff000dfc2e19962c8dea0430da9a1428e7975cf24b2/propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee", size = 230741, upload-time = "2025-03-26T03:04:44.06Z" }, + { url = "https://files.pythonhosted.org/packages/67/0c/3e82563af77d1f8731132166da69fdfd95e71210e31f18edce08a1eb11ea/propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815", size = 244047, upload-time = "2025-03-26T03:04:45.983Z" }, + { url = "https://files.pythonhosted.org/packages/f7/50/9fb7cca01532a08c4d5186d7bb2da6c4c587825c0ae134b89b47c7d62628/propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5", size = 246467, upload-time = "2025-03-26T03:04:47.699Z" }, + { url = "https://files.pythonhosted.org/packages/a9/02/ccbcf3e1c604c16cc525309161d57412c23cf2351523aedbb280eb7c9094/propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7", size = 241022, upload-time = "2025-03-26T03:04:49.195Z" }, + { url = "https://files.pythonhosted.org/packages/db/19/e777227545e09ca1e77a6e21274ae9ec45de0f589f0ce3eca2a41f366220/propcache-0.3.1-cp312-cp312-win32.whl", hash = "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b", size = 40647, upload-time = "2025-03-26T03:04:50.595Z" }, + { url = "https://files.pythonhosted.org/packages/24/bb/3b1b01da5dd04c77a204c84e538ff11f624e31431cfde7201d9110b092b1/propcache-0.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3", size = 44784, upload-time = "2025-03-26T03:04:51.791Z" }, + { url = "https://files.pythonhosted.org/packages/58/60/f645cc8b570f99be3cf46714170c2de4b4c9d6b827b912811eff1eb8a412/propcache-0.3.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f1528ec4374617a7a753f90f20e2f551121bb558fcb35926f99e3c42367164b8", size = 77865, upload-time = "2025-03-26T03:04:53.406Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d4/c1adbf3901537582e65cf90fd9c26fde1298fde5a2c593f987112c0d0798/propcache-0.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc1915ec523b3b494933b5424980831b636fe483d7d543f7afb7b3bf00f0c10f", size = 45452, upload-time = "2025-03-26T03:04:54.624Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b5/fe752b2e63f49f727c6c1c224175d21b7d1727ce1d4873ef1c24c9216830/propcache-0.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a110205022d077da24e60b3df8bcee73971be9575dec5573dd17ae5d81751111", size = 44800, upload-time = "2025-03-26T03:04:55.844Z" }, + { url = "https://files.pythonhosted.org/packages/62/37/fc357e345bc1971e21f76597028b059c3d795c5ca7690d7a8d9a03c9708a/propcache-0.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d249609e547c04d190e820d0d4c8ca03ed4582bcf8e4e160a6969ddfb57b62e5", size = 225804, upload-time = "2025-03-26T03:04:57.158Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f1/16e12c33e3dbe7f8b737809bad05719cff1dccb8df4dafbcff5575002c0e/propcache-0.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ced33d827625d0a589e831126ccb4f5c29dfdf6766cac441d23995a65825dcb", size = 230650, upload-time = "2025-03-26T03:04:58.61Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a2/018b9f2ed876bf5091e60153f727e8f9073d97573f790ff7cdf6bc1d1fb8/propcache-0.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4114c4ada8f3181af20808bedb250da6bae56660e4b8dfd9cd95d4549c0962f7", size = 234235, upload-time = "2025-03-26T03:05:00.599Z" }, + { url = "https://files.pythonhosted.org/packages/45/5f/3faee66fc930dfb5da509e34c6ac7128870631c0e3582987fad161fcb4b1/propcache-0.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:975af16f406ce48f1333ec5e912fe11064605d5c5b3f6746969077cc3adeb120", size = 228249, upload-time = "2025-03-26T03:05:02.11Z" }, + { url = "https://files.pythonhosted.org/packages/62/1e/a0d5ebda5da7ff34d2f5259a3e171a94be83c41eb1e7cd21a2105a84a02e/propcache-0.3.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a34aa3a1abc50740be6ac0ab9d594e274f59960d3ad253cd318af76b996dd654", size = 214964, upload-time = "2025-03-26T03:05:03.599Z" }, + { url = "https://files.pythonhosted.org/packages/db/a0/d72da3f61ceab126e9be1f3bc7844b4e98c6e61c985097474668e7e52152/propcache-0.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9cec3239c85ed15bfaded997773fdad9fb5662b0a7cbc854a43f291eb183179e", size = 222501, upload-time = "2025-03-26T03:05:05.107Z" }, + { url = "https://files.pythonhosted.org/packages/18/6d/a008e07ad7b905011253adbbd97e5b5375c33f0b961355ca0a30377504ac/propcache-0.3.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:05543250deac8e61084234d5fc54f8ebd254e8f2b39a16b1dce48904f45b744b", size = 217917, upload-time = "2025-03-26T03:05:06.59Z" }, + { url = "https://files.pythonhosted.org/packages/98/37/02c9343ffe59e590e0e56dc5c97d0da2b8b19fa747ebacf158310f97a79a/propcache-0.3.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5cb5918253912e088edbf023788de539219718d3b10aef334476b62d2b53de53", size = 217089, upload-time = "2025-03-26T03:05:08.1Z" }, + { url = "https://files.pythonhosted.org/packages/53/1b/d3406629a2c8a5666d4674c50f757a77be119b113eedd47b0375afdf1b42/propcache-0.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bbecd2f34d0e6d3c543fdb3b15d6b60dd69970c2b4c822379e5ec8f6f621d5", size = 228102, upload-time = "2025-03-26T03:05:09.982Z" }, + { url = "https://files.pythonhosted.org/packages/cd/a7/3664756cf50ce739e5f3abd48febc0be1a713b1f389a502ca819791a6b69/propcache-0.3.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aca63103895c7d960a5b9b044a83f544b233c95e0dcff114389d64d762017af7", size = 230122, upload-time = "2025-03-26T03:05:11.408Z" }, + { url = "https://files.pythonhosted.org/packages/35/36/0bbabaacdcc26dac4f8139625e930f4311864251276033a52fd52ff2a274/propcache-0.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a0a9898fdb99bf11786265468571e628ba60af80dc3f6eb89a3545540c6b0ef", size = 226818, upload-time = "2025-03-26T03:05:12.909Z" }, + { url = "https://files.pythonhosted.org/packages/cc/27/4e0ef21084b53bd35d4dae1634b6d0bad35e9c58ed4f032511acca9d4d26/propcache-0.3.1-cp313-cp313-win32.whl", hash = "sha256:3a02a28095b5e63128bcae98eb59025924f121f048a62393db682f049bf4ac24", size = 40112, upload-time = "2025-03-26T03:05:14.289Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2c/a54614d61895ba6dd7ac8f107e2b2a0347259ab29cbf2ecc7b94fa38c4dc/propcache-0.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:813fbb8b6aea2fc9659815e585e548fe706d6f663fa73dff59a1677d4595a037", size = 44034, upload-time = "2025-03-26T03:05:15.616Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a8/0a4fd2f664fc6acc66438370905124ce62e84e2e860f2557015ee4a61c7e/propcache-0.3.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a444192f20f5ce8a5e52761a031b90f5ea6288b1eef42ad4c7e64fef33540b8f", size = 82613, upload-time = "2025-03-26T03:05:16.913Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e5/5ef30eb2cd81576256d7b6caaa0ce33cd1d2c2c92c8903cccb1af1a4ff2f/propcache-0.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0fbe94666e62ebe36cd652f5fc012abfbc2342de99b523f8267a678e4dfdee3c", size = 47763, upload-time = "2025-03-26T03:05:18.607Z" }, + { url = "https://files.pythonhosted.org/packages/87/9a/87091ceb048efeba4d28e903c0b15bcc84b7c0bf27dc0261e62335d9b7b8/propcache-0.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f011f104db880f4e2166bcdcf7f58250f7a465bc6b068dc84c824a3d4a5c94dc", size = 47175, upload-time = "2025-03-26T03:05:19.85Z" }, + { url = "https://files.pythonhosted.org/packages/3e/2f/854e653c96ad1161f96194c6678a41bbb38c7947d17768e8811a77635a08/propcache-0.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e584b6d388aeb0001d6d5c2bd86b26304adde6d9bb9bfa9c4889805021b96de", size = 292265, upload-time = "2025-03-26T03:05:21.654Z" }, + { url = "https://files.pythonhosted.org/packages/40/8d/090955e13ed06bc3496ba4a9fb26c62e209ac41973cb0d6222de20c6868f/propcache-0.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a17583515a04358b034e241f952f1715243482fc2c2945fd99a1b03a0bd77d6", size = 294412, upload-time = "2025-03-26T03:05:23.147Z" }, + { url = "https://files.pythonhosted.org/packages/39/e6/d51601342e53cc7582449e6a3c14a0479fab2f0750c1f4d22302e34219c6/propcache-0.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5aed8d8308215089c0734a2af4f2e95eeb360660184ad3912686c181e500b2e7", size = 294290, upload-time = "2025-03-26T03:05:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/3b/4d/be5f1a90abc1881884aa5878989a1acdafd379a91d9c7e5e12cef37ec0d7/propcache-0.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d8e309ff9a0503ef70dc9a0ebd3e69cf7b3894c9ae2ae81fc10943c37762458", size = 282926, upload-time = "2025-03-26T03:05:26.459Z" }, + { url = "https://files.pythonhosted.org/packages/57/2b/8f61b998c7ea93a2b7eca79e53f3e903db1787fca9373af9e2cf8dc22f9d/propcache-0.3.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b655032b202028a582d27aeedc2e813299f82cb232f969f87a4fde491a233f11", size = 267808, upload-time = "2025-03-26T03:05:28.188Z" }, + { url = "https://files.pythonhosted.org/packages/11/1c/311326c3dfce59c58a6098388ba984b0e5fb0381ef2279ec458ef99bd547/propcache-0.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f64d91b751df77931336b5ff7bafbe8845c5770b06630e27acd5dbb71e1931c", size = 290916, upload-time = "2025-03-26T03:05:29.757Z" }, + { url = "https://files.pythonhosted.org/packages/4b/74/91939924b0385e54dc48eb2e4edd1e4903ffd053cf1916ebc5347ac227f7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:19a06db789a4bd896ee91ebc50d059e23b3639c25d58eb35be3ca1cbe967c3bf", size = 262661, upload-time = "2025-03-26T03:05:31.472Z" }, + { url = "https://files.pythonhosted.org/packages/c2/d7/e6079af45136ad325c5337f5dd9ef97ab5dc349e0ff362fe5c5db95e2454/propcache-0.3.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:bef100c88d8692864651b5f98e871fb090bd65c8a41a1cb0ff2322db39c96c27", size = 264384, upload-time = "2025-03-26T03:05:32.984Z" }, + { url = "https://files.pythonhosted.org/packages/b7/d5/ba91702207ac61ae6f1c2da81c5d0d6bf6ce89e08a2b4d44e411c0bbe867/propcache-0.3.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:87380fb1f3089d2a0b8b00f006ed12bd41bd858fabfa7330c954c70f50ed8757", size = 291420, upload-time = "2025-03-26T03:05:34.496Z" }, + { url = "https://files.pythonhosted.org/packages/58/70/2117780ed7edcd7ba6b8134cb7802aada90b894a9810ec56b7bb6018bee7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e474fc718e73ba5ec5180358aa07f6aded0ff5f2abe700e3115c37d75c947e18", size = 290880, upload-time = "2025-03-26T03:05:36.256Z" }, + { url = "https://files.pythonhosted.org/packages/4a/1f/ecd9ce27710021ae623631c0146719280a929d895a095f6d85efb6a0be2e/propcache-0.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:17d1c688a443355234f3c031349da69444be052613483f3e4158eef751abcd8a", size = 287407, upload-time = "2025-03-26T03:05:37.799Z" }, + { url = "https://files.pythonhosted.org/packages/3e/66/2e90547d6b60180fb29e23dc87bd8c116517d4255240ec6d3f7dc23d1926/propcache-0.3.1-cp313-cp313t-win32.whl", hash = "sha256:359e81a949a7619802eb601d66d37072b79b79c2505e6d3fd8b945538411400d", size = 42573, upload-time = "2025-03-26T03:05:39.193Z" }, + { url = "https://files.pythonhosted.org/packages/cb/8f/50ad8599399d1861b4d2b6b45271f0ef6af1b09b0a2386a46dbaf19c9535/propcache-0.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e7fb9a84c9abbf2b2683fa3e7b0d7da4d8ecf139a1c635732a8bda29c5214b0e", size = 46757, upload-time = "2025-03-26T03:05:40.811Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d3/c3cb8f1d6ae3b37f83e1de806713a9b3642c5895f0215a62e1a4bd6e5e34/propcache-0.3.1-py3-none-any.whl", hash = "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40", size = 12376, upload-time = "2025-03-26T03:06:10.5Z" }, ] [[package]] @@ -3185,50 +3263,50 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/ac/87285f15f7cce6d4a008f33f1757fb5a13611ea8914eb58c3d0d26243468/proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012", size = 56142 } +sdist = { url = "https://files.pythonhosted.org/packages/f4/ac/87285f15f7cce6d4a008f33f1757fb5a13611ea8914eb58c3d0d26243468/proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012", size = 56142, upload-time = "2025-03-10T15:54:38.843Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/6d/280c4c2ce28b1593a19ad5239c8b826871fc6ec275c21afc8e1820108039/proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66", size = 50163 }, + { url = "https://files.pythonhosted.org/packages/4e/6d/280c4c2ce28b1593a19ad5239c8b826871fc6ec275c21afc8e1820108039/proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66", size = 50163, upload-time = "2025-03-10T15:54:37.335Z" }, ] [[package]] name = "protobuf" version = "5.29.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/17/7d/b9dca7365f0e2c4fa7c193ff795427cfa6290147e5185ab11ece280a18e7/protobuf-5.29.4.tar.gz", hash = "sha256:4f1dfcd7997b31ef8f53ec82781ff434a28bf71d9102ddde14d076adcfc78c99", size = 424902 } +sdist = { url = "https://files.pythonhosted.org/packages/17/7d/b9dca7365f0e2c4fa7c193ff795427cfa6290147e5185ab11ece280a18e7/protobuf-5.29.4.tar.gz", hash = "sha256:4f1dfcd7997b31ef8f53ec82781ff434a28bf71d9102ddde14d076adcfc78c99", size = 424902, upload-time = "2025-03-19T21:23:24.25Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/b2/043a1a1a20edd134563699b0e91862726a0dc9146c090743b6c44d798e75/protobuf-5.29.4-cp310-abi3-win32.whl", hash = "sha256:13eb236f8eb9ec34e63fc8b1d6efd2777d062fa6aaa68268fb67cf77f6839ad7", size = 422709 }, - { url = "https://files.pythonhosted.org/packages/79/fc/2474b59570daa818de6124c0a15741ee3e5d6302e9d6ce0bdfd12e98119f/protobuf-5.29.4-cp310-abi3-win_amd64.whl", hash = "sha256:bcefcdf3976233f8a502d265eb65ea740c989bacc6c30a58290ed0e519eb4b8d", size = 434506 }, - { url = "https://files.pythonhosted.org/packages/46/de/7c126bbb06aa0f8a7b38aaf8bd746c514d70e6a2a3f6dd460b3b7aad7aae/protobuf-5.29.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:307ecba1d852ec237e9ba668e087326a67564ef83e45a0189a772ede9e854dd0", size = 417826 }, - { url = "https://files.pythonhosted.org/packages/a2/b5/bade14ae31ba871a139aa45e7a8183d869efe87c34a4850c87b936963261/protobuf-5.29.4-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:aec4962f9ea93c431d5714ed1be1c93f13e1a8618e70035ba2b0564d9e633f2e", size = 319574 }, - { url = "https://files.pythonhosted.org/packages/46/88/b01ed2291aae68b708f7d334288ad5fb3e7aa769a9c309c91a0d55cb91b0/protobuf-5.29.4-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:d7d3f7d1d5a66ed4942d4fefb12ac4b14a29028b209d4bfb25c68ae172059922", size = 319672 }, - { url = "https://files.pythonhosted.org/packages/12/fb/a586e0c973c95502e054ac5f81f88394f24ccc7982dac19c515acd9e2c93/protobuf-5.29.4-py3-none-any.whl", hash = "sha256:3fde11b505e1597f71b875ef2fc52062b6a9740e5f7c8997ce878b6009145862", size = 172551 }, + { url = "https://files.pythonhosted.org/packages/9a/b2/043a1a1a20edd134563699b0e91862726a0dc9146c090743b6c44d798e75/protobuf-5.29.4-cp310-abi3-win32.whl", hash = "sha256:13eb236f8eb9ec34e63fc8b1d6efd2777d062fa6aaa68268fb67cf77f6839ad7", size = 422709, upload-time = "2025-03-19T21:23:08.293Z" }, + { url = "https://files.pythonhosted.org/packages/79/fc/2474b59570daa818de6124c0a15741ee3e5d6302e9d6ce0bdfd12e98119f/protobuf-5.29.4-cp310-abi3-win_amd64.whl", hash = "sha256:bcefcdf3976233f8a502d265eb65ea740c989bacc6c30a58290ed0e519eb4b8d", size = 434506, upload-time = "2025-03-19T21:23:11.253Z" }, + { url = "https://files.pythonhosted.org/packages/46/de/7c126bbb06aa0f8a7b38aaf8bd746c514d70e6a2a3f6dd460b3b7aad7aae/protobuf-5.29.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:307ecba1d852ec237e9ba668e087326a67564ef83e45a0189a772ede9e854dd0", size = 417826, upload-time = "2025-03-19T21:23:13.132Z" }, + { url = "https://files.pythonhosted.org/packages/a2/b5/bade14ae31ba871a139aa45e7a8183d869efe87c34a4850c87b936963261/protobuf-5.29.4-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:aec4962f9ea93c431d5714ed1be1c93f13e1a8618e70035ba2b0564d9e633f2e", size = 319574, upload-time = "2025-03-19T21:23:14.531Z" }, + { url = "https://files.pythonhosted.org/packages/46/88/b01ed2291aae68b708f7d334288ad5fb3e7aa769a9c309c91a0d55cb91b0/protobuf-5.29.4-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:d7d3f7d1d5a66ed4942d4fefb12ac4b14a29028b209d4bfb25c68ae172059922", size = 319672, upload-time = "2025-03-19T21:23:15.839Z" }, + { url = "https://files.pythonhosted.org/packages/12/fb/a586e0c973c95502e054ac5f81f88394f24ccc7982dac19c515acd9e2c93/protobuf-5.29.4-py3-none-any.whl", hash = "sha256:3fde11b505e1597f71b875ef2fc52062b6a9740e5f7c8997ce878b6009145862", size = 172551, upload-time = "2025-03-19T21:23:22.682Z" }, ] [[package]] name = "ptyprocess" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762 } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993 }, + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, ] [[package]] name = "pure-eval" version = "0.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752 } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842 }, + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, ] [[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 } +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 }, + { 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]] @@ -3238,18 +3316,18 @@ 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 } +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 }, + { 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 = "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 } +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 }, + { 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]] @@ -3262,9 +3340,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f0/86/8ce9040065e8f924d642c58e4a344e33163a07f6b57f836d0d734e0ad3fb/pydantic-2.11.5.tar.gz", hash = "sha256:7f853db3d0ce78ce8bbb148c401c2cdd6431b3473c0cdff2755c7690952a7b7a", size = 787102 } +sdist = { url = "https://files.pythonhosted.org/packages/f0/86/8ce9040065e8f924d642c58e4a344e33163a07f6b57f836d0d734e0ad3fb/pydantic-2.11.5.tar.gz", hash = "sha256:7f853db3d0ce78ce8bbb148c401c2cdd6431b3473c0cdff2755c7690952a7b7a", size = 787102, upload-time = "2025-05-22T21:18:08.761Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/69/831ed22b38ff9b4b64b66569f0e5b7b97cf3638346eb95a2147fdb49ad5f/pydantic-2.11.5-py3-none-any.whl", hash = "sha256:f9c26ba06f9747749ca1e5c94d6a85cb84254577553c8785576fd38fa64dc0f7", size = 444229 }, + { url = "https://files.pythonhosted.org/packages/b5/69/831ed22b38ff9b4b64b66569f0e5b7b97cf3638346eb95a2147fdb49ad5f/pydantic-2.11.5-py3-none-any.whl", hash = "sha256:f9c26ba06f9747749ca1e5c94d6a85cb84254577553c8785576fd38fa64dc0f7", size = 444229, upload-time = "2025-05-22T21:18:06.329Z" }, ] [[package]] @@ -3274,84 +3352,84 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/92/b31726561b5dae176c2d2c2dc43a9c5bfba5d32f96f8b4c0a600dd492447/pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8", size = 2028817 }, - { url = "https://files.pythonhosted.org/packages/a3/44/3f0b95fafdaca04a483c4e685fe437c6891001bf3ce8b2fded82b9ea3aa1/pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d", size = 1861357 }, - { url = "https://files.pythonhosted.org/packages/30/97/e8f13b55766234caae05372826e8e4b3b96e7b248be3157f53237682e43c/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d", size = 1898011 }, - { url = "https://files.pythonhosted.org/packages/9b/a3/99c48cf7bafc991cc3ee66fd544c0aae8dc907b752f1dad2d79b1b5a471f/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572", size = 1982730 }, - { url = "https://files.pythonhosted.org/packages/de/8e/a5b882ec4307010a840fb8b58bd9bf65d1840c92eae7534c7441709bf54b/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02", size = 2136178 }, - { url = "https://files.pythonhosted.org/packages/e4/bb/71e35fc3ed05af6834e890edb75968e2802fe98778971ab5cba20a162315/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b", size = 2736462 }, - { url = "https://files.pythonhosted.org/packages/31/0d/c8f7593e6bc7066289bbc366f2235701dcbebcd1ff0ef8e64f6f239fb47d/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2", size = 2005652 }, - { url = "https://files.pythonhosted.org/packages/d2/7a/996d8bd75f3eda405e3dd219ff5ff0a283cd8e34add39d8ef9157e722867/pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a", size = 2113306 }, - { url = "https://files.pythonhosted.org/packages/ff/84/daf2a6fb2db40ffda6578a7e8c5a6e9c8affb251a05c233ae37098118788/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac", size = 2073720 }, - { url = "https://files.pythonhosted.org/packages/77/fb/2258da019f4825128445ae79456a5499c032b55849dbd5bed78c95ccf163/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a", size = 2244915 }, - { url = "https://files.pythonhosted.org/packages/d8/7a/925ff73756031289468326e355b6fa8316960d0d65f8b5d6b3a3e7866de7/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b", size = 2241884 }, - { url = "https://files.pythonhosted.org/packages/0b/b0/249ee6d2646f1cdadcb813805fe76265745c4010cf20a8eba7b0e639d9b2/pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22", size = 1910496 }, - { url = "https://files.pythonhosted.org/packages/66/ff/172ba8f12a42d4b552917aa65d1f2328990d3ccfc01d5b7c943ec084299f/pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640", size = 1955019 }, - { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584 }, - { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071 }, - { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823 }, - { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792 }, - { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338 }, - { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998 }, - { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200 }, - { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890 }, - { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359 }, - { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883 }, - { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074 }, - { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538 }, - { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909 }, - { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786 }, - { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000 }, - { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996 }, - { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957 }, - { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199 }, - { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296 }, - { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109 }, - { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028 }, - { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044 }, - { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881 }, - { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034 }, - { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187 }, - { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628 }, - { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866 }, - { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894 }, - { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688 }, - { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808 }, - { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580 }, - { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859 }, - { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810 }, - { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498 }, - { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611 }, - { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924 }, - { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196 }, - { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389 }, - { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223 }, - { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473 }, - { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269 }, - { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921 }, - { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162 }, - { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560 }, - { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777 }, - { url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982 }, - { url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412 }, - { url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749 }, - { url = "https://files.pythonhosted.org/packages/12/73/8cd57e20afba760b21b742106f9dbdfa6697f1570b189c7457a1af4cd8a0/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e", size = 2067527 }, - { url = "https://files.pythonhosted.org/packages/e3/d5/0bb5d988cc019b3cba4a78f2d4b3854427fc47ee8ec8e9eaabf787da239c/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c", size = 2108225 }, - { url = "https://files.pythonhosted.org/packages/f1/c5/00c02d1571913d496aabf146106ad8239dc132485ee22efe08085084ff7c/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec", size = 2069490 }, - { url = "https://files.pythonhosted.org/packages/22/a8/dccc38768274d3ed3a59b5d06f59ccb845778687652daa71df0cab4040d7/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052", size = 2237525 }, - { url = "https://files.pythonhosted.org/packages/d4/e7/4f98c0b125dda7cf7ccd14ba936218397b44f50a56dd8c16a3091df116c3/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c", size = 2238446 }, - { url = "https://files.pythonhosted.org/packages/ce/91/2ec36480fdb0b783cd9ef6795753c1dea13882f2e68e73bce76ae8c21e6a/pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808", size = 2066678 }, - { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200 }, - { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123 }, - { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852 }, - { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484 }, - { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896 }, - { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475 }, - { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013 }, - { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715 }, - { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757 }, +sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/92/b31726561b5dae176c2d2c2dc43a9c5bfba5d32f96f8b4c0a600dd492447/pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8", size = 2028817, upload-time = "2025-04-23T18:30:43.919Z" }, + { url = "https://files.pythonhosted.org/packages/a3/44/3f0b95fafdaca04a483c4e685fe437c6891001bf3ce8b2fded82b9ea3aa1/pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d", size = 1861357, upload-time = "2025-04-23T18:30:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/30/97/e8f13b55766234caae05372826e8e4b3b96e7b248be3157f53237682e43c/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d", size = 1898011, upload-time = "2025-04-23T18:30:47.591Z" }, + { url = "https://files.pythonhosted.org/packages/9b/a3/99c48cf7bafc991cc3ee66fd544c0aae8dc907b752f1dad2d79b1b5a471f/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572", size = 1982730, upload-time = "2025-04-23T18:30:49.328Z" }, + { url = "https://files.pythonhosted.org/packages/de/8e/a5b882ec4307010a840fb8b58bd9bf65d1840c92eae7534c7441709bf54b/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02", size = 2136178, upload-time = "2025-04-23T18:30:50.907Z" }, + { url = "https://files.pythonhosted.org/packages/e4/bb/71e35fc3ed05af6834e890edb75968e2802fe98778971ab5cba20a162315/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b", size = 2736462, upload-time = "2025-04-23T18:30:52.083Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/c8f7593e6bc7066289bbc366f2235701dcbebcd1ff0ef8e64f6f239fb47d/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2", size = 2005652, upload-time = "2025-04-23T18:30:53.389Z" }, + { url = "https://files.pythonhosted.org/packages/d2/7a/996d8bd75f3eda405e3dd219ff5ff0a283cd8e34add39d8ef9157e722867/pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a", size = 2113306, upload-time = "2025-04-23T18:30:54.661Z" }, + { url = "https://files.pythonhosted.org/packages/ff/84/daf2a6fb2db40ffda6578a7e8c5a6e9c8affb251a05c233ae37098118788/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac", size = 2073720, upload-time = "2025-04-23T18:30:56.11Z" }, + { url = "https://files.pythonhosted.org/packages/77/fb/2258da019f4825128445ae79456a5499c032b55849dbd5bed78c95ccf163/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a", size = 2244915, upload-time = "2025-04-23T18:30:57.501Z" }, + { url = "https://files.pythonhosted.org/packages/d8/7a/925ff73756031289468326e355b6fa8316960d0d65f8b5d6b3a3e7866de7/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b", size = 2241884, upload-time = "2025-04-23T18:30:58.867Z" }, + { url = "https://files.pythonhosted.org/packages/0b/b0/249ee6d2646f1cdadcb813805fe76265745c4010cf20a8eba7b0e639d9b2/pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22", size = 1910496, upload-time = "2025-04-23T18:31:00.078Z" }, + { url = "https://files.pythonhosted.org/packages/66/ff/172ba8f12a42d4b552917aa65d1f2328990d3ccfc01d5b7c943ec084299f/pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640", size = 1955019, upload-time = "2025-04-23T18:31:01.335Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" }, + { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" }, + { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" }, + { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" }, + { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" }, + { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" }, + { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" }, + { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" }, + { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" }, + { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" }, + { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" }, + { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" }, + { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" }, + { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" }, + { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" }, + { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" }, + { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" }, + { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" }, + { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, + { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, + { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, + { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, + { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, + { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, + { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, + { url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982, upload-time = "2025-04-23T18:32:53.14Z" }, + { url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412, upload-time = "2025-04-23T18:32:55.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749, upload-time = "2025-04-23T18:32:57.546Z" }, + { url = "https://files.pythonhosted.org/packages/12/73/8cd57e20afba760b21b742106f9dbdfa6697f1570b189c7457a1af4cd8a0/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e", size = 2067527, upload-time = "2025-04-23T18:32:59.771Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d5/0bb5d988cc019b3cba4a78f2d4b3854427fc47ee8ec8e9eaabf787da239c/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c", size = 2108225, upload-time = "2025-04-23T18:33:04.51Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c5/00c02d1571913d496aabf146106ad8239dc132485ee22efe08085084ff7c/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec", size = 2069490, upload-time = "2025-04-23T18:33:06.391Z" }, + { url = "https://files.pythonhosted.org/packages/22/a8/dccc38768274d3ed3a59b5d06f59ccb845778687652daa71df0cab4040d7/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052", size = 2237525, upload-time = "2025-04-23T18:33:08.44Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e7/4f98c0b125dda7cf7ccd14ba936218397b44f50a56dd8c16a3091df116c3/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c", size = 2238446, upload-time = "2025-04-23T18:33:10.313Z" }, + { url = "https://files.pythonhosted.org/packages/ce/91/2ec36480fdb0b783cd9ef6795753c1dea13882f2e68e73bce76ae8c21e6a/pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808", size = 2066678, upload-time = "2025-04-23T18:33:12.224Z" }, + { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" }, + { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" }, + { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" }, + { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" }, + { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" }, + { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" }, + { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" }, ] [[package]] @@ -3363,9 +3441,9 @@ dependencies = [ { 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 } +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 }, + { 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]] @@ -3377,27 +3455,27 @@ dependencies = [ { name = "ruamel-yaml" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/6c/6bc8f39406cdeed864578df88f52a63db27bd24aa8473206d650bc4fa1d8/pydantic_yaml-1.6.0.tar.gz", hash = "sha256:ce5f10b65d95ca45846a36ea8dae54e550fa3058e7d6218e0179184d9bf6f660", size = 25782 } +sdist = { url = "https://files.pythonhosted.org/packages/bb/6c/6bc8f39406cdeed864578df88f52a63db27bd24aa8473206d650bc4fa1d8/pydantic_yaml-1.6.0.tar.gz", hash = "sha256:ce5f10b65d95ca45846a36ea8dae54e550fa3058e7d6218e0179184d9bf6f660", size = 25782, upload-time = "2025-08-08T21:01:13.097Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/39/8d263fbcb409a8f5dd78ac8f89f1e6af1d4e4d9fbb7f856ca3245b354809/pydantic_yaml-1.6.0-py3-none-any.whl", hash = "sha256:02cb800b455b68daeeb74ad736c252a94a0b203da5fbbeef02539d468e1d98f8", size = 22511 }, + { url = "https://files.pythonhosted.org/packages/ba/39/8d263fbcb409a8f5dd78ac8f89f1e6af1d4e4d9fbb7f856ca3245b354809/pydantic_yaml-1.6.0-py3-none-any.whl", hash = "sha256:02cb800b455b68daeeb74ad736c252a94a0b203da5fbbeef02539d468e1d98f8", size = 22511, upload-time = "2025-08-08T21:01:11.425Z" }, ] [[package]] name = "pygments" version = "2.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, ] [[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 } +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 }, + { 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.optional-dependencies] @@ -3409,44 +3487,44 @@ crypto = [ name = "pypdfium2" version = "4.30.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/55/d4/905e621c62598a08168c272b42fc00136c8861cfce97afb2a1ecbd99487a/pypdfium2-4.30.1.tar.gz", hash = "sha256:5f5c7c6d03598e107d974f66b220a49436aceb191da34cda5f692be098a814ce", size = 164854 } +sdist = { url = "https://files.pythonhosted.org/packages/55/d4/905e621c62598a08168c272b42fc00136c8861cfce97afb2a1ecbd99487a/pypdfium2-4.30.1.tar.gz", hash = "sha256:5f5c7c6d03598e107d974f66b220a49436aceb191da34cda5f692be098a814ce", size = 164854, upload-time = "2024-12-19T19:28:11.459Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/8e/3ce0856b3af0f058dd3655ce57d31d1dbde4d4bd0e172022ffbf1b58a4b9/pypdfium2-4.30.1-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:e07c47633732cc18d890bb7e965ad28a9c5a932e548acb928596f86be2e5ae37", size = 2889836 }, - { url = "https://files.pythonhosted.org/packages/c2/6a/f6995b21f9c6c155487ce7df70632a2df1ba49efcb291b9943ea45f28b15/pypdfium2-4.30.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5ea2d44e96d361123b67b00f527017aa9c847c871b5714e013c01c3eb36a79fe", size = 2769232 }, - { url = "https://files.pythonhosted.org/packages/53/91/79060923148e6d380b8a299b32bba46d70aac5fe1cd4f04320bcbd1a48d3/pypdfium2-4.30.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de7a3a36803171b3f66911131046d65a732f9e7834438191cb58235e6163c4e", size = 2847531 }, - { url = "https://files.pythonhosted.org/packages/a8/6c/93507f87c159e747eaab54352c0fccbaec3f1b3749d0bb9085a47899f898/pypdfium2-4.30.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8a4231efb13170354f568c722d6540b8d5b476b08825586d48ef70c40d16e03", size = 2636266 }, - { url = "https://files.pythonhosted.org/packages/24/dc/d56f74a092f2091e328d6485f16562e2fc51cffb0ad6d5c616d80c1eb53c/pypdfium2-4.30.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f434a4934e8244aa95343ffcf24e9ad9f120dbb4785f631bb40a88c39292493", size = 2919296 }, - { url = "https://files.pythonhosted.org/packages/be/d9/a2f1ee03d47fbeb48bcfde47ed7155772739622cfadf7135a84ba6a97824/pypdfium2-4.30.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f454032a0bc7681900170f67d8711b3942824531e765f91c2f5ce7937f999794", size = 2866119 }, - { url = "https://files.pythonhosted.org/packages/01/47/6aa019c32aa39d3f33347c458c0c5887e84096cbe444456402bc97e66704/pypdfium2-4.30.1-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:bbf9130a72370ee9d602e39949b902db669a2a1c24746a91e5586eb829055d9f", size = 6228684 }, - { url = "https://files.pythonhosted.org/packages/4c/07/2954c15b3f7c85ceb80cad36757fd41b3aba0dd14e68f4bed9ce3f2e7e74/pypdfium2-4.30.1-py3-none-musllinux_1_1_i686.whl", hash = "sha256:5cb52884b1583b96e94fd78542c63bb42e06df5e8f9e52f8f31f5ad5a1e53367", size = 6231815 }, - { url = "https://files.pythonhosted.org/packages/b4/9b/b4667e95754624f4af5a912001abba90c046e1c80d4a4e887f0af664ffec/pypdfium2-4.30.1-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:1a9e372bd4867ff223cc8c338e33fe11055dad12f22885950fc27646cc8d9122", size = 6313429 }, - { url = "https://files.pythonhosted.org/packages/43/38/f9e77cf55ba5546a39fa659404b78b97de2ca344848271e7731efb0954cd/pypdfium2-4.30.1-py3-none-win32.whl", hash = "sha256:421f1cf205e213e07c1f2934905779547f4f4a2ff2f59dde29da3d511d3fc806", size = 2834989 }, - { url = "https://files.pythonhosted.org/packages/a4/f3/8d3a350efb4286b5ebdabcf6736f51d8e3b10dbe68804c6930b00f5cf329/pypdfium2-4.30.1-py3-none-win_amd64.whl", hash = "sha256:598a7f20264ab5113853cba6d86c4566e4356cad037d7d1f849c8c9021007e05", size = 2960157 }, - { url = "https://files.pythonhosted.org/packages/e1/6b/2706497c86e8d69fb76afe5ea857fe1794621aa0f3b1d863feb953fe0f22/pypdfium2-4.30.1-py3-none-win_arm64.whl", hash = "sha256:c2b6d63f6d425d9416c08d2511822b54b8e3ac38e639fc41164b1d75584b3a8c", size = 2814810 }, + { url = "https://files.pythonhosted.org/packages/30/8e/3ce0856b3af0f058dd3655ce57d31d1dbde4d4bd0e172022ffbf1b58a4b9/pypdfium2-4.30.1-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:e07c47633732cc18d890bb7e965ad28a9c5a932e548acb928596f86be2e5ae37", size = 2889836, upload-time = "2024-12-19T19:27:39.531Z" }, + { url = "https://files.pythonhosted.org/packages/c2/6a/f6995b21f9c6c155487ce7df70632a2df1ba49efcb291b9943ea45f28b15/pypdfium2-4.30.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5ea2d44e96d361123b67b00f527017aa9c847c871b5714e013c01c3eb36a79fe", size = 2769232, upload-time = "2024-12-19T19:27:43.227Z" }, + { url = "https://files.pythonhosted.org/packages/53/91/79060923148e6d380b8a299b32bba46d70aac5fe1cd4f04320bcbd1a48d3/pypdfium2-4.30.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de7a3a36803171b3f66911131046d65a732f9e7834438191cb58235e6163c4e", size = 2847531, upload-time = "2024-12-19T19:27:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/a8/6c/93507f87c159e747eaab54352c0fccbaec3f1b3749d0bb9085a47899f898/pypdfium2-4.30.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8a4231efb13170354f568c722d6540b8d5b476b08825586d48ef70c40d16e03", size = 2636266, upload-time = "2024-12-19T19:27:49.767Z" }, + { url = "https://files.pythonhosted.org/packages/24/dc/d56f74a092f2091e328d6485f16562e2fc51cffb0ad6d5c616d80c1eb53c/pypdfium2-4.30.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f434a4934e8244aa95343ffcf24e9ad9f120dbb4785f631bb40a88c39292493", size = 2919296, upload-time = "2024-12-19T19:27:51.767Z" }, + { url = "https://files.pythonhosted.org/packages/be/d9/a2f1ee03d47fbeb48bcfde47ed7155772739622cfadf7135a84ba6a97824/pypdfium2-4.30.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f454032a0bc7681900170f67d8711b3942824531e765f91c2f5ce7937f999794", size = 2866119, upload-time = "2024-12-19T19:27:53.561Z" }, + { url = "https://files.pythonhosted.org/packages/01/47/6aa019c32aa39d3f33347c458c0c5887e84096cbe444456402bc97e66704/pypdfium2-4.30.1-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:bbf9130a72370ee9d602e39949b902db669a2a1c24746a91e5586eb829055d9f", size = 6228684, upload-time = "2024-12-19T19:27:56.781Z" }, + { url = "https://files.pythonhosted.org/packages/4c/07/2954c15b3f7c85ceb80cad36757fd41b3aba0dd14e68f4bed9ce3f2e7e74/pypdfium2-4.30.1-py3-none-musllinux_1_1_i686.whl", hash = "sha256:5cb52884b1583b96e94fd78542c63bb42e06df5e8f9e52f8f31f5ad5a1e53367", size = 6231815, upload-time = "2024-12-19T19:28:00.351Z" }, + { url = "https://files.pythonhosted.org/packages/b4/9b/b4667e95754624f4af5a912001abba90c046e1c80d4a4e887f0af664ffec/pypdfium2-4.30.1-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:1a9e372bd4867ff223cc8c338e33fe11055dad12f22885950fc27646cc8d9122", size = 6313429, upload-time = "2024-12-19T19:28:02.536Z" }, + { url = "https://files.pythonhosted.org/packages/43/38/f9e77cf55ba5546a39fa659404b78b97de2ca344848271e7731efb0954cd/pypdfium2-4.30.1-py3-none-win32.whl", hash = "sha256:421f1cf205e213e07c1f2934905779547f4f4a2ff2f59dde29da3d511d3fc806", size = 2834989, upload-time = "2024-12-19T19:28:04.657Z" }, + { url = "https://files.pythonhosted.org/packages/a4/f3/8d3a350efb4286b5ebdabcf6736f51d8e3b10dbe68804c6930b00f5cf329/pypdfium2-4.30.1-py3-none-win_amd64.whl", hash = "sha256:598a7f20264ab5113853cba6d86c4566e4356cad037d7d1f849c8c9021007e05", size = 2960157, upload-time = "2024-12-19T19:28:07.772Z" }, + { url = "https://files.pythonhosted.org/packages/e1/6b/2706497c86e8d69fb76afe5ea857fe1794621aa0f3b1d863feb953fe0f22/pypdfium2-4.30.1-py3-none-win_arm64.whl", hash = "sha256:c2b6d63f6d425d9416c08d2511822b54b8e3ac38e639fc41164b1d75584b3a8c", size = 2814810, upload-time = "2024-12-19T19:28:09.857Z" }, ] [[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 } +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 } +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 }, + { 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 } +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 }, + { 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]] @@ -3461,9 +3539,9 @@ dependencies = [ { name = "pluggy" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891 } +sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634 }, + { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, ] [[package]] @@ -3473,9 +3551,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156 } +sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156, upload-time = "2025-03-25T06:22:28.883Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7f/338843f449ace853647ace35870874f69a764d251872ed1b4de9f234822c/pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0", size = 19694 }, + { url = "https://files.pythonhosted.org/packages/20/7f/338843f449ace853647ace35870874f69a764d251872ed1b4de9f234822c/pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0", size = 19694, upload-time = "2025-03-25T06:22:27.807Z" }, ] [[package]] @@ -3486,9 +3564,9 @@ dependencies = [ { name = "coverage", extra = ["toml"] }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/25/69/5f1e57f6c5a39f81411b550027bf72842c4567ff5fd572bed1edc9e4b5d9/pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a", size = 66857 } +sdist = { url = "https://files.pythonhosted.org/packages/25/69/5f1e57f6c5a39f81411b550027bf72842c4567ff5fd572bed1edc9e4b5d9/pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a", size = 66857, upload-time = "2025-04-05T14:07:51.592Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde", size = 23841 }, + { url = "https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde", size = 23841, upload-time = "2025-04-05T14:07:49.641Z" }, ] [[package]] @@ -3498,27 +3576,27 @@ 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/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 }, + { 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-dotenv" version = "1.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920 } +sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920, upload-time = "2025-03-25T10:14:56.835Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256 }, + { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256, upload-time = "2025-03-25T10:14:55.034Z" }, ] [[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 } +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 }, + { 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]] @@ -3534,7 +3612,7 @@ dependencies = [ { name = "networkx", version = "3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/4b/e37e4e5d5ee1179694917b445768bdbfb084f5a59ecd38089d3413d4c70f/pyvis-0.3.2-py3-none-any.whl", hash = "sha256:5720c4ca8161dc5d9ab352015723abb7a8bb8fb443edeb07f7a322db34a97555", size = 756038 }, + { url = "https://files.pythonhosted.org/packages/ab/4b/e37e4e5d5ee1179694917b445768bdbfb084f5a59ecd38089d3413d4c70f/pyvis-0.3.2-py3-none-any.whl", hash = "sha256:5720c4ca8161dc5d9ab352015723abb7a8bb8fb443edeb07f7a322db34a97555", size = 756038, upload-time = "2023-02-24T20:29:46.758Z" }, ] [[package]] @@ -3542,65 +3620,82 @@ name = "pywin32" version = "311" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/40/44efbb0dfbd33aca6a6483191dae0716070ed99e2ecb0c53683f400a0b4f/pywin32-311-cp310-cp310-win32.whl", hash = "sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3", size = 8760432 }, - { url = "https://files.pythonhosted.org/packages/5e/bf/360243b1e953bd254a82f12653974be395ba880e7ec23e3731d9f73921cc/pywin32-311-cp310-cp310-win_amd64.whl", hash = "sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b", size = 9590103 }, - { url = "https://files.pythonhosted.org/packages/57/38/d290720e6f138086fb3d5ffe0b6caa019a791dd57866940c82e4eeaf2012/pywin32-311-cp310-cp310-win_arm64.whl", hash = "sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b", size = 8778557 }, - { url = "https://files.pythonhosted.org/packages/7c/af/449a6a91e5d6db51420875c54f6aff7c97a86a3b13a0b4f1a5c13b988de3/pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151", size = 8697031 }, - { url = "https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503", size = 9508308 }, - { url = "https://files.pythonhosted.org/packages/44/7b/9c2ab54f74a138c491aba1b1cd0795ba61f144c711daea84a88b63dc0f6c/pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2", size = 8703930 }, - { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543 }, - { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040 }, - { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102 }, - { url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700 }, - { url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700 }, - { url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318 }, - { url = "https://files.pythonhosted.org/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714 }, - { url = "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800 }, - { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540 }, + { url = "https://files.pythonhosted.org/packages/7b/40/44efbb0dfbd33aca6a6483191dae0716070ed99e2ecb0c53683f400a0b4f/pywin32-311-cp310-cp310-win32.whl", hash = "sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3", size = 8760432, upload-time = "2025-07-14T20:13:05.9Z" }, + { url = "https://files.pythonhosted.org/packages/5e/bf/360243b1e953bd254a82f12653974be395ba880e7ec23e3731d9f73921cc/pywin32-311-cp310-cp310-win_amd64.whl", hash = "sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b", size = 9590103, upload-time = "2025-07-14T20:13:07.698Z" }, + { url = "https://files.pythonhosted.org/packages/57/38/d290720e6f138086fb3d5ffe0b6caa019a791dd57866940c82e4eeaf2012/pywin32-311-cp310-cp310-win_arm64.whl", hash = "sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b", size = 8778557, upload-time = "2025-07-14T20:13:11.11Z" }, + { url = "https://files.pythonhosted.org/packages/7c/af/449a6a91e5d6db51420875c54f6aff7c97a86a3b13a0b4f1a5c13b988de3/pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151", size = 8697031, upload-time = "2025-07-14T20:13:13.266Z" }, + { url = "https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503", size = 9508308, upload-time = "2025-07-14T20:13:15.147Z" }, + { url = "https://files.pythonhosted.org/packages/44/7b/9c2ab54f74a138c491aba1b1cd0795ba61f144c711daea84a88b63dc0f6c/pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2", size = 8703930, upload-time = "2025-07-14T20:13:16.945Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" }, + { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" }, + { url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700, upload-time = "2025-07-14T20:13:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700, upload-time = "2025-07-14T20:13:28.243Z" }, + { url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318, upload-time = "2025-07-14T20:13:30.348Z" }, + { url = "https://files.pythonhosted.org/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714, upload-time = "2025-07-14T20:13:32.449Z" }, + { url = "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800, upload-time = "2025-07-14T20:13:34.312Z" }, + { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload-time = "2025-07-14T20:13:36.379Z" }, ] [[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 } -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 }, +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 = "redis" +version = "6.4.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/0d/d6/e8b92798a5bd67d659d51a18170e91c16ac3b59738d91894651ee255ed49/redis-6.4.0.tar.gz", hash = "sha256:b01bc7282b8444e28ec36b261df5375183bb47a07eb9c603f284e89cbc5ef010", size = 4647399, upload-time = "2025-08-07T08:10:11.441Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/02/89e2ed7e85db6c93dfa9e8f691c5087df4e3551ab39081a4d7c6d1f90e05/redis-6.4.0-py3-none-any.whl", hash = "sha256:f0544fa9604264e9464cdf4814e7d4830f74b165d52f2a330a760a88dd248b7f", size = 279847, upload-time = "2025-08-07T08:10:09.84Z" }, +] + +[package.optional-dependencies] +hiredis = [ + { name = "hiredis" }, ] [[package]] @@ -3612,78 +3707,78 @@ dependencies = [ { 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 } +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 }, + { 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 } -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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/45/3f/ef9589aba93e084cd3f8471fded352826dcae8489b650d0b9b27bc5bba8a/regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e", size = 261714 }, - { url = "https://files.pythonhosted.org/packages/42/7e/5f1b92c8468290c465fd50c5318da64319133231415a8aa6ea5ab995a815/regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519", size = 274042 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/26/b7/b14e2440156ab39e0177506c08c18accaf2b8932e39fb092074de733d868/regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", size = 261734 }, - { url = "https://files.pythonhosted.org/packages/80/32/763a6cc01d21fb3819227a1cc3f60fd251c13c37c27a73b8ff4315433a8e/regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", size = 274052 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135 }, - { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122 }, - { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545 }, +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]] @@ -3696,9 +3791,9 @@ dependencies = [ { 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 } +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 }, + { 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]] @@ -3709,9 +3804,9 @@ 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 } +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 }, + { 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]] @@ -3721,9 +3816,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888 } +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/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481 }, + { 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]] @@ -3735,108 +3830,108 @@ dependencies = [ { name = "pygments" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 } +sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149, upload-time = "2024-11-01T16:43:57.873Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 }, + { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424, upload-time = "2024-11-01T16:43:55.817Z" }, ] [[package]] name = "rpds-py" version = "0.25.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/a6/60184b7fc00dd3ca80ac635dd5b8577d444c57e8e8742cecabfacb829921/rpds_py-0.25.1.tar.gz", hash = "sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3", size = 27304 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/09/e1158988e50905b7f8306487a576b52d32aa9a87f79f7ab24ee8db8b6c05/rpds_py-0.25.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f4ad628b5174d5315761b67f212774a32f5bad5e61396d38108bd801c0a8f5d9", size = 373140 }, - { url = "https://files.pythonhosted.org/packages/e0/4b/a284321fb3c45c02fc74187171504702b2934bfe16abab89713eedfe672e/rpds_py-0.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c742af695f7525e559c16f1562cf2323db0e3f0fbdcabdf6865b095256b2d40", size = 358860 }, - { url = "https://files.pythonhosted.org/packages/4e/46/8ac9811150c75edeae9fc6fa0e70376c19bc80f8e1f7716981433905912b/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:605ffe7769e24b1800b4d024d24034405d9404f0bc2f55b6db3362cd34145a6f", size = 386179 }, - { url = "https://files.pythonhosted.org/packages/f3/ec/87eb42d83e859bce91dcf763eb9f2ab117142a49c9c3d17285440edb5b69/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ccc6f3ddef93243538be76f8e47045b4aad7a66a212cd3a0f23e34469473d36b", size = 400282 }, - { url = "https://files.pythonhosted.org/packages/68/c8/2a38e0707d7919c8c78e1d582ab15cf1255b380bcb086ca265b73ed6db23/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f70316f760174ca04492b5ab01be631a8ae30cadab1d1081035136ba12738cfa", size = 521824 }, - { url = "https://files.pythonhosted.org/packages/5e/2c/6a92790243569784dde84d144bfd12bd45102f4a1c897d76375076d730ab/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1dafef8df605fdb46edcc0bf1573dea0d6d7b01ba87f85cd04dc855b2b4479e", size = 411644 }, - { url = "https://files.pythonhosted.org/packages/eb/76/66b523ffc84cf47db56efe13ae7cf368dee2bacdec9d89b9baca5e2e6301/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0701942049095741a8aeb298a31b203e735d1c61f4423511d2b1a41dcd8a16da", size = 386955 }, - { url = "https://files.pythonhosted.org/packages/b6/b9/a362d7522feaa24dc2b79847c6175daa1c642817f4a19dcd5c91d3e2c316/rpds_py-0.25.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e87798852ae0b37c88babb7f7bbbb3e3fecc562a1c340195b44c7e24d403e380", size = 421039 }, - { url = "https://files.pythonhosted.org/packages/0f/c4/b5b6f70b4d719b6584716889fd3413102acf9729540ee76708d56a76fa97/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3bcce0edc1488906c2d4c75c94c70a0417e83920dd4c88fec1078c94843a6ce9", size = 563290 }, - { url = "https://files.pythonhosted.org/packages/87/a3/2e6e816615c12a8f8662c9d8583a12eb54c52557521ef218cbe3095a8afa/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e2f6a2347d3440ae789505693a02836383426249d5293541cd712e07e7aecf54", size = 592089 }, - { url = "https://files.pythonhosted.org/packages/c0/08/9b8e1050e36ce266135994e2c7ec06e1841f1c64da739daeb8afe9cb77a4/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4fd52d3455a0aa997734f3835cbc4c9f32571345143960e7d7ebfe7b5fbfa3b2", size = 558400 }, - { url = "https://files.pythonhosted.org/packages/f2/df/b40b8215560b8584baccd839ff5c1056f3c57120d79ac41bd26df196da7e/rpds_py-0.25.1-cp310-cp310-win32.whl", hash = "sha256:3f0b1798cae2bbbc9b9db44ee068c556d4737911ad53a4e5093d09d04b3bbc24", size = 219741 }, - { url = "https://files.pythonhosted.org/packages/10/99/e4c58be18cf5d8b40b8acb4122bc895486230b08f978831b16a3916bd24d/rpds_py-0.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3ebd879ab996537fc510a2be58c59915b5dd63bccb06d1ef514fee787e05984a", size = 231553 }, - { url = "https://files.pythonhosted.org/packages/95/e1/df13fe3ddbbea43567e07437f097863b20c99318ae1f58a0fe389f763738/rpds_py-0.25.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5f048bbf18b1f9120685c6d6bb70cc1a52c8cc11bdd04e643d28d3be0baf666d", size = 373341 }, - { url = "https://files.pythonhosted.org/packages/7a/58/deef4d30fcbcbfef3b6d82d17c64490d5c94585a2310544ce8e2d3024f83/rpds_py-0.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fbb0dbba559959fcb5d0735a0f87cdbca9e95dac87982e9b95c0f8f7ad10255", size = 359111 }, - { url = "https://files.pythonhosted.org/packages/bb/7e/39f1f4431b03e96ebaf159e29a0f82a77259d8f38b2dd474721eb3a8ac9b/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4ca54b9cf9d80b4016a67a0193ebe0bcf29f6b0a96f09db942087e294d3d4c2", size = 386112 }, - { url = "https://files.pythonhosted.org/packages/db/e7/847068a48d63aec2ae695a1646089620b3b03f8ccf9f02c122ebaf778f3c/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ee3e26eb83d39b886d2cb6e06ea701bba82ef30a0de044d34626ede51ec98b0", size = 400362 }, - { url = "https://files.pythonhosted.org/packages/3b/3d/9441d5db4343d0cee759a7ab4d67420a476cebb032081763de934719727b/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89706d0683c73a26f76a5315d893c051324d771196ae8b13e6ffa1ffaf5e574f", size = 522214 }, - { url = "https://files.pythonhosted.org/packages/a2/ec/2cc5b30d95f9f1a432c79c7a2f65d85e52812a8f6cbf8768724571710786/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2013ee878c76269c7b557a9a9c042335d732e89d482606990b70a839635feb7", size = 411491 }, - { url = "https://files.pythonhosted.org/packages/dc/6c/44695c1f035077a017dd472b6a3253553780837af2fac9b6ac25f6a5cb4d/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45e484db65e5380804afbec784522de84fa95e6bb92ef1bd3325d33d13efaebd", size = 386978 }, - { url = "https://files.pythonhosted.org/packages/b1/74/b4357090bb1096db5392157b4e7ed8bb2417dc7799200fcbaee633a032c9/rpds_py-0.25.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:48d64155d02127c249695abb87d39f0faf410733428d499867606be138161d65", size = 420662 }, - { url = "https://files.pythonhosted.org/packages/26/dd/8cadbebf47b96e59dfe8b35868e5c38a42272699324e95ed522da09d3a40/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:048893e902132fd6548a2e661fb38bf4896a89eea95ac5816cf443524a85556f", size = 563385 }, - { url = "https://files.pythonhosted.org/packages/c3/ea/92960bb7f0e7a57a5ab233662f12152085c7dc0d5468534c65991a3d48c9/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0317177b1e8691ab5879f4f33f4b6dc55ad3b344399e23df2e499de7b10a548d", size = 592047 }, - { url = "https://files.pythonhosted.org/packages/61/ad/71aabc93df0d05dabcb4b0c749277881f8e74548582d96aa1bf24379493a/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bffcf57826d77a4151962bf1701374e0fc87f536e56ec46f1abdd6a903354042", size = 557863 }, - { url = "https://files.pythonhosted.org/packages/93/0f/89df0067c41f122b90b76f3660028a466eb287cbe38efec3ea70e637ca78/rpds_py-0.25.1-cp311-cp311-win32.whl", hash = "sha256:cda776f1967cb304816173b30994faaf2fd5bcb37e73118a47964a02c348e1bc", size = 219627 }, - { url = "https://files.pythonhosted.org/packages/7c/8d/93b1a4c1baa903d0229374d9e7aa3466d751f1d65e268c52e6039c6e338e/rpds_py-0.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:dc3c1ff0abc91444cd20ec643d0f805df9a3661fcacf9c95000329f3ddf268a4", size = 231603 }, - { url = "https://files.pythonhosted.org/packages/cb/11/392605e5247bead2f23e6888e77229fbd714ac241ebbebb39a1e822c8815/rpds_py-0.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:5a3ddb74b0985c4387719fc536faced33cadf2172769540c62e2a94b7b9be1c4", size = 223967 }, - { url = "https://files.pythonhosted.org/packages/7f/81/28ab0408391b1dc57393653b6a0cf2014cc282cc2909e4615e63e58262be/rpds_py-0.25.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5ffe453cde61f73fea9430223c81d29e2fbf412a6073951102146c84e19e34c", size = 364647 }, - { url = "https://files.pythonhosted.org/packages/2c/9a/7797f04cad0d5e56310e1238434f71fc6939d0bc517192a18bb99a72a95f/rpds_py-0.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:115874ae5e2fdcfc16b2aedc95b5eef4aebe91b28e7e21951eda8a5dc0d3461b", size = 350454 }, - { url = "https://files.pythonhosted.org/packages/69/3c/93d2ef941b04898011e5d6eaa56a1acf46a3b4c9f4b3ad1bbcbafa0bee1f/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a714bf6e5e81b0e570d01f56e0c89c6375101b8463999ead3a93a5d2a4af91fa", size = 389665 }, - { url = "https://files.pythonhosted.org/packages/c1/57/ad0e31e928751dde8903a11102559628d24173428a0f85e25e187defb2c1/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35634369325906bcd01577da4c19e3b9541a15e99f31e91a02d010816b49bfda", size = 403873 }, - { url = "https://files.pythonhosted.org/packages/16/ad/c0c652fa9bba778b4f54980a02962748479dc09632e1fd34e5282cf2556c/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4cb2b3ddc16710548801c6fcc0cfcdeeff9dafbc983f77265877793f2660309", size = 525866 }, - { url = "https://files.pythonhosted.org/packages/2a/39/3e1839bc527e6fcf48d5fec4770070f872cdee6c6fbc9b259932f4e88a38/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ceca1cf097ed77e1a51f1dbc8d174d10cb5931c188a4505ff9f3e119dfe519b", size = 416886 }, - { url = "https://files.pythonhosted.org/packages/7a/95/dd6b91cd4560da41df9d7030a038298a67d24f8ca38e150562644c829c48/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2cd1a4b0c2b8c5e31ffff50d09f39906fe351389ba143c195566056c13a7ea", size = 390666 }, - { url = "https://files.pythonhosted.org/packages/64/48/1be88a820e7494ce0a15c2d390ccb7c52212370badabf128e6a7bb4cb802/rpds_py-0.25.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1de336a4b164c9188cb23f3703adb74a7623ab32d20090d0e9bf499a2203ad65", size = 425109 }, - { url = "https://files.pythonhosted.org/packages/cf/07/3e2a17927ef6d7720b9949ec1b37d1e963b829ad0387f7af18d923d5cfa5/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9fca84a15333e925dd59ce01da0ffe2ffe0d6e5d29a9eeba2148916d1824948c", size = 567244 }, - { url = "https://files.pythonhosted.org/packages/d2/e5/76cf010998deccc4f95305d827847e2eae9c568099c06b405cf96384762b/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88ec04afe0c59fa64e2f6ea0dd9657e04fc83e38de90f6de201954b4d4eb59bd", size = 596023 }, - { url = "https://files.pythonhosted.org/packages/52/9a/df55efd84403736ba37a5a6377b70aad0fd1cb469a9109ee8a1e21299a1c/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8bd2f19e312ce3e1d2c635618e8a8d8132892bb746a7cf74780a489f0f6cdcb", size = 561634 }, - { url = "https://files.pythonhosted.org/packages/ab/aa/dc3620dd8db84454aaf9374bd318f1aa02578bba5e567f5bf6b79492aca4/rpds_py-0.25.1-cp312-cp312-win32.whl", hash = "sha256:e5e2f7280d8d0d3ef06f3ec1b4fd598d386cc6f0721e54f09109a8132182fbfe", size = 222713 }, - { url = "https://files.pythonhosted.org/packages/a3/7f/7cef485269a50ed5b4e9bae145f512d2a111ca638ae70cc101f661b4defd/rpds_py-0.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:db58483f71c5db67d643857404da360dce3573031586034b7d59f245144cc192", size = 235280 }, - { url = "https://files.pythonhosted.org/packages/99/f2/c2d64f6564f32af913bf5f3f7ae41c7c263c5ae4c4e8f1a17af8af66cd46/rpds_py-0.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:6d50841c425d16faf3206ddbba44c21aa3310a0cebc3c1cdfc3e3f4f9f6f5728", size = 225399 }, - { url = "https://files.pythonhosted.org/packages/2b/da/323848a2b62abe6a0fec16ebe199dc6889c5d0a332458da8985b2980dffe/rpds_py-0.25.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:659d87430a8c8c704d52d094f5ba6fa72ef13b4d385b7e542a08fc240cb4a559", size = 364498 }, - { url = "https://files.pythonhosted.org/packages/1f/b4/4d3820f731c80fd0cd823b3e95b9963fec681ae45ba35b5281a42382c67d/rpds_py-0.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68f6f060f0bbdfb0245267da014d3a6da9be127fe3e8cc4a68c6f833f8a23bb1", size = 350083 }, - { url = "https://files.pythonhosted.org/packages/d5/b1/3a8ee1c9d480e8493619a437dec685d005f706b69253286f50f498cbdbcf/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:083a9513a33e0b92cf6e7a6366036c6bb43ea595332c1ab5c8ae329e4bcc0a9c", size = 389023 }, - { url = "https://files.pythonhosted.org/packages/3b/31/17293edcfc934dc62c3bf74a0cb449ecd549531f956b72287203e6880b87/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:816568614ecb22b18a010c7a12559c19f6fe993526af88e95a76d5a60b8b75fb", size = 403283 }, - { url = "https://files.pythonhosted.org/packages/d1/ca/e0f0bc1a75a8925024f343258c8ecbd8828f8997ea2ac71e02f67b6f5299/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c6564c0947a7f52e4792983f8e6cf9bac140438ebf81f527a21d944f2fd0a40", size = 524634 }, - { url = "https://files.pythonhosted.org/packages/3e/03/5d0be919037178fff33a6672ffc0afa04ea1cfcb61afd4119d1b5280ff0f/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c4a128527fe415d73cf1f70a9a688d06130d5810be69f3b553bf7b45e8acf79", size = 416233 }, - { url = "https://files.pythonhosted.org/packages/05/7c/8abb70f9017a231c6c961a8941403ed6557664c0913e1bf413cbdc039e75/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a49e1d7a4978ed554f095430b89ecc23f42014a50ac385eb0c4d163ce213c325", size = 390375 }, - { url = "https://files.pythonhosted.org/packages/7a/ac/a87f339f0e066b9535074a9f403b9313fd3892d4a164d5d5f5875ac9f29f/rpds_py-0.25.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d74ec9bc0e2feb81d3f16946b005748119c0f52a153f6db6a29e8cd68636f295", size = 424537 }, - { url = "https://files.pythonhosted.org/packages/1f/8f/8d5c1567eaf8c8afe98a838dd24de5013ce6e8f53a01bd47fe8bb06b5533/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3af5b4cc10fa41e5bc64e5c198a1b2d2864337f8fcbb9a67e747e34002ce812b", size = 566425 }, - { url = "https://files.pythonhosted.org/packages/95/33/03016a6be5663b389c8ab0bbbcca68d9e96af14faeff0a04affcb587e776/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79dc317a5f1c51fd9c6a0c4f48209c6b8526d0524a6904fc1076476e79b00f98", size = 595197 }, - { url = "https://files.pythonhosted.org/packages/33/8d/da9f4d3e208c82fda311bff0cf0a19579afceb77cf456e46c559a1c075ba/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1521031351865e0181bc585147624d66b3b00a84109b57fcb7a779c3ec3772cd", size = 561244 }, - { url = "https://files.pythonhosted.org/packages/e2/b3/39d5dcf7c5f742ecd6dbc88f6f84ae54184b92f5f387a4053be2107b17f1/rpds_py-0.25.1-cp313-cp313-win32.whl", hash = "sha256:5d473be2b13600b93a5675d78f59e63b51b1ba2d0476893415dfbb5477e65b31", size = 222254 }, - { url = "https://files.pythonhosted.org/packages/5f/19/2d6772c8eeb8302c5f834e6d0dfd83935a884e7c5ce16340c7eaf89ce925/rpds_py-0.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7b74e92a3b212390bdce1d93da9f6488c3878c1d434c5e751cbc202c5e09500", size = 234741 }, - { url = "https://files.pythonhosted.org/packages/5b/5a/145ada26cfaf86018d0eb304fe55eafdd4f0b6b84530246bb4a7c4fb5c4b/rpds_py-0.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:dd326a81afe332ede08eb39ab75b301d5676802cdffd3a8f287a5f0b694dc3f5", size = 224830 }, - { url = "https://files.pythonhosted.org/packages/4b/ca/d435844829c384fd2c22754ff65889c5c556a675d2ed9eb0e148435c6690/rpds_py-0.25.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:a58d1ed49a94d4183483a3ce0af22f20318d4a1434acee255d683ad90bf78129", size = 359668 }, - { url = "https://files.pythonhosted.org/packages/1f/01/b056f21db3a09f89410d493d2f6614d87bb162499f98b649d1dbd2a81988/rpds_py-0.25.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f251bf23deb8332823aef1da169d5d89fa84c89f67bdfb566c49dea1fccfd50d", size = 345649 }, - { url = "https://files.pythonhosted.org/packages/e0/0f/e0d00dc991e3d40e03ca36383b44995126c36b3eafa0ccbbd19664709c88/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dbd586bfa270c1103ece2109314dd423df1fa3d9719928b5d09e4840cec0d72", size = 384776 }, - { url = "https://files.pythonhosted.org/packages/9f/a2/59374837f105f2ca79bde3c3cd1065b2f8c01678900924949f6392eab66d/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d273f136e912aa101a9274c3145dcbddbe4bac560e77e6d5b3c9f6e0ed06d34", size = 395131 }, - { url = "https://files.pythonhosted.org/packages/9c/dc/48e8d84887627a0fe0bac53f0b4631e90976fd5d35fff8be66b8e4f3916b/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:666fa7b1bd0a3810a7f18f6d3a25ccd8866291fbbc3c9b912b917a6715874bb9", size = 520942 }, - { url = "https://files.pythonhosted.org/packages/7c/f5/ee056966aeae401913d37befeeab57a4a43a4f00099e0a20297f17b8f00c/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:921954d7fbf3fccc7de8f717799304b14b6d9a45bbeec5a8d7408ccbf531faf5", size = 411330 }, - { url = "https://files.pythonhosted.org/packages/ab/74/b2cffb46a097cefe5d17f94ede7a174184b9d158a0aeb195f39f2c0361e8/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3d86373ff19ca0441ebeb696ef64cb58b8b5cbacffcda5a0ec2f3911732a194", size = 387339 }, - { url = "https://files.pythonhosted.org/packages/7f/9a/0ff0b375dcb5161c2b7054e7d0b7575f1680127505945f5cabaac890bc07/rpds_py-0.25.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c8980cde3bb8575e7c956a530f2c217c1d6aac453474bf3ea0f9c89868b531b6", size = 418077 }, - { url = "https://files.pythonhosted.org/packages/0d/a1/fda629bf20d6b698ae84c7c840cfb0e9e4200f664fc96e1f456f00e4ad6e/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8eb8c84ecea987a2523e057c0d950bcb3f789696c0499290b8d7b3107a719d78", size = 562441 }, - { url = "https://files.pythonhosted.org/packages/20/15/ce4b5257f654132f326f4acd87268e1006cc071e2c59794c5bdf4bebbb51/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e43a005671a9ed5a650f3bc39e4dbccd6d4326b24fb5ea8be5f3a43a6f576c72", size = 590750 }, - { url = "https://files.pythonhosted.org/packages/fb/ab/e04bf58a8d375aeedb5268edcc835c6a660ebf79d4384d8e0889439448b0/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:58f77c60956501a4a627749a6dcb78dac522f249dd96b5c9f1c6af29bfacfb66", size = 558891 }, - { url = "https://files.pythonhosted.org/packages/90/82/cb8c6028a6ef6cd2b7991e2e4ced01c854b6236ecf51e81b64b569c43d73/rpds_py-0.25.1-cp313-cp313t-win32.whl", hash = "sha256:2cb9e5b5e26fc02c8a4345048cd9998c2aca7c2712bd1b36da0c72ee969a3523", size = 218718 }, - { url = "https://files.pythonhosted.org/packages/b6/97/5a4b59697111c89477d20ba8a44df9ca16b41e737fa569d5ae8bff99e650/rpds_py-0.25.1-cp313-cp313t-win_amd64.whl", hash = "sha256:401ca1c4a20cc0510d3435d89c069fe0a9ae2ee6495135ac46bdd49ec0495763", size = 232218 }, - { url = "https://files.pythonhosted.org/packages/78/ff/566ce53529b12b4f10c0a348d316bd766970b7060b4fd50f888be3b3b281/rpds_py-0.25.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b24bf3cd93d5b6ecfbedec73b15f143596c88ee249fa98cefa9a9dc9d92c6f28", size = 373931 }, - { url = "https://files.pythonhosted.org/packages/83/5d/deba18503f7c7878e26aa696e97f051175788e19d5336b3b0e76d3ef9256/rpds_py-0.25.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:0eb90e94f43e5085623932b68840b6f379f26db7b5c2e6bcef3179bd83c9330f", size = 359074 }, - { url = "https://files.pythonhosted.org/packages/0d/74/313415c5627644eb114df49c56a27edba4d40cfd7c92bd90212b3604ca84/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d50e4864498a9ab639d6d8854b25e80642bd362ff104312d9770b05d66e5fb13", size = 387255 }, - { url = "https://files.pythonhosted.org/packages/8c/c8/c723298ed6338963d94e05c0f12793acc9b91d04ed7c4ba7508e534b7385/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c9409b47ba0650544b0bb3c188243b83654dfe55dcc173a86832314e1a6a35d", size = 400714 }, - { url = "https://files.pythonhosted.org/packages/33/8a/51f1f6aa653c2e110ed482ef2ae94140d56c910378752a1b483af11019ee/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:796ad874c89127c91970652a4ee8b00d56368b7e00d3477f4415fe78164c8000", size = 523105 }, - { url = "https://files.pythonhosted.org/packages/c7/a4/7873d15c088ad3bff36910b29ceb0f178e4b3232c2adbe9198de68a41e63/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:85608eb70a659bf4c1142b2781083d4b7c0c4e2c90eff11856a9754e965b2540", size = 411499 }, - { url = "https://files.pythonhosted.org/packages/90/f3/0ce1437befe1410766d11d08239333ac1b2d940f8a64234ce48a7714669c/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4feb9211d15d9160bc85fa72fed46432cdc143eb9cf6d5ca377335a921ac37b", size = 387918 }, - { url = "https://files.pythonhosted.org/packages/94/d4/5551247988b2a3566afb8a9dba3f1d4a3eea47793fd83000276c1a6c726e/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ccfa689b9246c48947d31dd9d8b16d89a0ecc8e0e26ea5253068efb6c542b76e", size = 421705 }, - { url = "https://files.pythonhosted.org/packages/b0/25/5960f28f847bf736cc7ee3c545a7e1d2f3b5edaf82c96fb616c2f5ed52d0/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:3c5b317ecbd8226887994852e85de562f7177add602514d4ac40f87de3ae45a8", size = 564489 }, - { url = "https://files.pythonhosted.org/packages/02/66/1c99884a0d44e8c2904d3c4ec302f995292d5dde892c3bf7685ac1930146/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:454601988aab2c6e8fd49e7634c65476b2b919647626208e376afcd22019eeb8", size = 592557 }, - { url = "https://files.pythonhosted.org/packages/55/ae/4aeac84ebeffeac14abb05b3bb1d2f728d00adb55d3fb7b51c9fa772e760/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:1c0c434a53714358532d13539272db75a5ed9df75a4a090a753ac7173ec14e11", size = 558691 }, - { url = "https://files.pythonhosted.org/packages/41/b3/728a08ff6f5e06fe3bb9af2e770e9d5fd20141af45cff8dfc62da4b2d0b3/rpds_py-0.25.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f73ce1512e04fbe2bc97836e89830d6b4314c171587a99688082d090f934d20a", size = 231651 }, - { url = "https://files.pythonhosted.org/packages/49/74/48f3df0715a585cbf5d34919c9c757a4c92c1a9eba059f2d334e72471f70/rpds_py-0.25.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ee86d81551ec68a5c25373c5643d343150cc54672b5e9a0cafc93c1870a53954", size = 374208 }, - { url = "https://files.pythonhosted.org/packages/55/b0/9b01bb11ce01ec03d05e627249cc2c06039d6aa24ea5a22a39c312167c10/rpds_py-0.25.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:89c24300cd4a8e4a51e55c31a8ff3918e6651b241ee8876a42cc2b2a078533ba", size = 359262 }, - { url = "https://files.pythonhosted.org/packages/a9/eb/5395621618f723ebd5116c53282052943a726dba111b49cd2071f785b665/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:771c16060ff4e79584dc48902a91ba79fd93eade3aa3a12d6d2a4aadaf7d542b", size = 387366 }, - { url = "https://files.pythonhosted.org/packages/68/73/3d51442bdb246db619d75039a50ea1cf8b5b4ee250c3e5cd5c3af5981cd4/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:785ffacd0ee61c3e60bdfde93baa6d7c10d86f15655bd706c89da08068dc5038", size = 400759 }, - { url = "https://files.pythonhosted.org/packages/b7/4c/3a32d5955d7e6cb117314597bc0f2224efc798428318b13073efe306512a/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a40046a529cc15cef88ac5ab589f83f739e2d332cb4d7399072242400ed68c9", size = 523128 }, - { url = "https://files.pythonhosted.org/packages/be/95/1ffccd3b0bb901ae60b1dd4b1be2ab98bb4eb834cd9b15199888f5702f7b/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:85fc223d9c76cabe5d0bff82214459189720dc135db45f9f66aa7cffbf9ff6c1", size = 411597 }, - { url = "https://files.pythonhosted.org/packages/ef/6d/6e6cd310180689db8b0d2de7f7d1eabf3fb013f239e156ae0d5a1a85c27f/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0be9965f93c222fb9b4cc254235b3b2b215796c03ef5ee64f995b1b69af0762", size = 388053 }, - { url = "https://files.pythonhosted.org/packages/4a/87/ec4186b1fe6365ced6fa470960e68fc7804bafbe7c0cf5a36237aa240efa/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8378fa4a940f3fb509c081e06cb7f7f2adae8cf46ef258b0e0ed7519facd573e", size = 421821 }, - { url = "https://files.pythonhosted.org/packages/7a/60/84f821f6bf4e0e710acc5039d91f8f594fae0d93fc368704920d8971680d/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:33358883a4490287e67a2c391dfaea4d9359860281db3292b6886bf0be3d8692", size = 564534 }, - { url = "https://files.pythonhosted.org/packages/41/3a/bc654eb15d3b38f9330fe0f545016ba154d89cdabc6177b0295910cd0ebe/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1d1fadd539298e70cac2f2cb36f5b8a65f742b9b9f1014dd4ea1f7785e2470bf", size = 592674 }, - { url = "https://files.pythonhosted.org/packages/2e/ba/31239736f29e4dfc7a58a45955c5db852864c306131fd6320aea214d5437/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9a46c2fb2545e21181445515960006e85d22025bd2fe6db23e76daec6eb689fe", size = 558781 }, +sdist = { url = "https://files.pythonhosted.org/packages/8c/a6/60184b7fc00dd3ca80ac635dd5b8577d444c57e8e8742cecabfacb829921/rpds_py-0.25.1.tar.gz", hash = "sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3", size = 27304, upload-time = "2025-05-21T12:46:12.502Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/09/e1158988e50905b7f8306487a576b52d32aa9a87f79f7ab24ee8db8b6c05/rpds_py-0.25.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f4ad628b5174d5315761b67f212774a32f5bad5e61396d38108bd801c0a8f5d9", size = 373140, upload-time = "2025-05-21T12:42:38.834Z" }, + { url = "https://files.pythonhosted.org/packages/e0/4b/a284321fb3c45c02fc74187171504702b2934bfe16abab89713eedfe672e/rpds_py-0.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c742af695f7525e559c16f1562cf2323db0e3f0fbdcabdf6865b095256b2d40", size = 358860, upload-time = "2025-05-21T12:42:41.394Z" }, + { url = "https://files.pythonhosted.org/packages/4e/46/8ac9811150c75edeae9fc6fa0e70376c19bc80f8e1f7716981433905912b/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:605ffe7769e24b1800b4d024d24034405d9404f0bc2f55b6db3362cd34145a6f", size = 386179, upload-time = "2025-05-21T12:42:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/f3/ec/87eb42d83e859bce91dcf763eb9f2ab117142a49c9c3d17285440edb5b69/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ccc6f3ddef93243538be76f8e47045b4aad7a66a212cd3a0f23e34469473d36b", size = 400282, upload-time = "2025-05-21T12:42:44.92Z" }, + { url = "https://files.pythonhosted.org/packages/68/c8/2a38e0707d7919c8c78e1d582ab15cf1255b380bcb086ca265b73ed6db23/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f70316f760174ca04492b5ab01be631a8ae30cadab1d1081035136ba12738cfa", size = 521824, upload-time = "2025-05-21T12:42:46.856Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2c/6a92790243569784dde84d144bfd12bd45102f4a1c897d76375076d730ab/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1dafef8df605fdb46edcc0bf1573dea0d6d7b01ba87f85cd04dc855b2b4479e", size = 411644, upload-time = "2025-05-21T12:42:48.838Z" }, + { url = "https://files.pythonhosted.org/packages/eb/76/66b523ffc84cf47db56efe13ae7cf368dee2bacdec9d89b9baca5e2e6301/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0701942049095741a8aeb298a31b203e735d1c61f4423511d2b1a41dcd8a16da", size = 386955, upload-time = "2025-05-21T12:42:50.835Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b9/a362d7522feaa24dc2b79847c6175daa1c642817f4a19dcd5c91d3e2c316/rpds_py-0.25.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e87798852ae0b37c88babb7f7bbbb3e3fecc562a1c340195b44c7e24d403e380", size = 421039, upload-time = "2025-05-21T12:42:52.348Z" }, + { url = "https://files.pythonhosted.org/packages/0f/c4/b5b6f70b4d719b6584716889fd3413102acf9729540ee76708d56a76fa97/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3bcce0edc1488906c2d4c75c94c70a0417e83920dd4c88fec1078c94843a6ce9", size = 563290, upload-time = "2025-05-21T12:42:54.404Z" }, + { url = "https://files.pythonhosted.org/packages/87/a3/2e6e816615c12a8f8662c9d8583a12eb54c52557521ef218cbe3095a8afa/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e2f6a2347d3440ae789505693a02836383426249d5293541cd712e07e7aecf54", size = 592089, upload-time = "2025-05-21T12:42:55.976Z" }, + { url = "https://files.pythonhosted.org/packages/c0/08/9b8e1050e36ce266135994e2c7ec06e1841f1c64da739daeb8afe9cb77a4/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4fd52d3455a0aa997734f3835cbc4c9f32571345143960e7d7ebfe7b5fbfa3b2", size = 558400, upload-time = "2025-05-21T12:42:58.032Z" }, + { url = "https://files.pythonhosted.org/packages/f2/df/b40b8215560b8584baccd839ff5c1056f3c57120d79ac41bd26df196da7e/rpds_py-0.25.1-cp310-cp310-win32.whl", hash = "sha256:3f0b1798cae2bbbc9b9db44ee068c556d4737911ad53a4e5093d09d04b3bbc24", size = 219741, upload-time = "2025-05-21T12:42:59.479Z" }, + { url = "https://files.pythonhosted.org/packages/10/99/e4c58be18cf5d8b40b8acb4122bc895486230b08f978831b16a3916bd24d/rpds_py-0.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3ebd879ab996537fc510a2be58c59915b5dd63bccb06d1ef514fee787e05984a", size = 231553, upload-time = "2025-05-21T12:43:01.425Z" }, + { url = "https://files.pythonhosted.org/packages/95/e1/df13fe3ddbbea43567e07437f097863b20c99318ae1f58a0fe389f763738/rpds_py-0.25.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5f048bbf18b1f9120685c6d6bb70cc1a52c8cc11bdd04e643d28d3be0baf666d", size = 373341, upload-time = "2025-05-21T12:43:02.978Z" }, + { url = "https://files.pythonhosted.org/packages/7a/58/deef4d30fcbcbfef3b6d82d17c64490d5c94585a2310544ce8e2d3024f83/rpds_py-0.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fbb0dbba559959fcb5d0735a0f87cdbca9e95dac87982e9b95c0f8f7ad10255", size = 359111, upload-time = "2025-05-21T12:43:05.128Z" }, + { url = "https://files.pythonhosted.org/packages/bb/7e/39f1f4431b03e96ebaf159e29a0f82a77259d8f38b2dd474721eb3a8ac9b/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4ca54b9cf9d80b4016a67a0193ebe0bcf29f6b0a96f09db942087e294d3d4c2", size = 386112, upload-time = "2025-05-21T12:43:07.13Z" }, + { url = "https://files.pythonhosted.org/packages/db/e7/847068a48d63aec2ae695a1646089620b3b03f8ccf9f02c122ebaf778f3c/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ee3e26eb83d39b886d2cb6e06ea701bba82ef30a0de044d34626ede51ec98b0", size = 400362, upload-time = "2025-05-21T12:43:08.693Z" }, + { url = "https://files.pythonhosted.org/packages/3b/3d/9441d5db4343d0cee759a7ab4d67420a476cebb032081763de934719727b/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89706d0683c73a26f76a5315d893c051324d771196ae8b13e6ffa1ffaf5e574f", size = 522214, upload-time = "2025-05-21T12:43:10.694Z" }, + { url = "https://files.pythonhosted.org/packages/a2/ec/2cc5b30d95f9f1a432c79c7a2f65d85e52812a8f6cbf8768724571710786/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2013ee878c76269c7b557a9a9c042335d732e89d482606990b70a839635feb7", size = 411491, upload-time = "2025-05-21T12:43:12.739Z" }, + { url = "https://files.pythonhosted.org/packages/dc/6c/44695c1f035077a017dd472b6a3253553780837af2fac9b6ac25f6a5cb4d/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45e484db65e5380804afbec784522de84fa95e6bb92ef1bd3325d33d13efaebd", size = 386978, upload-time = "2025-05-21T12:43:14.25Z" }, + { url = "https://files.pythonhosted.org/packages/b1/74/b4357090bb1096db5392157b4e7ed8bb2417dc7799200fcbaee633a032c9/rpds_py-0.25.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:48d64155d02127c249695abb87d39f0faf410733428d499867606be138161d65", size = 420662, upload-time = "2025-05-21T12:43:15.8Z" }, + { url = "https://files.pythonhosted.org/packages/26/dd/8cadbebf47b96e59dfe8b35868e5c38a42272699324e95ed522da09d3a40/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:048893e902132fd6548a2e661fb38bf4896a89eea95ac5816cf443524a85556f", size = 563385, upload-time = "2025-05-21T12:43:17.78Z" }, + { url = "https://files.pythonhosted.org/packages/c3/ea/92960bb7f0e7a57a5ab233662f12152085c7dc0d5468534c65991a3d48c9/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0317177b1e8691ab5879f4f33f4b6dc55ad3b344399e23df2e499de7b10a548d", size = 592047, upload-time = "2025-05-21T12:43:19.457Z" }, + { url = "https://files.pythonhosted.org/packages/61/ad/71aabc93df0d05dabcb4b0c749277881f8e74548582d96aa1bf24379493a/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bffcf57826d77a4151962bf1701374e0fc87f536e56ec46f1abdd6a903354042", size = 557863, upload-time = "2025-05-21T12:43:21.69Z" }, + { url = "https://files.pythonhosted.org/packages/93/0f/89df0067c41f122b90b76f3660028a466eb287cbe38efec3ea70e637ca78/rpds_py-0.25.1-cp311-cp311-win32.whl", hash = "sha256:cda776f1967cb304816173b30994faaf2fd5bcb37e73118a47964a02c348e1bc", size = 219627, upload-time = "2025-05-21T12:43:23.311Z" }, + { url = "https://files.pythonhosted.org/packages/7c/8d/93b1a4c1baa903d0229374d9e7aa3466d751f1d65e268c52e6039c6e338e/rpds_py-0.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:dc3c1ff0abc91444cd20ec643d0f805df9a3661fcacf9c95000329f3ddf268a4", size = 231603, upload-time = "2025-05-21T12:43:25.145Z" }, + { url = "https://files.pythonhosted.org/packages/cb/11/392605e5247bead2f23e6888e77229fbd714ac241ebbebb39a1e822c8815/rpds_py-0.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:5a3ddb74b0985c4387719fc536faced33cadf2172769540c62e2a94b7b9be1c4", size = 223967, upload-time = "2025-05-21T12:43:26.566Z" }, + { url = "https://files.pythonhosted.org/packages/7f/81/28ab0408391b1dc57393653b6a0cf2014cc282cc2909e4615e63e58262be/rpds_py-0.25.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5ffe453cde61f73fea9430223c81d29e2fbf412a6073951102146c84e19e34c", size = 364647, upload-time = "2025-05-21T12:43:28.559Z" }, + { url = "https://files.pythonhosted.org/packages/2c/9a/7797f04cad0d5e56310e1238434f71fc6939d0bc517192a18bb99a72a95f/rpds_py-0.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:115874ae5e2fdcfc16b2aedc95b5eef4aebe91b28e7e21951eda8a5dc0d3461b", size = 350454, upload-time = "2025-05-21T12:43:30.615Z" }, + { url = "https://files.pythonhosted.org/packages/69/3c/93d2ef941b04898011e5d6eaa56a1acf46a3b4c9f4b3ad1bbcbafa0bee1f/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a714bf6e5e81b0e570d01f56e0c89c6375101b8463999ead3a93a5d2a4af91fa", size = 389665, upload-time = "2025-05-21T12:43:32.629Z" }, + { url = "https://files.pythonhosted.org/packages/c1/57/ad0e31e928751dde8903a11102559628d24173428a0f85e25e187defb2c1/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35634369325906bcd01577da4c19e3b9541a15e99f31e91a02d010816b49bfda", size = 403873, upload-time = "2025-05-21T12:43:34.576Z" }, + { url = "https://files.pythonhosted.org/packages/16/ad/c0c652fa9bba778b4f54980a02962748479dc09632e1fd34e5282cf2556c/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4cb2b3ddc16710548801c6fcc0cfcdeeff9dafbc983f77265877793f2660309", size = 525866, upload-time = "2025-05-21T12:43:36.123Z" }, + { url = "https://files.pythonhosted.org/packages/2a/39/3e1839bc527e6fcf48d5fec4770070f872cdee6c6fbc9b259932f4e88a38/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ceca1cf097ed77e1a51f1dbc8d174d10cb5931c188a4505ff9f3e119dfe519b", size = 416886, upload-time = "2025-05-21T12:43:38.034Z" }, + { url = "https://files.pythonhosted.org/packages/7a/95/dd6b91cd4560da41df9d7030a038298a67d24f8ca38e150562644c829c48/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2cd1a4b0c2b8c5e31ffff50d09f39906fe351389ba143c195566056c13a7ea", size = 390666, upload-time = "2025-05-21T12:43:40.065Z" }, + { url = "https://files.pythonhosted.org/packages/64/48/1be88a820e7494ce0a15c2d390ccb7c52212370badabf128e6a7bb4cb802/rpds_py-0.25.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1de336a4b164c9188cb23f3703adb74a7623ab32d20090d0e9bf499a2203ad65", size = 425109, upload-time = "2025-05-21T12:43:42.263Z" }, + { url = "https://files.pythonhosted.org/packages/cf/07/3e2a17927ef6d7720b9949ec1b37d1e963b829ad0387f7af18d923d5cfa5/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9fca84a15333e925dd59ce01da0ffe2ffe0d6e5d29a9eeba2148916d1824948c", size = 567244, upload-time = "2025-05-21T12:43:43.846Z" }, + { url = "https://files.pythonhosted.org/packages/d2/e5/76cf010998deccc4f95305d827847e2eae9c568099c06b405cf96384762b/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88ec04afe0c59fa64e2f6ea0dd9657e04fc83e38de90f6de201954b4d4eb59bd", size = 596023, upload-time = "2025-05-21T12:43:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/52/9a/df55efd84403736ba37a5a6377b70aad0fd1cb469a9109ee8a1e21299a1c/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8bd2f19e312ce3e1d2c635618e8a8d8132892bb746a7cf74780a489f0f6cdcb", size = 561634, upload-time = "2025-05-21T12:43:48.263Z" }, + { url = "https://files.pythonhosted.org/packages/ab/aa/dc3620dd8db84454aaf9374bd318f1aa02578bba5e567f5bf6b79492aca4/rpds_py-0.25.1-cp312-cp312-win32.whl", hash = "sha256:e5e2f7280d8d0d3ef06f3ec1b4fd598d386cc6f0721e54f09109a8132182fbfe", size = 222713, upload-time = "2025-05-21T12:43:49.897Z" }, + { url = "https://files.pythonhosted.org/packages/a3/7f/7cef485269a50ed5b4e9bae145f512d2a111ca638ae70cc101f661b4defd/rpds_py-0.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:db58483f71c5db67d643857404da360dce3573031586034b7d59f245144cc192", size = 235280, upload-time = "2025-05-21T12:43:51.893Z" }, + { url = "https://files.pythonhosted.org/packages/99/f2/c2d64f6564f32af913bf5f3f7ae41c7c263c5ae4c4e8f1a17af8af66cd46/rpds_py-0.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:6d50841c425d16faf3206ddbba44c21aa3310a0cebc3c1cdfc3e3f4f9f6f5728", size = 225399, upload-time = "2025-05-21T12:43:53.351Z" }, + { url = "https://files.pythonhosted.org/packages/2b/da/323848a2b62abe6a0fec16ebe199dc6889c5d0a332458da8985b2980dffe/rpds_py-0.25.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:659d87430a8c8c704d52d094f5ba6fa72ef13b4d385b7e542a08fc240cb4a559", size = 364498, upload-time = "2025-05-21T12:43:54.841Z" }, + { url = "https://files.pythonhosted.org/packages/1f/b4/4d3820f731c80fd0cd823b3e95b9963fec681ae45ba35b5281a42382c67d/rpds_py-0.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68f6f060f0bbdfb0245267da014d3a6da9be127fe3e8cc4a68c6f833f8a23bb1", size = 350083, upload-time = "2025-05-21T12:43:56.428Z" }, + { url = "https://files.pythonhosted.org/packages/d5/b1/3a8ee1c9d480e8493619a437dec685d005f706b69253286f50f498cbdbcf/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:083a9513a33e0b92cf6e7a6366036c6bb43ea595332c1ab5c8ae329e4bcc0a9c", size = 389023, upload-time = "2025-05-21T12:43:57.995Z" }, + { url = "https://files.pythonhosted.org/packages/3b/31/17293edcfc934dc62c3bf74a0cb449ecd549531f956b72287203e6880b87/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:816568614ecb22b18a010c7a12559c19f6fe993526af88e95a76d5a60b8b75fb", size = 403283, upload-time = "2025-05-21T12:43:59.546Z" }, + { url = "https://files.pythonhosted.org/packages/d1/ca/e0f0bc1a75a8925024f343258c8ecbd8828f8997ea2ac71e02f67b6f5299/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c6564c0947a7f52e4792983f8e6cf9bac140438ebf81f527a21d944f2fd0a40", size = 524634, upload-time = "2025-05-21T12:44:01.087Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/5d0be919037178fff33a6672ffc0afa04ea1cfcb61afd4119d1b5280ff0f/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c4a128527fe415d73cf1f70a9a688d06130d5810be69f3b553bf7b45e8acf79", size = 416233, upload-time = "2025-05-21T12:44:02.604Z" }, + { url = "https://files.pythonhosted.org/packages/05/7c/8abb70f9017a231c6c961a8941403ed6557664c0913e1bf413cbdc039e75/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a49e1d7a4978ed554f095430b89ecc23f42014a50ac385eb0c4d163ce213c325", size = 390375, upload-time = "2025-05-21T12:44:04.162Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ac/a87f339f0e066b9535074a9f403b9313fd3892d4a164d5d5f5875ac9f29f/rpds_py-0.25.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d74ec9bc0e2feb81d3f16946b005748119c0f52a153f6db6a29e8cd68636f295", size = 424537, upload-time = "2025-05-21T12:44:06.175Z" }, + { url = "https://files.pythonhosted.org/packages/1f/8f/8d5c1567eaf8c8afe98a838dd24de5013ce6e8f53a01bd47fe8bb06b5533/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3af5b4cc10fa41e5bc64e5c198a1b2d2864337f8fcbb9a67e747e34002ce812b", size = 566425, upload-time = "2025-05-21T12:44:08.242Z" }, + { url = "https://files.pythonhosted.org/packages/95/33/03016a6be5663b389c8ab0bbbcca68d9e96af14faeff0a04affcb587e776/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79dc317a5f1c51fd9c6a0c4f48209c6b8526d0524a6904fc1076476e79b00f98", size = 595197, upload-time = "2025-05-21T12:44:10.449Z" }, + { url = "https://files.pythonhosted.org/packages/33/8d/da9f4d3e208c82fda311bff0cf0a19579afceb77cf456e46c559a1c075ba/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1521031351865e0181bc585147624d66b3b00a84109b57fcb7a779c3ec3772cd", size = 561244, upload-time = "2025-05-21T12:44:12.387Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b3/39d5dcf7c5f742ecd6dbc88f6f84ae54184b92f5f387a4053be2107b17f1/rpds_py-0.25.1-cp313-cp313-win32.whl", hash = "sha256:5d473be2b13600b93a5675d78f59e63b51b1ba2d0476893415dfbb5477e65b31", size = 222254, upload-time = "2025-05-21T12:44:14.261Z" }, + { url = "https://files.pythonhosted.org/packages/5f/19/2d6772c8eeb8302c5f834e6d0dfd83935a884e7c5ce16340c7eaf89ce925/rpds_py-0.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7b74e92a3b212390bdce1d93da9f6488c3878c1d434c5e751cbc202c5e09500", size = 234741, upload-time = "2025-05-21T12:44:16.236Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/145ada26cfaf86018d0eb304fe55eafdd4f0b6b84530246bb4a7c4fb5c4b/rpds_py-0.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:dd326a81afe332ede08eb39ab75b301d5676802cdffd3a8f287a5f0b694dc3f5", size = 224830, upload-time = "2025-05-21T12:44:17.749Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ca/d435844829c384fd2c22754ff65889c5c556a675d2ed9eb0e148435c6690/rpds_py-0.25.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:a58d1ed49a94d4183483a3ce0af22f20318d4a1434acee255d683ad90bf78129", size = 359668, upload-time = "2025-05-21T12:44:19.322Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/b056f21db3a09f89410d493d2f6614d87bb162499f98b649d1dbd2a81988/rpds_py-0.25.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f251bf23deb8332823aef1da169d5d89fa84c89f67bdfb566c49dea1fccfd50d", size = 345649, upload-time = "2025-05-21T12:44:20.962Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0f/e0d00dc991e3d40e03ca36383b44995126c36b3eafa0ccbbd19664709c88/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dbd586bfa270c1103ece2109314dd423df1fa3d9719928b5d09e4840cec0d72", size = 384776, upload-time = "2025-05-21T12:44:22.516Z" }, + { url = "https://files.pythonhosted.org/packages/9f/a2/59374837f105f2ca79bde3c3cd1065b2f8c01678900924949f6392eab66d/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d273f136e912aa101a9274c3145dcbddbe4bac560e77e6d5b3c9f6e0ed06d34", size = 395131, upload-time = "2025-05-21T12:44:24.147Z" }, + { url = "https://files.pythonhosted.org/packages/9c/dc/48e8d84887627a0fe0bac53f0b4631e90976fd5d35fff8be66b8e4f3916b/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:666fa7b1bd0a3810a7f18f6d3a25ccd8866291fbbc3c9b912b917a6715874bb9", size = 520942, upload-time = "2025-05-21T12:44:25.915Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f5/ee056966aeae401913d37befeeab57a4a43a4f00099e0a20297f17b8f00c/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:921954d7fbf3fccc7de8f717799304b14b6d9a45bbeec5a8d7408ccbf531faf5", size = 411330, upload-time = "2025-05-21T12:44:27.638Z" }, + { url = "https://files.pythonhosted.org/packages/ab/74/b2cffb46a097cefe5d17f94ede7a174184b9d158a0aeb195f39f2c0361e8/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3d86373ff19ca0441ebeb696ef64cb58b8b5cbacffcda5a0ec2f3911732a194", size = 387339, upload-time = "2025-05-21T12:44:29.292Z" }, + { url = "https://files.pythonhosted.org/packages/7f/9a/0ff0b375dcb5161c2b7054e7d0b7575f1680127505945f5cabaac890bc07/rpds_py-0.25.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c8980cde3bb8575e7c956a530f2c217c1d6aac453474bf3ea0f9c89868b531b6", size = 418077, upload-time = "2025-05-21T12:44:30.877Z" }, + { url = "https://files.pythonhosted.org/packages/0d/a1/fda629bf20d6b698ae84c7c840cfb0e9e4200f664fc96e1f456f00e4ad6e/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8eb8c84ecea987a2523e057c0d950bcb3f789696c0499290b8d7b3107a719d78", size = 562441, upload-time = "2025-05-21T12:44:32.541Z" }, + { url = "https://files.pythonhosted.org/packages/20/15/ce4b5257f654132f326f4acd87268e1006cc071e2c59794c5bdf4bebbb51/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e43a005671a9ed5a650f3bc39e4dbccd6d4326b24fb5ea8be5f3a43a6f576c72", size = 590750, upload-time = "2025-05-21T12:44:34.557Z" }, + { url = "https://files.pythonhosted.org/packages/fb/ab/e04bf58a8d375aeedb5268edcc835c6a660ebf79d4384d8e0889439448b0/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:58f77c60956501a4a627749a6dcb78dac522f249dd96b5c9f1c6af29bfacfb66", size = 558891, upload-time = "2025-05-21T12:44:37.358Z" }, + { url = "https://files.pythonhosted.org/packages/90/82/cb8c6028a6ef6cd2b7991e2e4ced01c854b6236ecf51e81b64b569c43d73/rpds_py-0.25.1-cp313-cp313t-win32.whl", hash = "sha256:2cb9e5b5e26fc02c8a4345048cd9998c2aca7c2712bd1b36da0c72ee969a3523", size = 218718, upload-time = "2025-05-21T12:44:38.969Z" }, + { url = "https://files.pythonhosted.org/packages/b6/97/5a4b59697111c89477d20ba8a44df9ca16b41e737fa569d5ae8bff99e650/rpds_py-0.25.1-cp313-cp313t-win_amd64.whl", hash = "sha256:401ca1c4a20cc0510d3435d89c069fe0a9ae2ee6495135ac46bdd49ec0495763", size = 232218, upload-time = "2025-05-21T12:44:40.512Z" }, + { url = "https://files.pythonhosted.org/packages/78/ff/566ce53529b12b4f10c0a348d316bd766970b7060b4fd50f888be3b3b281/rpds_py-0.25.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b24bf3cd93d5b6ecfbedec73b15f143596c88ee249fa98cefa9a9dc9d92c6f28", size = 373931, upload-time = "2025-05-21T12:45:05.01Z" }, + { url = "https://files.pythonhosted.org/packages/83/5d/deba18503f7c7878e26aa696e97f051175788e19d5336b3b0e76d3ef9256/rpds_py-0.25.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:0eb90e94f43e5085623932b68840b6f379f26db7b5c2e6bcef3179bd83c9330f", size = 359074, upload-time = "2025-05-21T12:45:06.714Z" }, + { url = "https://files.pythonhosted.org/packages/0d/74/313415c5627644eb114df49c56a27edba4d40cfd7c92bd90212b3604ca84/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d50e4864498a9ab639d6d8854b25e80642bd362ff104312d9770b05d66e5fb13", size = 387255, upload-time = "2025-05-21T12:45:08.669Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c8/c723298ed6338963d94e05c0f12793acc9b91d04ed7c4ba7508e534b7385/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c9409b47ba0650544b0bb3c188243b83654dfe55dcc173a86832314e1a6a35d", size = 400714, upload-time = "2025-05-21T12:45:10.39Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/51f1f6aa653c2e110ed482ef2ae94140d56c910378752a1b483af11019ee/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:796ad874c89127c91970652a4ee8b00d56368b7e00d3477f4415fe78164c8000", size = 523105, upload-time = "2025-05-21T12:45:12.273Z" }, + { url = "https://files.pythonhosted.org/packages/c7/a4/7873d15c088ad3bff36910b29ceb0f178e4b3232c2adbe9198de68a41e63/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:85608eb70a659bf4c1142b2781083d4b7c0c4e2c90eff11856a9754e965b2540", size = 411499, upload-time = "2025-05-21T12:45:13.95Z" }, + { url = "https://files.pythonhosted.org/packages/90/f3/0ce1437befe1410766d11d08239333ac1b2d940f8a64234ce48a7714669c/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4feb9211d15d9160bc85fa72fed46432cdc143eb9cf6d5ca377335a921ac37b", size = 387918, upload-time = "2025-05-21T12:45:15.649Z" }, + { url = "https://files.pythonhosted.org/packages/94/d4/5551247988b2a3566afb8a9dba3f1d4a3eea47793fd83000276c1a6c726e/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ccfa689b9246c48947d31dd9d8b16d89a0ecc8e0e26ea5253068efb6c542b76e", size = 421705, upload-time = "2025-05-21T12:45:17.788Z" }, + { url = "https://files.pythonhosted.org/packages/b0/25/5960f28f847bf736cc7ee3c545a7e1d2f3b5edaf82c96fb616c2f5ed52d0/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:3c5b317ecbd8226887994852e85de562f7177add602514d4ac40f87de3ae45a8", size = 564489, upload-time = "2025-05-21T12:45:19.466Z" }, + { url = "https://files.pythonhosted.org/packages/02/66/1c99884a0d44e8c2904d3c4ec302f995292d5dde892c3bf7685ac1930146/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:454601988aab2c6e8fd49e7634c65476b2b919647626208e376afcd22019eeb8", size = 592557, upload-time = "2025-05-21T12:45:21.362Z" }, + { url = "https://files.pythonhosted.org/packages/55/ae/4aeac84ebeffeac14abb05b3bb1d2f728d00adb55d3fb7b51c9fa772e760/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:1c0c434a53714358532d13539272db75a5ed9df75a4a090a753ac7173ec14e11", size = 558691, upload-time = "2025-05-21T12:45:23.084Z" }, + { url = "https://files.pythonhosted.org/packages/41/b3/728a08ff6f5e06fe3bb9af2e770e9d5fd20141af45cff8dfc62da4b2d0b3/rpds_py-0.25.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f73ce1512e04fbe2bc97836e89830d6b4314c171587a99688082d090f934d20a", size = 231651, upload-time = "2025-05-21T12:45:24.72Z" }, + { url = "https://files.pythonhosted.org/packages/49/74/48f3df0715a585cbf5d34919c9c757a4c92c1a9eba059f2d334e72471f70/rpds_py-0.25.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ee86d81551ec68a5c25373c5643d343150cc54672b5e9a0cafc93c1870a53954", size = 374208, upload-time = "2025-05-21T12:45:26.306Z" }, + { url = "https://files.pythonhosted.org/packages/55/b0/9b01bb11ce01ec03d05e627249cc2c06039d6aa24ea5a22a39c312167c10/rpds_py-0.25.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:89c24300cd4a8e4a51e55c31a8ff3918e6651b241ee8876a42cc2b2a078533ba", size = 359262, upload-time = "2025-05-21T12:45:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/a9/eb/5395621618f723ebd5116c53282052943a726dba111b49cd2071f785b665/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:771c16060ff4e79584dc48902a91ba79fd93eade3aa3a12d6d2a4aadaf7d542b", size = 387366, upload-time = "2025-05-21T12:45:30.42Z" }, + { url = "https://files.pythonhosted.org/packages/68/73/3d51442bdb246db619d75039a50ea1cf8b5b4ee250c3e5cd5c3af5981cd4/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:785ffacd0ee61c3e60bdfde93baa6d7c10d86f15655bd706c89da08068dc5038", size = 400759, upload-time = "2025-05-21T12:45:32.516Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4c/3a32d5955d7e6cb117314597bc0f2224efc798428318b13073efe306512a/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a40046a529cc15cef88ac5ab589f83f739e2d332cb4d7399072242400ed68c9", size = 523128, upload-time = "2025-05-21T12:45:34.396Z" }, + { url = "https://files.pythonhosted.org/packages/be/95/1ffccd3b0bb901ae60b1dd4b1be2ab98bb4eb834cd9b15199888f5702f7b/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:85fc223d9c76cabe5d0bff82214459189720dc135db45f9f66aa7cffbf9ff6c1", size = 411597, upload-time = "2025-05-21T12:45:36.164Z" }, + { url = "https://files.pythonhosted.org/packages/ef/6d/6e6cd310180689db8b0d2de7f7d1eabf3fb013f239e156ae0d5a1a85c27f/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0be9965f93c222fb9b4cc254235b3b2b215796c03ef5ee64f995b1b69af0762", size = 388053, upload-time = "2025-05-21T12:45:38.45Z" }, + { url = "https://files.pythonhosted.org/packages/4a/87/ec4186b1fe6365ced6fa470960e68fc7804bafbe7c0cf5a36237aa240efa/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8378fa4a940f3fb509c081e06cb7f7f2adae8cf46ef258b0e0ed7519facd573e", size = 421821, upload-time = "2025-05-21T12:45:40.732Z" }, + { url = "https://files.pythonhosted.org/packages/7a/60/84f821f6bf4e0e710acc5039d91f8f594fae0d93fc368704920d8971680d/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:33358883a4490287e67a2c391dfaea4d9359860281db3292b6886bf0be3d8692", size = 564534, upload-time = "2025-05-21T12:45:42.672Z" }, + { url = "https://files.pythonhosted.org/packages/41/3a/bc654eb15d3b38f9330fe0f545016ba154d89cdabc6177b0295910cd0ebe/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1d1fadd539298e70cac2f2cb36f5b8a65f742b9b9f1014dd4ea1f7785e2470bf", size = 592674, upload-time = "2025-05-21T12:45:44.533Z" }, + { url = "https://files.pythonhosted.org/packages/2e/ba/31239736f29e4dfc7a58a45955c5db852864c306131fd6320aea214d5437/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9a46c2fb2545e21181445515960006e85d22025bd2fe6db23e76daec6eb689fe", size = 558781, upload-time = "2025-05-21T12:45:46.281Z" }, ] [[package]] @@ -3846,9 +3941,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034 } +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/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696 }, + { 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]] @@ -3858,78 +3953,78 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ruamel-yaml-clib", marker = "python_full_version < '3.14' and platform_python_implementation == 'CPython'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/39/87/6da0df742a4684263261c253f00edd5829e6aca970fff69e75028cccc547/ruamel.yaml-0.18.14.tar.gz", hash = "sha256:7227b76aaec364df15936730efbf7d72b30c0b79b1d578bbb8e3dcb2d81f52b7", size = 145511 } +sdist = { url = "https://files.pythonhosted.org/packages/39/87/6da0df742a4684263261c253f00edd5829e6aca970fff69e75028cccc547/ruamel.yaml-0.18.14.tar.gz", hash = "sha256:7227b76aaec364df15936730efbf7d72b30c0b79b1d578bbb8e3dcb2d81f52b7", size = 145511, upload-time = "2025-06-09T08:51:09.828Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/6d/6fe4805235e193aad4aaf979160dd1f3c487c57d48b810c816e6e842171b/ruamel.yaml-0.18.14-py3-none-any.whl", hash = "sha256:710ff198bb53da66718c7db27eec4fbcc9aa6ca7204e4c1df2f282b6fe5eb6b2", size = 118570 }, + { url = "https://files.pythonhosted.org/packages/af/6d/6fe4805235e193aad4aaf979160dd1f3c487c57d48b810c816e6e842171b/ruamel.yaml-0.18.14-py3-none-any.whl", hash = "sha256:710ff198bb53da66718c7db27eec4fbcc9aa6ca7204e4c1df2f282b6fe5eb6b2", size = 118570, upload-time = "2025-06-09T08:51:06.348Z" }, ] [[package]] name = "ruamel-yaml-clib" version = "0.2.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f", size = 225315 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/57/40a958e863e299f0c74ef32a3bde9f2d1ea8d69669368c0c502a0997f57f/ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5", size = 131301 }, - { url = "https://files.pythonhosted.org/packages/98/a8/29a3eb437b12b95f50a6bcc3d7d7214301c6c529d8fdc227247fa84162b5/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969", size = 633728 }, - { url = "https://files.pythonhosted.org/packages/35/6d/ae05a87a3ad540259c3ad88d71275cbd1c0f2d30ae04c65dcbfb6dcd4b9f/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df", size = 722230 }, - { url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76", size = 686712 }, - { url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6", size = 663936 }, - { url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd", size = 696580 }, - { url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a", size = 663393 }, - { url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da", size = 100326 }, - { url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28", size = 118079 }, - { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224 }, - { url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e", size = 641480 }, - { url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e", size = 739068 }, - { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012 }, - { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352 }, - { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344 }, - { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498 }, - { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205 }, - { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185 }, - { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433 }, - { url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d", size = 647362 }, - { url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c", size = 754118 }, - { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497 }, - { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042 }, - { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831 }, - { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692 }, - { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777 }, - { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, - { url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a", size = 132011 }, - { url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475", size = 642488 }, - { url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef", size = 745066 }, - { url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6", size = 701785 }, - { url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf", size = 693017 }, - { url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1", size = 741270 }, - { url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01", size = 709059 }, - { url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6", size = 98583 }, - { url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3", size = 115190 }, +sdist = { url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f", size = 225315, upload-time = "2024-10-20T10:10:56.22Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/57/40a958e863e299f0c74ef32a3bde9f2d1ea8d69669368c0c502a0997f57f/ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5", size = 131301, upload-time = "2024-10-20T10:12:35.876Z" }, + { url = "https://files.pythonhosted.org/packages/98/a8/29a3eb437b12b95f50a6bcc3d7d7214301c6c529d8fdc227247fa84162b5/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969", size = 633728, upload-time = "2024-10-20T10:12:37.858Z" }, + { url = "https://files.pythonhosted.org/packages/35/6d/ae05a87a3ad540259c3ad88d71275cbd1c0f2d30ae04c65dcbfb6dcd4b9f/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df", size = 722230, upload-time = "2024-10-20T10:12:39.457Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76", size = 686712, upload-time = "2024-10-20T10:12:41.119Z" }, + { url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6", size = 663936, upload-time = "2024-10-21T11:26:37.419Z" }, + { url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd", size = 696580, upload-time = "2024-10-21T11:26:39.503Z" }, + { url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a", size = 663393, upload-time = "2024-12-11T19:58:13.873Z" }, + { url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da", size = 100326, upload-time = "2024-10-20T10:12:42.967Z" }, + { url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28", size = 118079, upload-time = "2024-10-20T10:12:44.117Z" }, + { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224, upload-time = "2024-10-20T10:12:45.162Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e", size = 641480, upload-time = "2024-10-20T10:12:46.758Z" }, + { url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e", size = 739068, upload-time = "2024-10-20T10:12:48.605Z" }, + { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012, upload-time = "2024-10-20T10:12:51.124Z" }, + { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352, upload-time = "2024-10-21T11:26:41.438Z" }, + { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344, upload-time = "2024-10-21T11:26:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498, upload-time = "2024-12-11T19:58:15.592Z" }, + { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205, upload-time = "2024-10-20T10:12:52.865Z" }, + { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185, upload-time = "2024-10-20T10:12:54.652Z" }, + { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433, upload-time = "2024-10-20T10:12:55.657Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d", size = 647362, upload-time = "2024-10-20T10:12:57.155Z" }, + { url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c", size = 754118, upload-time = "2024-10-20T10:12:58.501Z" }, + { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497, upload-time = "2024-10-20T10:13:00.211Z" }, + { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042, upload-time = "2024-10-21T11:26:46.038Z" }, + { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831, upload-time = "2024-10-21T11:26:47.487Z" }, + { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692, upload-time = "2024-12-11T19:58:17.252Z" }, + { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777, upload-time = "2024-10-20T10:13:01.395Z" }, + { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523, upload-time = "2024-10-20T10:13:02.768Z" }, + { url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a", size = 132011, upload-time = "2024-10-20T10:13:04.377Z" }, + { url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475", size = 642488, upload-time = "2024-10-20T10:13:05.906Z" }, + { url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef", size = 745066, upload-time = "2024-10-20T10:13:07.26Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6", size = 701785, upload-time = "2024-10-20T10:13:08.504Z" }, + { url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf", size = 693017, upload-time = "2024-10-21T11:26:48.866Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1", size = 741270, upload-time = "2024-10-21T11:26:50.213Z" }, + { url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01", size = 709059, upload-time = "2024-12-11T19:58:18.846Z" }, + { url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6", size = 98583, upload-time = "2024-10-20T10:13:09.658Z" }, + { url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3", size = 115190, upload-time = "2024-10-20T10:13:10.66Z" }, ] [[package]] name = "ruff" version = "0.11.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/53/ae4857030d59286924a8bdb30d213d6ff22d8f0957e738d0289990091dd8/ruff-0.11.11.tar.gz", hash = "sha256:7774173cc7c1980e6bf67569ebb7085989a78a103922fb83ef3dfe230cd0687d", size = 4186707 } +sdist = { url = "https://files.pythonhosted.org/packages/b2/53/ae4857030d59286924a8bdb30d213d6ff22d8f0957e738d0289990091dd8/ruff-0.11.11.tar.gz", hash = "sha256:7774173cc7c1980e6bf67569ebb7085989a78a103922fb83ef3dfe230cd0687d", size = 4186707, upload-time = "2025-05-22T19:19:34.363Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/14/f2326676197bab099e2a24473158c21656fbf6a207c65f596ae15acb32b9/ruff-0.11.11-py3-none-linux_armv6l.whl", hash = "sha256:9924e5ae54125ed8958a4f7de320dab7380f6e9fa3195e3dc3b137c6842a0092", size = 10229049 }, - { url = "https://files.pythonhosted.org/packages/9a/f3/bff7c92dd66c959e711688b2e0768e486bbca46b2f35ac319bb6cce04447/ruff-0.11.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c8a93276393d91e952f790148eb226658dd275cddfde96c6ca304873f11d2ae4", size = 11053601 }, - { url = "https://files.pythonhosted.org/packages/e2/38/8e1a3efd0ef9d8259346f986b77de0f62c7a5ff4a76563b6b39b68f793b9/ruff-0.11.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6e333dbe2e6ae84cdedefa943dfd6434753ad321764fd937eef9d6b62022bcd", size = 10367421 }, - { url = "https://files.pythonhosted.org/packages/b4/50/557ad9dd4fb9d0bf524ec83a090a3932d284d1a8b48b5906b13b72800e5f/ruff-0.11.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7885d9a5e4c77b24e8c88aba8c80be9255fa22ab326019dac2356cff42089fc6", size = 10581980 }, - { url = "https://files.pythonhosted.org/packages/c4/b2/e2ed82d6e2739ece94f1bdbbd1d81b712d3cdaf69f0a1d1f1a116b33f9ad/ruff-0.11.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1b5ab797fcc09121ed82e9b12b6f27e34859e4227080a42d090881be888755d4", size = 10089241 }, - { url = "https://files.pythonhosted.org/packages/3d/9f/b4539f037a5302c450d7c695c82f80e98e48d0d667ecc250e6bdeb49b5c3/ruff-0.11.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e231ff3132c1119ece836487a02785f099a43992b95c2f62847d29bace3c75ac", size = 11699398 }, - { url = "https://files.pythonhosted.org/packages/61/fb/32e029d2c0b17df65e6eaa5ce7aea5fbeaed22dddd9fcfbbf5fe37c6e44e/ruff-0.11.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a97c9babe1d4081037a90289986925726b802d180cca784ac8da2bbbc335f709", size = 12427955 }, - { url = "https://files.pythonhosted.org/packages/6e/e3/160488dbb11f18c8121cfd588e38095ba779ae208292765972f7732bfd95/ruff-0.11.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8c4ddcbe8a19f59f57fd814b8b117d4fcea9bee7c0492e6cf5fdc22cfa563c8", size = 12069803 }, - { url = "https://files.pythonhosted.org/packages/ff/16/3b006a875f84b3d0bff24bef26b8b3591454903f6f754b3f0a318589dcc3/ruff-0.11.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6224076c344a7694c6fbbb70d4f2a7b730f6d47d2a9dc1e7f9d9bb583faf390b", size = 11242630 }, - { url = "https://files.pythonhosted.org/packages/65/0d/0338bb8ac0b97175c2d533e9c8cdc127166de7eb16d028a43c5ab9e75abd/ruff-0.11.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:882821fcdf7ae8db7a951df1903d9cb032bbe838852e5fc3c2b6c3ab54e39875", size = 11507310 }, - { url = "https://files.pythonhosted.org/packages/6f/bf/d7130eb26174ce9b02348b9f86d5874eafbf9f68e5152e15e8e0a392e4a3/ruff-0.11.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:dcec2d50756463d9df075a26a85a6affbc1b0148873da3997286caf1ce03cae1", size = 10441144 }, - { url = "https://files.pythonhosted.org/packages/b3/f3/4be2453b258c092ff7b1761987cf0749e70ca1340cd1bfb4def08a70e8d8/ruff-0.11.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99c28505ecbaeb6594701a74e395b187ee083ee26478c1a795d35084d53ebd81", size = 10081987 }, - { url = "https://files.pythonhosted.org/packages/6c/6e/dfa4d2030c5b5c13db158219f2ec67bf333e8a7748dccf34cfa2a6ab9ebc/ruff-0.11.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9263f9e5aa4ff1dec765e99810f1cc53f0c868c5329b69f13845f699fe74f639", size = 11073922 }, - { url = "https://files.pythonhosted.org/packages/ff/f4/f7b0b0c3d32b593a20ed8010fa2c1a01f2ce91e79dda6119fcc51d26c67b/ruff-0.11.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:64ac6f885e3ecb2fdbb71de2701d4e34526651f1e8503af8fb30d4915a3fe345", size = 11568537 }, - { url = "https://files.pythonhosted.org/packages/d2/46/0e892064d0adc18bcc81deed9aaa9942a27fd2cd9b1b7791111ce468c25f/ruff-0.11.11-py3-none-win32.whl", hash = "sha256:1adcb9a18802268aaa891ffb67b1c94cd70578f126637118e8099b8e4adcf112", size = 10536492 }, - { url = "https://files.pythonhosted.org/packages/1b/d9/232e79459850b9f327e9f1dc9c047a2a38a6f9689e1ec30024841fc4416c/ruff-0.11.11-py3-none-win_amd64.whl", hash = "sha256:748b4bb245f11e91a04a4ff0f96e386711df0a30412b9fe0c74d5bdc0e4a531f", size = 11612562 }, - { url = "https://files.pythonhosted.org/packages/ce/eb/09c132cff3cc30b2e7244191dcce69437352d6d6709c0adf374f3e6f476e/ruff-0.11.11-py3-none-win_arm64.whl", hash = "sha256:6c51f136c0364ab1b774767aa8b86331bd8e9d414e2d107db7a2189f35ea1f7b", size = 10735951 }, + { url = "https://files.pythonhosted.org/packages/b1/14/f2326676197bab099e2a24473158c21656fbf6a207c65f596ae15acb32b9/ruff-0.11.11-py3-none-linux_armv6l.whl", hash = "sha256:9924e5ae54125ed8958a4f7de320dab7380f6e9fa3195e3dc3b137c6842a0092", size = 10229049, upload-time = "2025-05-22T19:18:45.516Z" }, + { url = "https://files.pythonhosted.org/packages/9a/f3/bff7c92dd66c959e711688b2e0768e486bbca46b2f35ac319bb6cce04447/ruff-0.11.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c8a93276393d91e952f790148eb226658dd275cddfde96c6ca304873f11d2ae4", size = 11053601, upload-time = "2025-05-22T19:18:49.269Z" }, + { url = "https://files.pythonhosted.org/packages/e2/38/8e1a3efd0ef9d8259346f986b77de0f62c7a5ff4a76563b6b39b68f793b9/ruff-0.11.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6e333dbe2e6ae84cdedefa943dfd6434753ad321764fd937eef9d6b62022bcd", size = 10367421, upload-time = "2025-05-22T19:18:51.754Z" }, + { url = "https://files.pythonhosted.org/packages/b4/50/557ad9dd4fb9d0bf524ec83a090a3932d284d1a8b48b5906b13b72800e5f/ruff-0.11.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7885d9a5e4c77b24e8c88aba8c80be9255fa22ab326019dac2356cff42089fc6", size = 10581980, upload-time = "2025-05-22T19:18:54.011Z" }, + { url = "https://files.pythonhosted.org/packages/c4/b2/e2ed82d6e2739ece94f1bdbbd1d81b712d3cdaf69f0a1d1f1a116b33f9ad/ruff-0.11.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1b5ab797fcc09121ed82e9b12b6f27e34859e4227080a42d090881be888755d4", size = 10089241, upload-time = "2025-05-22T19:18:56.041Z" }, + { url = "https://files.pythonhosted.org/packages/3d/9f/b4539f037a5302c450d7c695c82f80e98e48d0d667ecc250e6bdeb49b5c3/ruff-0.11.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e231ff3132c1119ece836487a02785f099a43992b95c2f62847d29bace3c75ac", size = 11699398, upload-time = "2025-05-22T19:18:58.248Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/32e029d2c0b17df65e6eaa5ce7aea5fbeaed22dddd9fcfbbf5fe37c6e44e/ruff-0.11.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a97c9babe1d4081037a90289986925726b802d180cca784ac8da2bbbc335f709", size = 12427955, upload-time = "2025-05-22T19:19:00.981Z" }, + { url = "https://files.pythonhosted.org/packages/6e/e3/160488dbb11f18c8121cfd588e38095ba779ae208292765972f7732bfd95/ruff-0.11.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8c4ddcbe8a19f59f57fd814b8b117d4fcea9bee7c0492e6cf5fdc22cfa563c8", size = 12069803, upload-time = "2025-05-22T19:19:03.258Z" }, + { url = "https://files.pythonhosted.org/packages/ff/16/3b006a875f84b3d0bff24bef26b8b3591454903f6f754b3f0a318589dcc3/ruff-0.11.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6224076c344a7694c6fbbb70d4f2a7b730f6d47d2a9dc1e7f9d9bb583faf390b", size = 11242630, upload-time = "2025-05-22T19:19:05.871Z" }, + { url = "https://files.pythonhosted.org/packages/65/0d/0338bb8ac0b97175c2d533e9c8cdc127166de7eb16d028a43c5ab9e75abd/ruff-0.11.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:882821fcdf7ae8db7a951df1903d9cb032bbe838852e5fc3c2b6c3ab54e39875", size = 11507310, upload-time = "2025-05-22T19:19:08.584Z" }, + { url = "https://files.pythonhosted.org/packages/6f/bf/d7130eb26174ce9b02348b9f86d5874eafbf9f68e5152e15e8e0a392e4a3/ruff-0.11.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:dcec2d50756463d9df075a26a85a6affbc1b0148873da3997286caf1ce03cae1", size = 10441144, upload-time = "2025-05-22T19:19:13.621Z" }, + { url = "https://files.pythonhosted.org/packages/b3/f3/4be2453b258c092ff7b1761987cf0749e70ca1340cd1bfb4def08a70e8d8/ruff-0.11.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99c28505ecbaeb6594701a74e395b187ee083ee26478c1a795d35084d53ebd81", size = 10081987, upload-time = "2025-05-22T19:19:15.821Z" }, + { url = "https://files.pythonhosted.org/packages/6c/6e/dfa4d2030c5b5c13db158219f2ec67bf333e8a7748dccf34cfa2a6ab9ebc/ruff-0.11.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9263f9e5aa4ff1dec765e99810f1cc53f0c868c5329b69f13845f699fe74f639", size = 11073922, upload-time = "2025-05-22T19:19:18.104Z" }, + { url = "https://files.pythonhosted.org/packages/ff/f4/f7b0b0c3d32b593a20ed8010fa2c1a01f2ce91e79dda6119fcc51d26c67b/ruff-0.11.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:64ac6f885e3ecb2fdbb71de2701d4e34526651f1e8503af8fb30d4915a3fe345", size = 11568537, upload-time = "2025-05-22T19:19:20.889Z" }, + { url = "https://files.pythonhosted.org/packages/d2/46/0e892064d0adc18bcc81deed9aaa9942a27fd2cd9b1b7791111ce468c25f/ruff-0.11.11-py3-none-win32.whl", hash = "sha256:1adcb9a18802268aaa891ffb67b1c94cd70578f126637118e8099b8e4adcf112", size = 10536492, upload-time = "2025-05-22T19:19:23.642Z" }, + { url = "https://files.pythonhosted.org/packages/1b/d9/232e79459850b9f327e9f1dc9c047a2a38a6f9689e1ec30024841fc4416c/ruff-0.11.11-py3-none-win_amd64.whl", hash = "sha256:748b4bb245f11e91a04a4ff0f96e386711df0a30412b9fe0c74d5bdc0e4a531f", size = 11612562, upload-time = "2025-05-22T19:19:27.013Z" }, + { url = "https://files.pythonhosted.org/packages/ce/eb/09c132cff3cc30b2e7244191dcce69437352d6d6709c0adf374f3e6f476e/ruff-0.11.11-py3-none-win_arm64.whl", hash = "sha256:6c51f136c0364ab1b774767aa8b86331bd8e9d414e2d107db7a2189f35ea1f7b", size = 10735951, upload-time = "2025-05-22T19:19:30.043Z" }, ] [[package]] @@ -3939,9 +4034,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ed/5d/9dcc100abc6711e8247af5aa561fc07c4a046f72f659c3adea9a449e191a/s3transfer-0.13.0.tar.gz", hash = "sha256:f5e6db74eb7776a37208001113ea7aa97695368242b364d73e91c981ac522177", size = 150232 } +sdist = { url = "https://files.pythonhosted.org/packages/ed/5d/9dcc100abc6711e8247af5aa561fc07c4a046f72f659c3adea9a449e191a/s3transfer-0.13.0.tar.gz", hash = "sha256:f5e6db74eb7776a37208001113ea7aa97695368242b364d73e91c981ac522177", size = 150232, upload-time = "2025-05-22T19:24:50.245Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/17/22bf8155aa0ea2305eefa3a6402e040df7ebe512d1310165eda1e233c3f8/s3transfer-0.13.0-py3-none-any.whl", hash = "sha256:0148ef34d6dd964d0d8cf4311b2b21c474693e57c2e069ec708ce043d2b527be", size = 85152 }, + { url = "https://files.pythonhosted.org/packages/18/17/22bf8155aa0ea2305eefa3a6402e040df7ebe512d1310165eda1e233c3f8/s3transfer-0.13.0-py3-none-any.whl", hash = "sha256:0148ef34d6dd964d0d8cf4311b2b21c474693e57c2e069ec708ce043d2b527be", size = 85152, upload-time = "2025-05-22T19:24:48.703Z" }, ] [[package]] @@ -3954,32 +4049,32 @@ dependencies = [ { name = "scipy" }, { name = "threadpoolctl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9e/a5/4ae3b3a0755f7b35a280ac90b28817d1f380318973cff14075ab41ef50d9/scikit_learn-1.6.1.tar.gz", hash = "sha256:b4fc2525eca2c69a59260f583c56a7557c6ccdf8deafdba6e060f94c1c59738e", size = 7068312 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2e/3a/f4597eb41049110b21ebcbb0bcb43e4035017545daa5eedcfeb45c08b9c5/scikit_learn-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d056391530ccd1e501056160e3c9673b4da4805eb67eb2bdf4e983e1f9c9204e", size = 12067702 }, - { url = "https://files.pythonhosted.org/packages/37/19/0423e5e1fd1c6ec5be2352ba05a537a473c1677f8188b9306097d684b327/scikit_learn-1.6.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:0c8d036eb937dbb568c6242fa598d551d88fb4399c0344d95c001980ec1c7d36", size = 11112765 }, - { url = "https://files.pythonhosted.org/packages/70/95/d5cb2297a835b0f5fc9a77042b0a2d029866379091ab8b3f52cc62277808/scikit_learn-1.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8634c4bd21a2a813e0a7e3900464e6d593162a29dd35d25bdf0103b3fce60ed5", size = 12643991 }, - { url = "https://files.pythonhosted.org/packages/b7/91/ab3c697188f224d658969f678be86b0968ccc52774c8ab4a86a07be13c25/scikit_learn-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:775da975a471c4f6f467725dff0ced5c7ac7bda5e9316b260225b48475279a1b", size = 13497182 }, - { url = "https://files.pythonhosted.org/packages/17/04/d5d556b6c88886c092cc989433b2bab62488e0f0dafe616a1d5c9cb0efb1/scikit_learn-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:8a600c31592bd7dab31e1c61b9bbd6dea1b3433e67d264d17ce1017dbdce8002", size = 11125517 }, - { url = "https://files.pythonhosted.org/packages/6c/2a/e291c29670795406a824567d1dfc91db7b699799a002fdaa452bceea8f6e/scikit_learn-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72abc587c75234935e97d09aa4913a82f7b03ee0b74111dcc2881cba3c5a7b33", size = 12102620 }, - { url = "https://files.pythonhosted.org/packages/25/92/ee1d7a00bb6b8c55755d4984fd82608603a3cc59959245068ce32e7fb808/scikit_learn-1.6.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b3b00cdc8f1317b5f33191df1386c0befd16625f49d979fe77a8d44cae82410d", size = 11116234 }, - { url = "https://files.pythonhosted.org/packages/30/cd/ed4399485ef364bb25f388ab438e3724e60dc218c547a407b6e90ccccaef/scikit_learn-1.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc4765af3386811c3ca21638f63b9cf5ecf66261cc4815c1db3f1e7dc7b79db2", size = 12592155 }, - { url = "https://files.pythonhosted.org/packages/a8/f3/62fc9a5a659bb58a03cdd7e258956a5824bdc9b4bb3c5d932f55880be569/scikit_learn-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25fc636bdaf1cc2f4a124a116312d837148b5e10872147bdaf4887926b8c03d8", size = 13497069 }, - { url = "https://files.pythonhosted.org/packages/a1/a6/c5b78606743a1f28eae8f11973de6613a5ee87366796583fb74c67d54939/scikit_learn-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:fa909b1a36e000a03c382aade0bd2063fd5680ff8b8e501660c0f59f021a6415", size = 11139809 }, - { url = "https://files.pythonhosted.org/packages/0a/18/c797c9b8c10380d05616db3bfb48e2a3358c767affd0857d56c2eb501caa/scikit_learn-1.6.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:926f207c804104677af4857b2c609940b743d04c4c35ce0ddc8ff4f053cddc1b", size = 12104516 }, - { url = "https://files.pythonhosted.org/packages/c4/b7/2e35f8e289ab70108f8cbb2e7a2208f0575dc704749721286519dcf35f6f/scikit_learn-1.6.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2c2cae262064e6a9b77eee1c8e768fc46aa0b8338c6a8297b9b6759720ec0ff2", size = 11167837 }, - { url = "https://files.pythonhosted.org/packages/a4/f6/ff7beaeb644bcad72bcfd5a03ff36d32ee4e53a8b29a639f11bcb65d06cd/scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1061b7c028a8663fb9a1a1baf9317b64a257fcb036dae5c8752b2abef31d136f", size = 12253728 }, - { url = "https://files.pythonhosted.org/packages/29/7a/8bce8968883e9465de20be15542f4c7e221952441727c4dad24d534c6d99/scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e69fab4ebfc9c9b580a7a80111b43d214ab06250f8a7ef590a4edf72464dd86", size = 13147700 }, - { url = "https://files.pythonhosted.org/packages/62/27/585859e72e117fe861c2079bcba35591a84f801e21bc1ab85bce6ce60305/scikit_learn-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:70b1d7e85b1c96383f872a519b3375f92f14731e279a7b4c6cfd650cf5dffc52", size = 11110613 }, - { url = "https://files.pythonhosted.org/packages/2e/59/8eb1872ca87009bdcdb7f3cdc679ad557b992c12f4b61f9250659e592c63/scikit_learn-1.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ffa1e9e25b3d93990e74a4be2c2fc61ee5af85811562f1288d5d055880c4322", size = 12010001 }, - { url = "https://files.pythonhosted.org/packages/9d/05/f2fc4effc5b32e525408524c982c468c29d22f828834f0625c5ef3d601be/scikit_learn-1.6.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dc5cf3d68c5a20ad6d571584c0750ec641cc46aeef1c1507be51300e6003a7e1", size = 11096360 }, - { url = "https://files.pythonhosted.org/packages/c8/e4/4195d52cf4f113573fb8ebc44ed5a81bd511a92c0228889125fac2f4c3d1/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c06beb2e839ecc641366000ca84f3cf6fa9faa1777e29cf0c04be6e4d096a348", size = 12209004 }, - { url = "https://files.pythonhosted.org/packages/94/be/47e16cdd1e7fcf97d95b3cb08bde1abb13e627861af427a3651fcb80b517/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8ca8cb270fee8f1f76fa9bfd5c3507d60c6438bbee5687f81042e2bb98e5a97", size = 13171776 }, - { url = "https://files.pythonhosted.org/packages/34/b0/ca92b90859070a1487827dbc672f998da95ce83edce1270fc23f96f1f61a/scikit_learn-1.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:7a1c43c8ec9fde528d664d947dc4c0789be4077a3647f232869f41d9bf50e0fb", size = 11071865 }, - { url = "https://files.pythonhosted.org/packages/12/ae/993b0fb24a356e71e9a894e42b8a9eec528d4c70217353a1cd7a48bc25d4/scikit_learn-1.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a17c1dea1d56dcda2fac315712f3651a1fea86565b64b48fa1bc090249cbf236", size = 11955804 }, - { url = "https://files.pythonhosted.org/packages/d6/54/32fa2ee591af44507eac86406fa6bba968d1eb22831494470d0a2e4a1eb1/scikit_learn-1.6.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6a7aa5f9908f0f28f4edaa6963c0a6183f1911e63a69aa03782f0d924c830a35", size = 11100530 }, - { url = "https://files.pythonhosted.org/packages/3f/58/55856da1adec655bdce77b502e94a267bf40a8c0b89f8622837f89503b5a/scikit_learn-1.6.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0650e730afb87402baa88afbf31c07b84c98272622aaba002559b614600ca691", size = 12433852 }, - { url = "https://files.pythonhosted.org/packages/ff/4f/c83853af13901a574f8f13b645467285a48940f185b690936bb700a50863/scikit_learn-1.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:3f59fe08dc03ea158605170eb52b22a105f238a5d512c4470ddeca71feae8e5f", size = 11337256 }, +sdist = { url = "https://files.pythonhosted.org/packages/9e/a5/4ae3b3a0755f7b35a280ac90b28817d1f380318973cff14075ab41ef50d9/scikit_learn-1.6.1.tar.gz", hash = "sha256:b4fc2525eca2c69a59260f583c56a7557c6ccdf8deafdba6e060f94c1c59738e", size = 7068312, upload-time = "2025-01-10T08:07:55.348Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/3a/f4597eb41049110b21ebcbb0bcb43e4035017545daa5eedcfeb45c08b9c5/scikit_learn-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d056391530ccd1e501056160e3c9673b4da4805eb67eb2bdf4e983e1f9c9204e", size = 12067702, upload-time = "2025-01-10T08:05:56.515Z" }, + { url = "https://files.pythonhosted.org/packages/37/19/0423e5e1fd1c6ec5be2352ba05a537a473c1677f8188b9306097d684b327/scikit_learn-1.6.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:0c8d036eb937dbb568c6242fa598d551d88fb4399c0344d95c001980ec1c7d36", size = 11112765, upload-time = "2025-01-10T08:06:00.272Z" }, + { url = "https://files.pythonhosted.org/packages/70/95/d5cb2297a835b0f5fc9a77042b0a2d029866379091ab8b3f52cc62277808/scikit_learn-1.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8634c4bd21a2a813e0a7e3900464e6d593162a29dd35d25bdf0103b3fce60ed5", size = 12643991, upload-time = "2025-01-10T08:06:04.813Z" }, + { url = "https://files.pythonhosted.org/packages/b7/91/ab3c697188f224d658969f678be86b0968ccc52774c8ab4a86a07be13c25/scikit_learn-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:775da975a471c4f6f467725dff0ced5c7ac7bda5e9316b260225b48475279a1b", size = 13497182, upload-time = "2025-01-10T08:06:08.42Z" }, + { url = "https://files.pythonhosted.org/packages/17/04/d5d556b6c88886c092cc989433b2bab62488e0f0dafe616a1d5c9cb0efb1/scikit_learn-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:8a600c31592bd7dab31e1c61b9bbd6dea1b3433e67d264d17ce1017dbdce8002", size = 11125517, upload-time = "2025-01-10T08:06:12.783Z" }, + { url = "https://files.pythonhosted.org/packages/6c/2a/e291c29670795406a824567d1dfc91db7b699799a002fdaa452bceea8f6e/scikit_learn-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72abc587c75234935e97d09aa4913a82f7b03ee0b74111dcc2881cba3c5a7b33", size = 12102620, upload-time = "2025-01-10T08:06:16.675Z" }, + { url = "https://files.pythonhosted.org/packages/25/92/ee1d7a00bb6b8c55755d4984fd82608603a3cc59959245068ce32e7fb808/scikit_learn-1.6.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b3b00cdc8f1317b5f33191df1386c0befd16625f49d979fe77a8d44cae82410d", size = 11116234, upload-time = "2025-01-10T08:06:21.83Z" }, + { url = "https://files.pythonhosted.org/packages/30/cd/ed4399485ef364bb25f388ab438e3724e60dc218c547a407b6e90ccccaef/scikit_learn-1.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc4765af3386811c3ca21638f63b9cf5ecf66261cc4815c1db3f1e7dc7b79db2", size = 12592155, upload-time = "2025-01-10T08:06:27.309Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f3/62fc9a5a659bb58a03cdd7e258956a5824bdc9b4bb3c5d932f55880be569/scikit_learn-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25fc636bdaf1cc2f4a124a116312d837148b5e10872147bdaf4887926b8c03d8", size = 13497069, upload-time = "2025-01-10T08:06:32.515Z" }, + { url = "https://files.pythonhosted.org/packages/a1/a6/c5b78606743a1f28eae8f11973de6613a5ee87366796583fb74c67d54939/scikit_learn-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:fa909b1a36e000a03c382aade0bd2063fd5680ff8b8e501660c0f59f021a6415", size = 11139809, upload-time = "2025-01-10T08:06:35.514Z" }, + { url = "https://files.pythonhosted.org/packages/0a/18/c797c9b8c10380d05616db3bfb48e2a3358c767affd0857d56c2eb501caa/scikit_learn-1.6.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:926f207c804104677af4857b2c609940b743d04c4c35ce0ddc8ff4f053cddc1b", size = 12104516, upload-time = "2025-01-10T08:06:40.009Z" }, + { url = "https://files.pythonhosted.org/packages/c4/b7/2e35f8e289ab70108f8cbb2e7a2208f0575dc704749721286519dcf35f6f/scikit_learn-1.6.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2c2cae262064e6a9b77eee1c8e768fc46aa0b8338c6a8297b9b6759720ec0ff2", size = 11167837, upload-time = "2025-01-10T08:06:43.305Z" }, + { url = "https://files.pythonhosted.org/packages/a4/f6/ff7beaeb644bcad72bcfd5a03ff36d32ee4e53a8b29a639f11bcb65d06cd/scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1061b7c028a8663fb9a1a1baf9317b64a257fcb036dae5c8752b2abef31d136f", size = 12253728, upload-time = "2025-01-10T08:06:47.618Z" }, + { url = "https://files.pythonhosted.org/packages/29/7a/8bce8968883e9465de20be15542f4c7e221952441727c4dad24d534c6d99/scikit_learn-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e69fab4ebfc9c9b580a7a80111b43d214ab06250f8a7ef590a4edf72464dd86", size = 13147700, upload-time = "2025-01-10T08:06:50.888Z" }, + { url = "https://files.pythonhosted.org/packages/62/27/585859e72e117fe861c2079bcba35591a84f801e21bc1ab85bce6ce60305/scikit_learn-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:70b1d7e85b1c96383f872a519b3375f92f14731e279a7b4c6cfd650cf5dffc52", size = 11110613, upload-time = "2025-01-10T08:06:54.115Z" }, + { url = "https://files.pythonhosted.org/packages/2e/59/8eb1872ca87009bdcdb7f3cdc679ad557b992c12f4b61f9250659e592c63/scikit_learn-1.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ffa1e9e25b3d93990e74a4be2c2fc61ee5af85811562f1288d5d055880c4322", size = 12010001, upload-time = "2025-01-10T08:06:58.613Z" }, + { url = "https://files.pythonhosted.org/packages/9d/05/f2fc4effc5b32e525408524c982c468c29d22f828834f0625c5ef3d601be/scikit_learn-1.6.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dc5cf3d68c5a20ad6d571584c0750ec641cc46aeef1c1507be51300e6003a7e1", size = 11096360, upload-time = "2025-01-10T08:07:01.556Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e4/4195d52cf4f113573fb8ebc44ed5a81bd511a92c0228889125fac2f4c3d1/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c06beb2e839ecc641366000ca84f3cf6fa9faa1777e29cf0c04be6e4d096a348", size = 12209004, upload-time = "2025-01-10T08:07:06.931Z" }, + { url = "https://files.pythonhosted.org/packages/94/be/47e16cdd1e7fcf97d95b3cb08bde1abb13e627861af427a3651fcb80b517/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8ca8cb270fee8f1f76fa9bfd5c3507d60c6438bbee5687f81042e2bb98e5a97", size = 13171776, upload-time = "2025-01-10T08:07:11.715Z" }, + { url = "https://files.pythonhosted.org/packages/34/b0/ca92b90859070a1487827dbc672f998da95ce83edce1270fc23f96f1f61a/scikit_learn-1.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:7a1c43c8ec9fde528d664d947dc4c0789be4077a3647f232869f41d9bf50e0fb", size = 11071865, upload-time = "2025-01-10T08:07:16.088Z" }, + { url = "https://files.pythonhosted.org/packages/12/ae/993b0fb24a356e71e9a894e42b8a9eec528d4c70217353a1cd7a48bc25d4/scikit_learn-1.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a17c1dea1d56dcda2fac315712f3651a1fea86565b64b48fa1bc090249cbf236", size = 11955804, upload-time = "2025-01-10T08:07:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/d6/54/32fa2ee591af44507eac86406fa6bba968d1eb22831494470d0a2e4a1eb1/scikit_learn-1.6.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6a7aa5f9908f0f28f4edaa6963c0a6183f1911e63a69aa03782f0d924c830a35", size = 11100530, upload-time = "2025-01-10T08:07:23.675Z" }, + { url = "https://files.pythonhosted.org/packages/3f/58/55856da1adec655bdce77b502e94a267bf40a8c0b89f8622837f89503b5a/scikit_learn-1.6.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0650e730afb87402baa88afbf31c07b84c98272622aaba002559b614600ca691", size = 12433852, upload-time = "2025-01-10T08:07:26.817Z" }, + { url = "https://files.pythonhosted.org/packages/ff/4f/c83853af13901a574f8f13b645467285a48940f185b690936bb700a50863/scikit_learn-1.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:3f59fe08dc03ea158605170eb52b22a105f238a5d512c4470ddeca71feae8e5f", size = 11337256, upload-time = "2025-01-10T08:07:31.084Z" }, ] [[package]] @@ -3989,53 +4084,53 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214 } -wheels = [ - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/d1/84/55bc4881973d3f79b479a5a2e2df61c8c9a04fcb986a213ac9c02cfb659b/scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13", size = 41259201 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/ab/a7/0ddaf514ce8a8714f6ed243a2b391b41dbb65251affe21ee3077ec45ea9a/scipy-1.15.3-cp311-cp311-win_amd64.whl", hash = "sha256:ae48a786a28412d744c62fd7816a4118ef97e5be0bee968ce8f0a2fba7acf3bb", size = 41246504 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/e6/eb/3bf6ea8ab7f1503dca3a10df2e4b9c3f6b3316df07f6c0ded94b281c7101/scipy-1.15.3-cp312-cp312-win_amd64.whl", hash = "sha256:52092bc0472cfd17df49ff17e70624345efece4e1a12b23783a1ac59a1b728ed", size = 40966184 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/87/2e/892ad2862ba54f084ffe8cc4a22667eaf9c2bcec6d2bff1d15713c6c0703/scipy-1.15.3-cp313-cp313-win_amd64.whl", hash = "sha256:b90ab29d0c37ec9bf55424c064312930ca5f4bde15ee8619ee44e69319aab163", size = 40988851 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/81/06/0a5e5349474e1cbc5757975b21bd4fad0e72ebf138c5592f191646154e06/scipy-1.15.3-cp313-cp313t-win_amd64.whl", hash = "sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca", size = 40308097 }, +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/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]] @@ -4045,84 +4140,84 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/3c/2da625233f4e605155926566c0e7ea8dda361877f48e8b1655e53456f252/shapely-2.1.1.tar.gz", hash = "sha256:500621967f2ffe9642454808009044c21e5b35db89ce69f8a2042c2ffd0e2772", size = 315422 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/82/fa/f18025c95b86116dd8f1ec58cab078bd59ab51456b448136ca27463be533/shapely-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d8ccc872a632acb7bdcb69e5e78df27213f7efd195882668ffba5405497337c6", size = 1825117 }, - { url = "https://files.pythonhosted.org/packages/c7/65/46b519555ee9fb851234288be7c78be11e6260995281071d13abf2c313d0/shapely-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f24f2ecda1e6c091da64bcbef8dd121380948074875bd1b247b3d17e99407099", size = 1628541 }, - { url = "https://files.pythonhosted.org/packages/29/51/0b158a261df94e33505eadfe737db9531f346dfa60850945ad25fd4162f1/shapely-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45112a5be0b745b49e50f8829ce490eb67fefb0cea8d4f8ac5764bfedaa83d2d", size = 2948453 }, - { url = "https://files.pythonhosted.org/packages/a9/4f/6c9bb4bd7b1a14d7051641b9b479ad2a643d5cbc382bcf5bd52fd0896974/shapely-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c10ce6f11904d65e9bbb3e41e774903c944e20b3f0b282559885302f52f224a", size = 3057029 }, - { url = "https://files.pythonhosted.org/packages/89/0b/ad1b0af491d753a83ea93138eee12a4597f763ae12727968d05934fe7c78/shapely-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:61168010dfe4e45f956ffbbaf080c88afce199ea81eb1f0ac43230065df320bd", size = 3894342 }, - { url = "https://files.pythonhosted.org/packages/7d/96/73232c5de0b9fdf0ec7ddfc95c43aaf928740e87d9f168bff0e928d78c6d/shapely-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cacf067cdff741cd5c56a21c52f54ece4e4dad9d311130493a791997da4a886b", size = 4056766 }, - { url = "https://files.pythonhosted.org/packages/43/cc/eec3c01f754f5b3e0c47574b198f9deb70465579ad0dad0e1cef2ce9e103/shapely-2.1.1-cp310-cp310-win32.whl", hash = "sha256:23b8772c3b815e7790fb2eab75a0b3951f435bc0fce7bb146cb064f17d35ab4f", size = 1523744 }, - { url = "https://files.pythonhosted.org/packages/50/fc/a7187e6dadb10b91e66a9e715d28105cde6489e1017cce476876185a43da/shapely-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:2c7b2b6143abf4fa77851cef8ef690e03feade9a0d48acd6dc41d9e0e78d7ca6", size = 1703061 }, - { url = "https://files.pythonhosted.org/packages/19/97/2df985b1e03f90c503796ad5ecd3d9ed305123b64d4ccb54616b30295b29/shapely-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:587a1aa72bc858fab9b8c20427b5f6027b7cbc92743b8e2c73b9de55aa71c7a7", size = 1819368 }, - { url = "https://files.pythonhosted.org/packages/56/17/504518860370f0a28908b18864f43d72f03581e2b6680540ca668f07aa42/shapely-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fa5c53b0791a4b998f9ad84aad456c988600757a96b0a05e14bba10cebaaaea", size = 1625362 }, - { url = "https://files.pythonhosted.org/packages/36/a1/9677337d729b79fce1ef3296aac6b8ef4743419086f669e8a8070eff8f40/shapely-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aabecd038841ab5310d23495253f01c2a82a3aedae5ab9ca489be214aa458aa7", size = 2999005 }, - { url = "https://files.pythonhosted.org/packages/a2/17/e09357274699c6e012bbb5a8ea14765a4d5860bb658df1931c9f90d53bd3/shapely-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586f6aee1edec04e16227517a866df3e9a2e43c1f635efc32978bb3dc9c63753", size = 3108489 }, - { url = "https://files.pythonhosted.org/packages/17/5d/93a6c37c4b4e9955ad40834f42b17260ca74ecf36df2e81bb14d12221b90/shapely-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b9878b9e37ad26c72aada8de0c9cfe418d9e2ff36992a1693b7f65a075b28647", size = 3945727 }, - { url = "https://files.pythonhosted.org/packages/a3/1a/ad696648f16fd82dd6bfcca0b3b8fbafa7aacc13431c7fc4c9b49e481681/shapely-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9a531c48f289ba355e37b134e98e28c557ff13965d4653a5228d0f42a09aed0", size = 4109311 }, - { url = "https://files.pythonhosted.org/packages/d4/38/150dd245beab179ec0d4472bf6799bf18f21b1efbef59ac87de3377dbf1c/shapely-2.1.1-cp311-cp311-win32.whl", hash = "sha256:4866de2673a971820c75c0167b1f1cd8fb76f2d641101c23d3ca021ad0449bab", size = 1522982 }, - { url = "https://files.pythonhosted.org/packages/93/5b/842022c00fbb051083c1c85430f3bb55565b7fd2d775f4f398c0ba8052ce/shapely-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:20a9d79958b3d6c70d8a886b250047ea32ff40489d7abb47d01498c704557a93", size = 1703872 }, - { url = "https://files.pythonhosted.org/packages/fb/64/9544dc07dfe80a2d489060791300827c941c451e2910f7364b19607ea352/shapely-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2827365b58bf98efb60affc94a8e01c56dd1995a80aabe4b701465d86dcbba43", size = 1833021 }, - { url = "https://files.pythonhosted.org/packages/07/aa/fb5f545e72e89b6a0f04a0effda144f5be956c9c312c7d4e00dfddbddbcf/shapely-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9c551f7fa7f1e917af2347fe983f21f212863f1d04f08eece01e9c275903fad", size = 1643018 }, - { url = "https://files.pythonhosted.org/packages/03/46/61e03edba81de729f09d880ce7ae5c1af873a0814206bbfb4402ab5c3388/shapely-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78dec4d4fbe7b1db8dc36de3031767e7ece5911fb7782bc9e95c5cdec58fb1e9", size = 2986417 }, - { url = "https://files.pythonhosted.org/packages/1f/1e/83ec268ab8254a446b4178b45616ab5822d7b9d2b7eb6e27cf0b82f45601/shapely-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:872d3c0a7b8b37da0e23d80496ec5973c4692920b90de9f502b5beb994bbaaef", size = 3098224 }, - { url = "https://files.pythonhosted.org/packages/f1/44/0c21e7717c243e067c9ef8fa9126de24239f8345a5bba9280f7bb9935959/shapely-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2e2b9125ebfbc28ecf5353511de62f75a8515ae9470521c9a693e4bb9fbe0cf1", size = 3925982 }, - { url = "https://files.pythonhosted.org/packages/15/50/d3b4e15fefc103a0eb13d83bad5f65cd6e07a5d8b2ae920e767932a247d1/shapely-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4b96cea171b3d7f6786976a0520f178c42792897653ecca0c5422fb1e6946e6d", size = 4089122 }, - { url = "https://files.pythonhosted.org/packages/bd/05/9a68f27fc6110baeedeeebc14fd86e73fa38738c5b741302408fb6355577/shapely-2.1.1-cp312-cp312-win32.whl", hash = "sha256:39dca52201e02996df02e447f729da97cfb6ff41a03cb50f5547f19d02905af8", size = 1522437 }, - { url = "https://files.pythonhosted.org/packages/bc/e9/a4560e12b9338842a1f82c9016d2543eaa084fce30a1ca11991143086b57/shapely-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:13d643256f81d55a50013eff6321142781cf777eb6a9e207c2c9e6315ba6044a", size = 1703479 }, - { url = "https://files.pythonhosted.org/packages/71/8e/2bc836437f4b84d62efc1faddce0d4e023a5d990bbddd3c78b2004ebc246/shapely-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3004a644d9e89e26c20286d5fdc10f41b1744c48ce910bd1867fdff963fe6c48", size = 1832107 }, - { url = "https://files.pythonhosted.org/packages/12/a2/12c7cae5b62d5d851c2db836eadd0986f63918a91976495861f7c492f4a9/shapely-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1415146fa12d80a47d13cfad5310b3c8b9c2aa8c14a0c845c9d3d75e77cb54f6", size = 1642355 }, - { url = "https://files.pythonhosted.org/packages/5b/7e/6d28b43d53fea56de69c744e34c2b999ed4042f7a811dc1bceb876071c95/shapely-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21fcab88b7520820ec16d09d6bea68652ca13993c84dffc6129dc3607c95594c", size = 2968871 }, - { url = "https://files.pythonhosted.org/packages/dd/87/1017c31e52370b2b79e4d29e07cbb590ab9e5e58cf7e2bdfe363765d6251/shapely-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5ce6a5cc52c974b291237a96c08c5592e50f066871704fb5b12be2639d9026a", size = 3080830 }, - { url = "https://files.pythonhosted.org/packages/1d/fe/f4a03d81abd96a6ce31c49cd8aaba970eaaa98e191bd1e4d43041e57ae5a/shapely-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:04e4c12a45a1d70aeb266618d8cf81a2de9c4df511b63e105b90bfdfb52146de", size = 3908961 }, - { url = "https://files.pythonhosted.org/packages/ef/59/7605289a95a6844056a2017ab36d9b0cb9d6a3c3b5317c1f968c193031c9/shapely-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ca74d851ca5264aae16c2b47e96735579686cb69fa93c4078070a0ec845b8d8", size = 4079623 }, - { url = "https://files.pythonhosted.org/packages/bc/4d/9fea036eff2ef4059d30247128b2d67aaa5f0b25e9fc27e1d15cc1b84704/shapely-2.1.1-cp313-cp313-win32.whl", hash = "sha256:fd9130501bf42ffb7e0695b9ea17a27ae8ce68d50b56b6941c7f9b3d3453bc52", size = 1521916 }, - { url = "https://files.pythonhosted.org/packages/12/d9/6d13b8957a17c95794f0c4dfb65ecd0957e6c7131a56ce18d135c1107a52/shapely-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:ab8d878687b438a2f4c138ed1a80941c6ab0029e0f4c785ecfe114413b498a97", size = 1702746 }, - { url = "https://files.pythonhosted.org/packages/60/36/b1452e3e7f35f5f6454d96f3be6e2bb87082720ff6c9437ecc215fa79be0/shapely-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0c062384316a47f776305ed2fa22182717508ffdeb4a56d0ff4087a77b2a0f6d", size = 1833482 }, - { url = "https://files.pythonhosted.org/packages/ce/ca/8e6f59be0718893eb3e478141285796a923636dc8f086f83e5b0ec0036d0/shapely-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4ecf6c196b896e8f1360cc219ed4eee1c1e5f5883e505d449f263bd053fb8c05", size = 1642256 }, - { url = "https://files.pythonhosted.org/packages/ab/78/0053aea449bb1d4503999525fec6232f049abcdc8df60d290416110de943/shapely-2.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb00070b4c4860f6743c600285109c273cca5241e970ad56bb87bef0be1ea3a0", size = 3016614 }, - { url = "https://files.pythonhosted.org/packages/ee/53/36f1b1de1dfafd1b457dcbafa785b298ce1b8a3e7026b79619e708a245d5/shapely-2.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14a9afa5fa980fbe7bf63706fdfb8ff588f638f145a1d9dbc18374b5b7de913", size = 3093542 }, - { url = "https://files.pythonhosted.org/packages/b9/bf/0619f37ceec6b924d84427c88835b61f27f43560239936ff88915c37da19/shapely-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b640e390dabde790e3fb947198b466e63223e0a9ccd787da5f07bcb14756c28d", size = 3945961 }, - { url = "https://files.pythonhosted.org/packages/93/c9/20ca4afeb572763b07a7997f00854cb9499df6af85929e93012b189d8917/shapely-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:69e08bf9697c1b73ec6aa70437db922bafcea7baca131c90c26d59491a9760f9", size = 4089514 }, - { url = "https://files.pythonhosted.org/packages/33/6a/27036a5a560b80012a544366bceafd491e8abb94a8db14047b5346b5a749/shapely-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:ef2d09d5a964cc90c2c18b03566cf918a61c248596998a0301d5b632beadb9db", size = 1540607 }, - { url = "https://files.pythonhosted.org/packages/ea/f1/5e9b3ba5c7aa7ebfaf269657e728067d16a7c99401c7973ddf5f0cf121bd/shapely-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8cb8f17c377260452e9d7720eeaf59082c5f8ea48cf104524d953e5d36d4bdb7", size = 1723061 }, +sdist = { url = "https://files.pythonhosted.org/packages/ca/3c/2da625233f4e605155926566c0e7ea8dda361877f48e8b1655e53456f252/shapely-2.1.1.tar.gz", hash = "sha256:500621967f2ffe9642454808009044c21e5b35db89ce69f8a2042c2ffd0e2772", size = 315422, upload-time = "2025-05-19T11:04:41.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/fa/f18025c95b86116dd8f1ec58cab078bd59ab51456b448136ca27463be533/shapely-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d8ccc872a632acb7bdcb69e5e78df27213f7efd195882668ffba5405497337c6", size = 1825117, upload-time = "2025-05-19T11:03:43.547Z" }, + { url = "https://files.pythonhosted.org/packages/c7/65/46b519555ee9fb851234288be7c78be11e6260995281071d13abf2c313d0/shapely-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f24f2ecda1e6c091da64bcbef8dd121380948074875bd1b247b3d17e99407099", size = 1628541, upload-time = "2025-05-19T11:03:45.162Z" }, + { url = "https://files.pythonhosted.org/packages/29/51/0b158a261df94e33505eadfe737db9531f346dfa60850945ad25fd4162f1/shapely-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45112a5be0b745b49e50f8829ce490eb67fefb0cea8d4f8ac5764bfedaa83d2d", size = 2948453, upload-time = "2025-05-19T11:03:46.681Z" }, + { url = "https://files.pythonhosted.org/packages/a9/4f/6c9bb4bd7b1a14d7051641b9b479ad2a643d5cbc382bcf5bd52fd0896974/shapely-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c10ce6f11904d65e9bbb3e41e774903c944e20b3f0b282559885302f52f224a", size = 3057029, upload-time = "2025-05-19T11:03:48.346Z" }, + { url = "https://files.pythonhosted.org/packages/89/0b/ad1b0af491d753a83ea93138eee12a4597f763ae12727968d05934fe7c78/shapely-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:61168010dfe4e45f956ffbbaf080c88afce199ea81eb1f0ac43230065df320bd", size = 3894342, upload-time = "2025-05-19T11:03:49.602Z" }, + { url = "https://files.pythonhosted.org/packages/7d/96/73232c5de0b9fdf0ec7ddfc95c43aaf928740e87d9f168bff0e928d78c6d/shapely-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cacf067cdff741cd5c56a21c52f54ece4e4dad9d311130493a791997da4a886b", size = 4056766, upload-time = "2025-05-19T11:03:51.252Z" }, + { url = "https://files.pythonhosted.org/packages/43/cc/eec3c01f754f5b3e0c47574b198f9deb70465579ad0dad0e1cef2ce9e103/shapely-2.1.1-cp310-cp310-win32.whl", hash = "sha256:23b8772c3b815e7790fb2eab75a0b3951f435bc0fce7bb146cb064f17d35ab4f", size = 1523744, upload-time = "2025-05-19T11:03:52.624Z" }, + { url = "https://files.pythonhosted.org/packages/50/fc/a7187e6dadb10b91e66a9e715d28105cde6489e1017cce476876185a43da/shapely-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:2c7b2b6143abf4fa77851cef8ef690e03feade9a0d48acd6dc41d9e0e78d7ca6", size = 1703061, upload-time = "2025-05-19T11:03:54.695Z" }, + { url = "https://files.pythonhosted.org/packages/19/97/2df985b1e03f90c503796ad5ecd3d9ed305123b64d4ccb54616b30295b29/shapely-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:587a1aa72bc858fab9b8c20427b5f6027b7cbc92743b8e2c73b9de55aa71c7a7", size = 1819368, upload-time = "2025-05-19T11:03:55.937Z" }, + { url = "https://files.pythonhosted.org/packages/56/17/504518860370f0a28908b18864f43d72f03581e2b6680540ca668f07aa42/shapely-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fa5c53b0791a4b998f9ad84aad456c988600757a96b0a05e14bba10cebaaaea", size = 1625362, upload-time = "2025-05-19T11:03:57.06Z" }, + { url = "https://files.pythonhosted.org/packages/36/a1/9677337d729b79fce1ef3296aac6b8ef4743419086f669e8a8070eff8f40/shapely-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aabecd038841ab5310d23495253f01c2a82a3aedae5ab9ca489be214aa458aa7", size = 2999005, upload-time = "2025-05-19T11:03:58.692Z" }, + { url = "https://files.pythonhosted.org/packages/a2/17/e09357274699c6e012bbb5a8ea14765a4d5860bb658df1931c9f90d53bd3/shapely-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586f6aee1edec04e16227517a866df3e9a2e43c1f635efc32978bb3dc9c63753", size = 3108489, upload-time = "2025-05-19T11:04:00.059Z" }, + { url = "https://files.pythonhosted.org/packages/17/5d/93a6c37c4b4e9955ad40834f42b17260ca74ecf36df2e81bb14d12221b90/shapely-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b9878b9e37ad26c72aada8de0c9cfe418d9e2ff36992a1693b7f65a075b28647", size = 3945727, upload-time = "2025-05-19T11:04:01.786Z" }, + { url = "https://files.pythonhosted.org/packages/a3/1a/ad696648f16fd82dd6bfcca0b3b8fbafa7aacc13431c7fc4c9b49e481681/shapely-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9a531c48f289ba355e37b134e98e28c557ff13965d4653a5228d0f42a09aed0", size = 4109311, upload-time = "2025-05-19T11:04:03.134Z" }, + { url = "https://files.pythonhosted.org/packages/d4/38/150dd245beab179ec0d4472bf6799bf18f21b1efbef59ac87de3377dbf1c/shapely-2.1.1-cp311-cp311-win32.whl", hash = "sha256:4866de2673a971820c75c0167b1f1cd8fb76f2d641101c23d3ca021ad0449bab", size = 1522982, upload-time = "2025-05-19T11:04:05.217Z" }, + { url = "https://files.pythonhosted.org/packages/93/5b/842022c00fbb051083c1c85430f3bb55565b7fd2d775f4f398c0ba8052ce/shapely-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:20a9d79958b3d6c70d8a886b250047ea32ff40489d7abb47d01498c704557a93", size = 1703872, upload-time = "2025-05-19T11:04:06.791Z" }, + { url = "https://files.pythonhosted.org/packages/fb/64/9544dc07dfe80a2d489060791300827c941c451e2910f7364b19607ea352/shapely-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2827365b58bf98efb60affc94a8e01c56dd1995a80aabe4b701465d86dcbba43", size = 1833021, upload-time = "2025-05-19T11:04:08.022Z" }, + { url = "https://files.pythonhosted.org/packages/07/aa/fb5f545e72e89b6a0f04a0effda144f5be956c9c312c7d4e00dfddbddbcf/shapely-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9c551f7fa7f1e917af2347fe983f21f212863f1d04f08eece01e9c275903fad", size = 1643018, upload-time = "2025-05-19T11:04:09.343Z" }, + { url = "https://files.pythonhosted.org/packages/03/46/61e03edba81de729f09d880ce7ae5c1af873a0814206bbfb4402ab5c3388/shapely-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78dec4d4fbe7b1db8dc36de3031767e7ece5911fb7782bc9e95c5cdec58fb1e9", size = 2986417, upload-time = "2025-05-19T11:04:10.56Z" }, + { url = "https://files.pythonhosted.org/packages/1f/1e/83ec268ab8254a446b4178b45616ab5822d7b9d2b7eb6e27cf0b82f45601/shapely-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:872d3c0a7b8b37da0e23d80496ec5973c4692920b90de9f502b5beb994bbaaef", size = 3098224, upload-time = "2025-05-19T11:04:11.903Z" }, + { url = "https://files.pythonhosted.org/packages/f1/44/0c21e7717c243e067c9ef8fa9126de24239f8345a5bba9280f7bb9935959/shapely-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2e2b9125ebfbc28ecf5353511de62f75a8515ae9470521c9a693e4bb9fbe0cf1", size = 3925982, upload-time = "2025-05-19T11:04:13.224Z" }, + { url = "https://files.pythonhosted.org/packages/15/50/d3b4e15fefc103a0eb13d83bad5f65cd6e07a5d8b2ae920e767932a247d1/shapely-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4b96cea171b3d7f6786976a0520f178c42792897653ecca0c5422fb1e6946e6d", size = 4089122, upload-time = "2025-05-19T11:04:14.477Z" }, + { url = "https://files.pythonhosted.org/packages/bd/05/9a68f27fc6110baeedeeebc14fd86e73fa38738c5b741302408fb6355577/shapely-2.1.1-cp312-cp312-win32.whl", hash = "sha256:39dca52201e02996df02e447f729da97cfb6ff41a03cb50f5547f19d02905af8", size = 1522437, upload-time = "2025-05-19T11:04:16.203Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e9/a4560e12b9338842a1f82c9016d2543eaa084fce30a1ca11991143086b57/shapely-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:13d643256f81d55a50013eff6321142781cf777eb6a9e207c2c9e6315ba6044a", size = 1703479, upload-time = "2025-05-19T11:04:18.497Z" }, + { url = "https://files.pythonhosted.org/packages/71/8e/2bc836437f4b84d62efc1faddce0d4e023a5d990bbddd3c78b2004ebc246/shapely-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3004a644d9e89e26c20286d5fdc10f41b1744c48ce910bd1867fdff963fe6c48", size = 1832107, upload-time = "2025-05-19T11:04:19.736Z" }, + { url = "https://files.pythonhosted.org/packages/12/a2/12c7cae5b62d5d851c2db836eadd0986f63918a91976495861f7c492f4a9/shapely-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1415146fa12d80a47d13cfad5310b3c8b9c2aa8c14a0c845c9d3d75e77cb54f6", size = 1642355, upload-time = "2025-05-19T11:04:21.035Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/6d28b43d53fea56de69c744e34c2b999ed4042f7a811dc1bceb876071c95/shapely-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21fcab88b7520820ec16d09d6bea68652ca13993c84dffc6129dc3607c95594c", size = 2968871, upload-time = "2025-05-19T11:04:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/dd/87/1017c31e52370b2b79e4d29e07cbb590ab9e5e58cf7e2bdfe363765d6251/shapely-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5ce6a5cc52c974b291237a96c08c5592e50f066871704fb5b12be2639d9026a", size = 3080830, upload-time = "2025-05-19T11:04:23.997Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fe/f4a03d81abd96a6ce31c49cd8aaba970eaaa98e191bd1e4d43041e57ae5a/shapely-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:04e4c12a45a1d70aeb266618d8cf81a2de9c4df511b63e105b90bfdfb52146de", size = 3908961, upload-time = "2025-05-19T11:04:25.702Z" }, + { url = "https://files.pythonhosted.org/packages/ef/59/7605289a95a6844056a2017ab36d9b0cb9d6a3c3b5317c1f968c193031c9/shapely-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ca74d851ca5264aae16c2b47e96735579686cb69fa93c4078070a0ec845b8d8", size = 4079623, upload-time = "2025-05-19T11:04:27.171Z" }, + { url = "https://files.pythonhosted.org/packages/bc/4d/9fea036eff2ef4059d30247128b2d67aaa5f0b25e9fc27e1d15cc1b84704/shapely-2.1.1-cp313-cp313-win32.whl", hash = "sha256:fd9130501bf42ffb7e0695b9ea17a27ae8ce68d50b56b6941c7f9b3d3453bc52", size = 1521916, upload-time = "2025-05-19T11:04:28.405Z" }, + { url = "https://files.pythonhosted.org/packages/12/d9/6d13b8957a17c95794f0c4dfb65ecd0957e6c7131a56ce18d135c1107a52/shapely-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:ab8d878687b438a2f4c138ed1a80941c6ab0029e0f4c785ecfe114413b498a97", size = 1702746, upload-time = "2025-05-19T11:04:29.643Z" }, + { url = "https://files.pythonhosted.org/packages/60/36/b1452e3e7f35f5f6454d96f3be6e2bb87082720ff6c9437ecc215fa79be0/shapely-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0c062384316a47f776305ed2fa22182717508ffdeb4a56d0ff4087a77b2a0f6d", size = 1833482, upload-time = "2025-05-19T11:04:30.852Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ca/8e6f59be0718893eb3e478141285796a923636dc8f086f83e5b0ec0036d0/shapely-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4ecf6c196b896e8f1360cc219ed4eee1c1e5f5883e505d449f263bd053fb8c05", size = 1642256, upload-time = "2025-05-19T11:04:32.068Z" }, + { url = "https://files.pythonhosted.org/packages/ab/78/0053aea449bb1d4503999525fec6232f049abcdc8df60d290416110de943/shapely-2.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb00070b4c4860f6743c600285109c273cca5241e970ad56bb87bef0be1ea3a0", size = 3016614, upload-time = "2025-05-19T11:04:33.7Z" }, + { url = "https://files.pythonhosted.org/packages/ee/53/36f1b1de1dfafd1b457dcbafa785b298ce1b8a3e7026b79619e708a245d5/shapely-2.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14a9afa5fa980fbe7bf63706fdfb8ff588f638f145a1d9dbc18374b5b7de913", size = 3093542, upload-time = "2025-05-19T11:04:34.952Z" }, + { url = "https://files.pythonhosted.org/packages/b9/bf/0619f37ceec6b924d84427c88835b61f27f43560239936ff88915c37da19/shapely-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b640e390dabde790e3fb947198b466e63223e0a9ccd787da5f07bcb14756c28d", size = 3945961, upload-time = "2025-05-19T11:04:36.32Z" }, + { url = "https://files.pythonhosted.org/packages/93/c9/20ca4afeb572763b07a7997f00854cb9499df6af85929e93012b189d8917/shapely-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:69e08bf9697c1b73ec6aa70437db922bafcea7baca131c90c26d59491a9760f9", size = 4089514, upload-time = "2025-05-19T11:04:37.683Z" }, + { url = "https://files.pythonhosted.org/packages/33/6a/27036a5a560b80012a544366bceafd491e8abb94a8db14047b5346b5a749/shapely-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:ef2d09d5a964cc90c2c18b03566cf918a61c248596998a0301d5b632beadb9db", size = 1540607, upload-time = "2025-05-19T11:04:38.925Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f1/5e9b3ba5c7aa7ebfaf269657e728067d16a7c99401c7973ddf5f0cf121bd/shapely-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8cb8f17c377260452e9d7720eeaf59082c5f8ea48cf104524d953e5d36d4bdb7", size = 1723061, upload-time = "2025-05-19T11:04:40.082Z" }, ] [[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.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[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 }, + { 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 = "sortedcontainers" version = "2.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594 } +sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, + { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, ] [[package]] @@ -4133,9 +4228,9 @@ dependencies = [ { name = "anyio" }, { name = "starlette" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/10/5f/28f45b1ff14bee871bacafd0a97213f7ec70e389939a80c60c0fb72a9fc9/sse_starlette-2.3.5.tar.gz", hash = "sha256:228357b6e42dcc73a427990e2b4a03c023e2495ecee82e14f07ba15077e334b2", size = 17511 } +sdist = { url = "https://files.pythonhosted.org/packages/10/5f/28f45b1ff14bee871bacafd0a97213f7ec70e389939a80c60c0fb72a9fc9/sse_starlette-2.3.5.tar.gz", hash = "sha256:228357b6e42dcc73a427990e2b4a03c023e2495ecee82e14f07ba15077e334b2", size = 17511, upload-time = "2025-05-12T18:23:52.601Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/48/3e49cf0f64961656402c0023edbc51844fe17afe53ab50e958a6dbbbd499/sse_starlette-2.3.5-py3-none-any.whl", hash = "sha256:251708539a335570f10eaaa21d1848a10c42ee6dc3a9cf37ef42266cdb1c52a8", size = 10233 }, + { url = "https://files.pythonhosted.org/packages/c8/48/3e49cf0f64961656402c0023edbc51844fe17afe53ab50e958a6dbbbd499/sse_starlette-2.3.5-py3-none-any.whl", hash = "sha256:251708539a335570f10eaaa21d1848a10c42ee6dc3a9cf37ef42266cdb1c52a8", size = 10233, upload-time = "2025-05-12T18:23:50.722Z" }, ] [[package]] @@ -4147,9 +4242,9 @@ dependencies = [ { name = "executing" }, { name = "pure-eval" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707 } +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 }, + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, ] [[package]] @@ -4159,9 +4254,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846 } +sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037 }, + { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037, upload-time = "2025-04-13T13:56:16.21Z" }, ] [[package]] @@ -4171,9 +4266,9 @@ 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 } +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/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353 }, + { 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]] @@ -4186,13 +4281,13 @@ dependencies = [ { name = "types-protobuf" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/2a/bd8cfdd116e65309c6a9f3b72126d658159d6655163802ecf719c5435d06/temporalio-1.11.1.tar.gz", hash = "sha256:d7b5e4fdcdb523fa56979fa7330903b3188980f9aec9a4564c2ad910aec0cb85", size = 1509413 } +sdist = { url = "https://files.pythonhosted.org/packages/b7/2a/bd8cfdd116e65309c6a9f3b72126d658159d6655163802ecf719c5435d06/temporalio-1.11.1.tar.gz", hash = "sha256:d7b5e4fdcdb523fa56979fa7330903b3188980f9aec9a4564c2ad910aec0cb85", size = 1509413, upload-time = "2025-05-09T16:56:29.89Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/d9/60b127d9a7e313a94196f10d34bc070c1b4aa9f36d18a27a4641a8f5071a/temporalio-1.11.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:747e6562a5de53b9b72cbbf4c731c128e9db7448211df0a53f0ae74cd492e292", size = 11792321 }, - { url = "https://files.pythonhosted.org/packages/96/28/f3d1829ef0fa7df8e9421172a16afec382733b3de8d1d92ff521cd548509/temporalio-1.11.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1c98d50520cb145c6219847876db8f8928d2b8f371341184686ebd30371868bf", size = 11480568 }, - { url = "https://files.pythonhosted.org/packages/f2/43/245578eaeaddc4166ec5726adfeea7cc356a6600f9996e55d74b13e162e6/temporalio-1.11.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96711fc26387e6308ff68c12653a887230bb86cf26e6bc00c7f9208d3e6641df", size = 11864944 }, - { url = "https://files.pythonhosted.org/packages/6e/43/f7fe59b4d2a4ed1b14aadaa8b3a848ea5a36958f51f78d0e32c7d44f0d37/temporalio-1.11.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78f6d4d1032ede5051a10e41670d6168e2821a5c2e533e2a2eafa0eb8d2d1911", size = 12041100 }, - { url = "https://files.pythonhosted.org/packages/88/17/1d58baeccbd4caea47360d623e67165120023ff8bbb7bc1f24e0f300d26a/temporalio-1.11.1-cp39-abi3-win_amd64.whl", hash = "sha256:504f6ddb219bd7b39c67b7648c599edf3626043eef90d11da952af5db8c7f1a5", size = 12125170 }, + { url = "https://files.pythonhosted.org/packages/c4/d9/60b127d9a7e313a94196f10d34bc070c1b4aa9f36d18a27a4641a8f5071a/temporalio-1.11.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:747e6562a5de53b9b72cbbf4c731c128e9db7448211df0a53f0ae74cd492e292", size = 11792321, upload-time = "2025-05-09T16:56:09.963Z" }, + { url = "https://files.pythonhosted.org/packages/96/28/f3d1829ef0fa7df8e9421172a16afec382733b3de8d1d92ff521cd548509/temporalio-1.11.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1c98d50520cb145c6219847876db8f8928d2b8f371341184686ebd30371868bf", size = 11480568, upload-time = "2025-05-09T16:56:15.074Z" }, + { url = "https://files.pythonhosted.org/packages/f2/43/245578eaeaddc4166ec5726adfeea7cc356a6600f9996e55d74b13e162e6/temporalio-1.11.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96711fc26387e6308ff68c12653a887230bb86cf26e6bc00c7f9208d3e6641df", size = 11864944, upload-time = "2025-05-09T16:56:19.411Z" }, + { url = "https://files.pythonhosted.org/packages/6e/43/f7fe59b4d2a4ed1b14aadaa8b3a848ea5a36958f51f78d0e32c7d44f0d37/temporalio-1.11.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78f6d4d1032ede5051a10e41670d6168e2821a5c2e533e2a2eafa0eb8d2d1911", size = 12041100, upload-time = "2025-05-09T16:56:23.186Z" }, + { url = "https://files.pythonhosted.org/packages/88/17/1d58baeccbd4caea47360d623e67165120023ff8bbb7bc1f24e0f300d26a/temporalio-1.11.1-cp39-abi3-win_amd64.whl", hash = "sha256:504f6ddb219bd7b39c67b7648c599edf3626043eef90d11da952af5db8c7f1a5", size = 12125170, upload-time = "2025-05-09T16:56:26.87Z" }, ] [package.optional-dependencies] @@ -4205,18 +4300,18 @@ opentelemetry = [ name = "tenacity" version = "9.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036 } +sdist = { url = "https://files.pythonhosted.org/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036, upload-time = "2025-04-02T08:25:09.966Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248 }, + { url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248, upload-time = "2025-04-02T08:25:07.678Z" }, ] [[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 } +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 }, + { 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]] @@ -4227,32 +4322,32 @@ 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 } -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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/cd/4c/22eb8e9856a2b1808d0a002d171e534eac03f96dbe1161978d7389a59498/tiktoken-0.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:26113fec3bd7a352e4b33dbaf1bd8948de2507e30bd95a44e2b1156647bc01b4", size = 894026 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/6f/07/c67ad1724b8e14e2b4c8cca04b15da158733ac60136879131db05dda7c30/tiktoken-0.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:11a20e67fdf58b0e2dea7b8654a288e481bb4fc0289d3ad21291f8d0849915fb", size = 893895 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/5b/64/b16003419a1d7728d0d8c0d56a4c24325e7b10a21a9dd1fc0f7115c02f0a/tiktoken-0.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:5a62d7a25225bafed786a524c1b9f0910a1128f4232615bf3f8257a73aaa3b16", size = 894897 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/de/a8/8f499c179ec900783ffe133e9aab10044481679bb9aad78436d239eee716/tiktoken-0.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:5ea0edb6f83dc56d794723286215918c1cde03712cbbafa0348b33448faf5b95", size = 894669 }, +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]] @@ -4262,111 +4357,111 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/25/b1681c1c30ea3ea6e584ae3fffd552430b12faa599b558c4c4783f56d7ff/tokenizers-0.20.3.tar.gz", hash = "sha256:2278b34c5d0dd78e087e1ca7f9b1dcbf129d80211afa645f214bd6e051037539", size = 340513 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/51/421bb0052fc4333f7c1e3231d8c6607552933d919b628c8fabd06f60ba1e/tokenizers-0.20.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:31ccab28dbb1a9fe539787210b0026e22debeab1662970f61c2d921f7557f7e4", size = 2674308 }, - { url = "https://files.pythonhosted.org/packages/a6/e9/f651f8d27614fd59af387f4dfa568b55207e5fac8d06eec106dc00b921c4/tokenizers-0.20.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6361191f762bda98c773da418cf511cbaa0cb8d0a1196f16f8c0119bde68ff8", size = 2559363 }, - { url = "https://files.pythonhosted.org/packages/e3/e8/0e9f81a09ab79f409eabfd99391ca519e315496694671bebca24c3e90448/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f128d5da1202b78fa0a10d8d938610472487da01b57098d48f7e944384362514", size = 2892896 }, - { url = "https://files.pythonhosted.org/packages/b0/72/15fdbc149e05005e99431ecd471807db2241983deafe1e704020f608f40e/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79c4121a2e9433ad7ef0769b9ca1f7dd7fa4c0cd501763d0a030afcbc6384481", size = 2802785 }, - { url = "https://files.pythonhosted.org/packages/26/44/1f8aea48f9bb117d966b7272484671b33a509f6217a8e8544d79442c90db/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7850fde24197fe5cd6556e2fdba53a6d3bae67c531ea33a3d7c420b90904141", size = 3086060 }, - { url = "https://files.pythonhosted.org/packages/2e/83/82ba40da99870b3a0b801cffaf4f099f088a84c7e07d32cc6ca751ce08e6/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b357970c095dc134978a68c67d845a1e3803ab7c4fbb39195bde914e7e13cf8b", size = 3096760 }, - { url = "https://files.pythonhosted.org/packages/f3/46/7a025404201d937f86548928616c0a164308aa3998e546efdf798bf5ee9c/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a333d878c4970b72d6c07848b90c05f6b045cf9273fc2bc04a27211721ad6118", size = 3380165 }, - { url = "https://files.pythonhosted.org/packages/aa/49/15fae66ac62e49255eeedbb7f4127564b2c3f3aef2009913f525732d1a08/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd9fee817f655a8f50049f685e224828abfadd436b8ff67979fc1d054b435f1", size = 2994038 }, - { url = "https://files.pythonhosted.org/packages/f4/64/693afc9ba2393c2eed85c02bacb44762f06a29f0d1a5591fa5b40b39c0a2/tokenizers-0.20.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e7816808b402129393a435ea2a509679b41246175d6e5e9f25b8692bfaa272b", size = 8977285 }, - { url = "https://files.pythonhosted.org/packages/be/7e/6126c18694310fe07970717929e889898767c41fbdd95b9078e8aec0f9ef/tokenizers-0.20.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba96367db9d8a730d3a1d5996b4b7babb846c3994b8ef14008cd8660f55db59d", size = 9294890 }, - { url = "https://files.pythonhosted.org/packages/71/7d/5e3307a1091c8608a1e58043dff49521bc19553c6e9548c7fac6840cc2c4/tokenizers-0.20.3-cp310-none-win32.whl", hash = "sha256:ee31ba9d7df6a98619426283e80c6359f167e2e9882d9ce1b0254937dbd32f3f", size = 2196883 }, - { url = "https://files.pythonhosted.org/packages/47/62/aaf5b2a526b3b10c20985d9568ff8c8f27159345eaef3347831e78cd5894/tokenizers-0.20.3-cp310-none-win_amd64.whl", hash = "sha256:a845c08fdad554fe0871d1255df85772f91236e5fd6b9287ef8b64f5807dbd0c", size = 2381637 }, - { url = "https://files.pythonhosted.org/packages/c6/93/6742ef9206409d5ce1fdf44d5ca1687cdc3847ba0485424e2c731e6bcf67/tokenizers-0.20.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:585b51e06ca1f4839ce7759941e66766d7b060dccfdc57c4ca1e5b9a33013a90", size = 2674224 }, - { url = "https://files.pythonhosted.org/packages/aa/14/e75ece72e99f6ef9ae07777ca9fdd78608f69466a5cecf636e9bd2f25d5c/tokenizers-0.20.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:61cbf11954f3b481d08723ebd048ba4b11e582986f9be74d2c3bdd9293a4538d", size = 2558991 }, - { url = "https://files.pythonhosted.org/packages/46/54/033b5b2ba0c3ae01e026c6f7ced147d41a2fa1c573d00a66cb97f6d7f9b3/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef820880d5e4e8484e2fa54ff8d297bb32519eaa7815694dc835ace9130a3eea", size = 2892476 }, - { url = "https://files.pythonhosted.org/packages/e6/b0/cc369fb3297d61f3311cab523d16d48c869dc2f0ba32985dbf03ff811041/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:67ef4dcb8841a4988cd00dd288fb95dfc8e22ed021f01f37348fd51c2b055ba9", size = 2802775 }, - { url = "https://files.pythonhosted.org/packages/1a/74/62ad983e8ea6a63e04ed9c5be0b605056bf8aac2f0125f9b5e0b3e2b89fa/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff1ef8bd47a02b0dc191688ccb4da53600df5d4c9a05a4b68e1e3de4823e78eb", size = 3086138 }, - { url = "https://files.pythonhosted.org/packages/6b/ac/4637ba619db25094998523f9e6f5b456e1db1f8faa770a3d925d436db0c3/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:444d188186eab3148baf0615b522461b41b1f0cd58cd57b862ec94b6ac9780f1", size = 3098076 }, - { url = "https://files.pythonhosted.org/packages/58/ce/9793f2dc2ce529369807c9c74e42722b05034af411d60f5730b720388c7d/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37c04c032c1442740b2c2d925f1857885c07619224a533123ac7ea71ca5713da", size = 3379650 }, - { url = "https://files.pythonhosted.org/packages/50/f6/2841de926bc4118af996eaf0bdf0ea5b012245044766ffc0347e6c968e63/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:453c7769d22231960ee0e883d1005c93c68015025a5e4ae56275406d94a3c907", size = 2994005 }, - { url = "https://files.pythonhosted.org/packages/a3/b2/00915c4fed08e9505d37cf6eaab45b12b4bff8f6719d459abcb9ead86a4b/tokenizers-0.20.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4bb31f7b2847e439766aaa9cc7bccf7ac7088052deccdb2275c952d96f691c6a", size = 8977488 }, - { url = "https://files.pythonhosted.org/packages/e9/ac/1c069e7808181ff57bcf2d39e9b6fbee9133a55410e6ebdaa89f67c32e83/tokenizers-0.20.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:843729bf0f991b29655a069a2ff58a4c24375a553c70955e15e37a90dd4e045c", size = 9294935 }, - { url = "https://files.pythonhosted.org/packages/50/47/722feb70ee68d1c4412b12d0ea4acc2713179fd63f054913990f9e259492/tokenizers-0.20.3-cp311-none-win32.whl", hash = "sha256:efcce3a927b1e20ca694ba13f7a68c59b0bd859ef71e441db68ee42cf20c2442", size = 2197175 }, - { url = "https://files.pythonhosted.org/packages/75/68/1b4f928b15a36ed278332ac75d66d7eb65d865bf344d049c452c18447bf9/tokenizers-0.20.3-cp311-none-win_amd64.whl", hash = "sha256:88301aa0801f225725b6df5dea3d77c80365ff2362ca7e252583f2b4809c4cc0", size = 2381616 }, - { url = "https://files.pythonhosted.org/packages/07/00/92a08af2a6b0c88c50f1ab47d7189e695722ad9714b0ee78ea5e1e2e1def/tokenizers-0.20.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:49d12a32e190fad0e79e5bdb788d05da2f20d8e006b13a70859ac47fecf6ab2f", size = 2667951 }, - { url = "https://files.pythonhosted.org/packages/ec/9a/e17a352f0bffbf415cf7d73756f5c73a3219225fc5957bc2f39d52c61684/tokenizers-0.20.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:282848cacfb9c06d5e51489f38ec5aa0b3cd1e247a023061945f71f41d949d73", size = 2555167 }, - { url = "https://files.pythonhosted.org/packages/27/37/d108df55daf4f0fcf1f58554692ff71687c273d870a34693066f0847be96/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abe4e08c7d0cd6154c795deb5bf81d2122f36daf075e0c12a8b050d824ef0a64", size = 2898389 }, - { url = "https://files.pythonhosted.org/packages/b2/27/32f29da16d28f59472fa7fb38e7782069748c7e9ab9854522db20341624c/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ca94fc1b73b3883c98f0c88c77700b13d55b49f1071dfd57df2b06f3ff7afd64", size = 2795866 }, - { url = "https://files.pythonhosted.org/packages/29/4e/8a9a3c89e128c4a40f247b501c10279d2d7ade685953407c4d94c8c0f7a7/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef279c7e239f95c8bdd6ff319d9870f30f0d24915b04895f55b1adcf96d6c60d", size = 3085446 }, - { url = "https://files.pythonhosted.org/packages/b4/3b/a2a7962c496ebcd95860ca99e423254f760f382cd4bd376f8895783afaf5/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16384073973f6ccbde9852157a4fdfe632bb65208139c9d0c0bd0176a71fd67f", size = 3094378 }, - { url = "https://files.pythonhosted.org/packages/1f/f4/a8a33f0192a1629a3bd0afcad17d4d221bbf9276da4b95d226364208d5eb/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:312d522caeb8a1a42ebdec87118d99b22667782b67898a76c963c058a7e41d4f", size = 3385755 }, - { url = "https://files.pythonhosted.org/packages/9e/65/c83cb3545a65a9eaa2e13b22c93d5e00bd7624b354a44adbdc93d5d9bd91/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2b7cb962564785a83dafbba0144ecb7f579f1d57d8c406cdaa7f32fe32f18ad", size = 2997679 }, - { url = "https://files.pythonhosted.org/packages/55/e9/a80d4e592307688a67c7c59ab77e03687b6a8bd92eb5db763a2c80f93f57/tokenizers-0.20.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:124c5882ebb88dadae1fc788a582299fcd3a8bd84fc3e260b9918cf28b8751f5", size = 8989296 }, - { url = "https://files.pythonhosted.org/packages/90/af/60c957af8d2244321124e893828f1a4817cde1a2d08d09d423b73f19bd2f/tokenizers-0.20.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2b6e54e71f84c4202111a489879005cb14b92616a87417f6c102c833af961ea2", size = 9303621 }, - { url = "https://files.pythonhosted.org/packages/be/a9/96172310ee141009646d63a1ca267c099c462d747fe5ef7e33f74e27a683/tokenizers-0.20.3-cp312-none-win32.whl", hash = "sha256:83d9bfbe9af86f2d9df4833c22e94d94750f1d0cd9bfb22a7bb90a86f61cdb1c", size = 2188979 }, - { url = "https://files.pythonhosted.org/packages/bd/68/61d85ae7ae96dde7d0974ff3538db75d5cdc29be2e4329cd7fc51a283e22/tokenizers-0.20.3-cp312-none-win_amd64.whl", hash = "sha256:44def74cee574d609a36e17c8914311d1b5dbcfe37c55fd29369d42591b91cf2", size = 2380725 }, - { url = "https://files.pythonhosted.org/packages/07/19/36e9eaafb229616cb8502b42030fa7fe347550e76cb618de71b498fc3222/tokenizers-0.20.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e0b630e0b536ef0e3c8b42c685c1bc93bd19e98c0f1543db52911f8ede42cf84", size = 2666813 }, - { url = "https://files.pythonhosted.org/packages/b9/c7/e2ce1d4f756c8a62ef93fdb4df877c2185339b6d63667b015bf70ea9d34b/tokenizers-0.20.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a02d160d2b19bcbfdf28bd9a4bf11be4cb97d0499c000d95d4c4b1a4312740b6", size = 2555354 }, - { url = "https://files.pythonhosted.org/packages/7c/cf/5309c2d173a6a67f9ec8697d8e710ea32418de6fd8541778032c202a1c3e/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e3d80d89b068bc30034034b5319218c7c0a91b00af19679833f55f3becb6945", size = 2897745 }, - { url = "https://files.pythonhosted.org/packages/2c/e5/af3078e32f225e680e69d61f78855880edb8d53f5850a1834d519b2b103f/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:174a54910bed1b089226512b4458ea60d6d6fd93060254734d3bc3540953c51c", size = 2794385 }, - { url = "https://files.pythonhosted.org/packages/0b/a7/bc421fe46650cc4eb4a913a236b88c243204f32c7480684d2f138925899e/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:098b8a632b8656aa5802c46689462c5c48f02510f24029d71c208ec2c822e771", size = 3084580 }, - { url = "https://files.pythonhosted.org/packages/c6/22/97e1e95ee81f75922c9f569c23cb2b1fdc7f5a7a29c4c9fae17e63f751a6/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:78c8c143e3ae41e718588281eb3e212c2b31623c9d6d40410ec464d7d6221fb5", size = 3093581 }, - { url = "https://files.pythonhosted.org/packages/d5/14/f0df0ee3b9e516121e23c0099bccd7b9f086ba9150021a750e99b16ce56f/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b26b0aadb18cd8701077362ba359a06683662d5cafe3e8e8aba10eb05c037f1", size = 3385934 }, - { url = "https://files.pythonhosted.org/packages/66/52/7a171bd4929e3ffe61a29b4340fe5b73484709f92a8162a18946e124c34c/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07d7851a72717321022f3774e84aa9d595a041d643fafa2e87fbc9b18711dac0", size = 2997311 }, - { url = "https://files.pythonhosted.org/packages/7c/64/f1993bb8ebf775d56875ca0d50a50f2648bfbbb143da92fe2e6ceeb4abd5/tokenizers-0.20.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:bd44e48a430ada902c6266a8245f5036c4fe744fcb51f699999fbe82aa438797", size = 8988601 }, - { url = "https://files.pythonhosted.org/packages/d6/3f/49fa63422159bbc2f2a4ac5bfc597d04d4ec0ad3d2ef46649b5e9a340e37/tokenizers-0.20.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:a4c186bb006ccbe1f5cc4e0380d1ce7806f5955c244074fd96abc55e27b77f01", size = 9303950 }, - { url = "https://files.pythonhosted.org/packages/66/11/79d91aeb2817ad1993ef61c690afe73e6dbedbfb21918b302ef5a2ba9bfb/tokenizers-0.20.3-cp313-none-win32.whl", hash = "sha256:6e19e0f1d854d6ab7ea0c743d06e764d1d9a546932be0a67f33087645f00fe13", size = 2188941 }, - { url = "https://files.pythonhosted.org/packages/c2/ff/ac8410f868fb8b14b5e619efa304aa119cb8a40bd7df29fc81a898e64f99/tokenizers-0.20.3-cp313-none-win_amd64.whl", hash = "sha256:d50ede425c7e60966a9680d41b58b3a0950afa1bb570488e2972fa61662c4273", size = 2380269 }, - { url = "https://files.pythonhosted.org/packages/29/cd/ff1586dd572aaf1637d59968df3f6f6532fa255f4638fbc29f6d27e0b690/tokenizers-0.20.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e919f2e3e68bb51dc31de4fcbbeff3bdf9c1cad489044c75e2b982a91059bd3c", size = 2672044 }, - { url = "https://files.pythonhosted.org/packages/b5/9e/7a2c00abbc8edb021ee0b1f12aab76a7b7824b49f94bcd9f075d0818d4b0/tokenizers-0.20.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b8e9608f2773996cc272156e305bd79066163a66b0390fe21750aff62df1ac07", size = 2558841 }, - { url = "https://files.pythonhosted.org/packages/8e/c1/6af62ef61316f33ecf785bbb2bee4292f34ea62b491d4480ad9b09acf6b6/tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39270a7050deaf50f7caff4c532c01b3c48f6608d42b3eacdebdc6795478c8df", size = 2897936 }, - { url = "https://files.pythonhosted.org/packages/9a/0b/c076b2ff3ee6dc70c805181fbe325668b89cfee856f8dfa24cc9aa293c84/tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e005466632b1c5d2d2120f6de8aa768cc9d36cd1ab7d51d0c27a114c91a1e6ee", size = 3082688 }, - { url = "https://files.pythonhosted.org/packages/0a/60/56510124933136c2e90879e1c81603cfa753ae5a87830e3ef95056b20d8f/tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a07962340b36189b6c8feda552ea1bfeee6cf067ff922a1d7760662c2ee229e5", size = 2998924 }, - { url = "https://files.pythonhosted.org/packages/68/60/4107b618b7b9155cb34ad2e0fc90946b7e71f041b642122fb6314f660688/tokenizers-0.20.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:55046ad3dd5f2b3c67501fcc8c9cbe3e901d8355f08a3b745e9b57894855f85b", size = 8989514 }, - { url = "https://files.pythonhosted.org/packages/e8/bd/48475818e614b73316baf37ac1e4e51b578bbdf58651812d7e55f43b88d8/tokenizers-0.20.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:efcf0eb939988b627558aaf2b9dc3e56d759cad2e0cfa04fcab378e4b48fc4fd", size = 9303476 }, +sdist = { url = "https://files.pythonhosted.org/packages/da/25/b1681c1c30ea3ea6e584ae3fffd552430b12faa599b558c4c4783f56d7ff/tokenizers-0.20.3.tar.gz", hash = "sha256:2278b34c5d0dd78e087e1ca7f9b1dcbf129d80211afa645f214bd6e051037539", size = 340513, upload-time = "2024-11-05T17:34:10.403Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/51/421bb0052fc4333f7c1e3231d8c6607552933d919b628c8fabd06f60ba1e/tokenizers-0.20.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:31ccab28dbb1a9fe539787210b0026e22debeab1662970f61c2d921f7557f7e4", size = 2674308, upload-time = "2024-11-05T17:30:25.423Z" }, + { url = "https://files.pythonhosted.org/packages/a6/e9/f651f8d27614fd59af387f4dfa568b55207e5fac8d06eec106dc00b921c4/tokenizers-0.20.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6361191f762bda98c773da418cf511cbaa0cb8d0a1196f16f8c0119bde68ff8", size = 2559363, upload-time = "2024-11-05T17:30:28.841Z" }, + { url = "https://files.pythonhosted.org/packages/e3/e8/0e9f81a09ab79f409eabfd99391ca519e315496694671bebca24c3e90448/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f128d5da1202b78fa0a10d8d938610472487da01b57098d48f7e944384362514", size = 2892896, upload-time = "2024-11-05T17:30:30.429Z" }, + { url = "https://files.pythonhosted.org/packages/b0/72/15fdbc149e05005e99431ecd471807db2241983deafe1e704020f608f40e/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79c4121a2e9433ad7ef0769b9ca1f7dd7fa4c0cd501763d0a030afcbc6384481", size = 2802785, upload-time = "2024-11-05T17:30:32.045Z" }, + { url = "https://files.pythonhosted.org/packages/26/44/1f8aea48f9bb117d966b7272484671b33a509f6217a8e8544d79442c90db/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7850fde24197fe5cd6556e2fdba53a6d3bae67c531ea33a3d7c420b90904141", size = 3086060, upload-time = "2024-11-05T17:30:34.11Z" }, + { url = "https://files.pythonhosted.org/packages/2e/83/82ba40da99870b3a0b801cffaf4f099f088a84c7e07d32cc6ca751ce08e6/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b357970c095dc134978a68c67d845a1e3803ab7c4fbb39195bde914e7e13cf8b", size = 3096760, upload-time = "2024-11-05T17:30:36.276Z" }, + { url = "https://files.pythonhosted.org/packages/f3/46/7a025404201d937f86548928616c0a164308aa3998e546efdf798bf5ee9c/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a333d878c4970b72d6c07848b90c05f6b045cf9273fc2bc04a27211721ad6118", size = 3380165, upload-time = "2024-11-05T17:30:37.642Z" }, + { url = "https://files.pythonhosted.org/packages/aa/49/15fae66ac62e49255eeedbb7f4127564b2c3f3aef2009913f525732d1a08/tokenizers-0.20.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd9fee817f655a8f50049f685e224828abfadd436b8ff67979fc1d054b435f1", size = 2994038, upload-time = "2024-11-05T17:30:40.075Z" }, + { url = "https://files.pythonhosted.org/packages/f4/64/693afc9ba2393c2eed85c02bacb44762f06a29f0d1a5591fa5b40b39c0a2/tokenizers-0.20.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e7816808b402129393a435ea2a509679b41246175d6e5e9f25b8692bfaa272b", size = 8977285, upload-time = "2024-11-05T17:30:42.095Z" }, + { url = "https://files.pythonhosted.org/packages/be/7e/6126c18694310fe07970717929e889898767c41fbdd95b9078e8aec0f9ef/tokenizers-0.20.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba96367db9d8a730d3a1d5996b4b7babb846c3994b8ef14008cd8660f55db59d", size = 9294890, upload-time = "2024-11-05T17:30:44.563Z" }, + { url = "https://files.pythonhosted.org/packages/71/7d/5e3307a1091c8608a1e58043dff49521bc19553c6e9548c7fac6840cc2c4/tokenizers-0.20.3-cp310-none-win32.whl", hash = "sha256:ee31ba9d7df6a98619426283e80c6359f167e2e9882d9ce1b0254937dbd32f3f", size = 2196883, upload-time = "2024-11-05T17:30:46.792Z" }, + { url = "https://files.pythonhosted.org/packages/47/62/aaf5b2a526b3b10c20985d9568ff8c8f27159345eaef3347831e78cd5894/tokenizers-0.20.3-cp310-none-win_amd64.whl", hash = "sha256:a845c08fdad554fe0871d1255df85772f91236e5fd6b9287ef8b64f5807dbd0c", size = 2381637, upload-time = "2024-11-05T17:30:48.156Z" }, + { url = "https://files.pythonhosted.org/packages/c6/93/6742ef9206409d5ce1fdf44d5ca1687cdc3847ba0485424e2c731e6bcf67/tokenizers-0.20.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:585b51e06ca1f4839ce7759941e66766d7b060dccfdc57c4ca1e5b9a33013a90", size = 2674224, upload-time = "2024-11-05T17:30:49.972Z" }, + { url = "https://files.pythonhosted.org/packages/aa/14/e75ece72e99f6ef9ae07777ca9fdd78608f69466a5cecf636e9bd2f25d5c/tokenizers-0.20.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:61cbf11954f3b481d08723ebd048ba4b11e582986f9be74d2c3bdd9293a4538d", size = 2558991, upload-time = "2024-11-05T17:30:51.666Z" }, + { url = "https://files.pythonhosted.org/packages/46/54/033b5b2ba0c3ae01e026c6f7ced147d41a2fa1c573d00a66cb97f6d7f9b3/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef820880d5e4e8484e2fa54ff8d297bb32519eaa7815694dc835ace9130a3eea", size = 2892476, upload-time = "2024-11-05T17:30:53.505Z" }, + { url = "https://files.pythonhosted.org/packages/e6/b0/cc369fb3297d61f3311cab523d16d48c869dc2f0ba32985dbf03ff811041/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:67ef4dcb8841a4988cd00dd288fb95dfc8e22ed021f01f37348fd51c2b055ba9", size = 2802775, upload-time = "2024-11-05T17:30:55.229Z" }, + { url = "https://files.pythonhosted.org/packages/1a/74/62ad983e8ea6a63e04ed9c5be0b605056bf8aac2f0125f9b5e0b3e2b89fa/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff1ef8bd47a02b0dc191688ccb4da53600df5d4c9a05a4b68e1e3de4823e78eb", size = 3086138, upload-time = "2024-11-05T17:30:57.332Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ac/4637ba619db25094998523f9e6f5b456e1db1f8faa770a3d925d436db0c3/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:444d188186eab3148baf0615b522461b41b1f0cd58cd57b862ec94b6ac9780f1", size = 3098076, upload-time = "2024-11-05T17:30:59.455Z" }, + { url = "https://files.pythonhosted.org/packages/58/ce/9793f2dc2ce529369807c9c74e42722b05034af411d60f5730b720388c7d/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37c04c032c1442740b2c2d925f1857885c07619224a533123ac7ea71ca5713da", size = 3379650, upload-time = "2024-11-05T17:31:01.264Z" }, + { url = "https://files.pythonhosted.org/packages/50/f6/2841de926bc4118af996eaf0bdf0ea5b012245044766ffc0347e6c968e63/tokenizers-0.20.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:453c7769d22231960ee0e883d1005c93c68015025a5e4ae56275406d94a3c907", size = 2994005, upload-time = "2024-11-05T17:31:02.985Z" }, + { url = "https://files.pythonhosted.org/packages/a3/b2/00915c4fed08e9505d37cf6eaab45b12b4bff8f6719d459abcb9ead86a4b/tokenizers-0.20.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4bb31f7b2847e439766aaa9cc7bccf7ac7088052deccdb2275c952d96f691c6a", size = 8977488, upload-time = "2024-11-05T17:31:04.424Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ac/1c069e7808181ff57bcf2d39e9b6fbee9133a55410e6ebdaa89f67c32e83/tokenizers-0.20.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:843729bf0f991b29655a069a2ff58a4c24375a553c70955e15e37a90dd4e045c", size = 9294935, upload-time = "2024-11-05T17:31:06.882Z" }, + { url = "https://files.pythonhosted.org/packages/50/47/722feb70ee68d1c4412b12d0ea4acc2713179fd63f054913990f9e259492/tokenizers-0.20.3-cp311-none-win32.whl", hash = "sha256:efcce3a927b1e20ca694ba13f7a68c59b0bd859ef71e441db68ee42cf20c2442", size = 2197175, upload-time = "2024-11-05T17:31:09.385Z" }, + { url = "https://files.pythonhosted.org/packages/75/68/1b4f928b15a36ed278332ac75d66d7eb65d865bf344d049c452c18447bf9/tokenizers-0.20.3-cp311-none-win_amd64.whl", hash = "sha256:88301aa0801f225725b6df5dea3d77c80365ff2362ca7e252583f2b4809c4cc0", size = 2381616, upload-time = "2024-11-05T17:31:10.685Z" }, + { url = "https://files.pythonhosted.org/packages/07/00/92a08af2a6b0c88c50f1ab47d7189e695722ad9714b0ee78ea5e1e2e1def/tokenizers-0.20.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:49d12a32e190fad0e79e5bdb788d05da2f20d8e006b13a70859ac47fecf6ab2f", size = 2667951, upload-time = "2024-11-05T17:31:12.356Z" }, + { url = "https://files.pythonhosted.org/packages/ec/9a/e17a352f0bffbf415cf7d73756f5c73a3219225fc5957bc2f39d52c61684/tokenizers-0.20.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:282848cacfb9c06d5e51489f38ec5aa0b3cd1e247a023061945f71f41d949d73", size = 2555167, upload-time = "2024-11-05T17:31:13.839Z" }, + { url = "https://files.pythonhosted.org/packages/27/37/d108df55daf4f0fcf1f58554692ff71687c273d870a34693066f0847be96/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abe4e08c7d0cd6154c795deb5bf81d2122f36daf075e0c12a8b050d824ef0a64", size = 2898389, upload-time = "2024-11-05T17:31:15.12Z" }, + { url = "https://files.pythonhosted.org/packages/b2/27/32f29da16d28f59472fa7fb38e7782069748c7e9ab9854522db20341624c/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ca94fc1b73b3883c98f0c88c77700b13d55b49f1071dfd57df2b06f3ff7afd64", size = 2795866, upload-time = "2024-11-05T17:31:16.857Z" }, + { url = "https://files.pythonhosted.org/packages/29/4e/8a9a3c89e128c4a40f247b501c10279d2d7ade685953407c4d94c8c0f7a7/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef279c7e239f95c8bdd6ff319d9870f30f0d24915b04895f55b1adcf96d6c60d", size = 3085446, upload-time = "2024-11-05T17:31:18.392Z" }, + { url = "https://files.pythonhosted.org/packages/b4/3b/a2a7962c496ebcd95860ca99e423254f760f382cd4bd376f8895783afaf5/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16384073973f6ccbde9852157a4fdfe632bb65208139c9d0c0bd0176a71fd67f", size = 3094378, upload-time = "2024-11-05T17:31:20.329Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f4/a8a33f0192a1629a3bd0afcad17d4d221bbf9276da4b95d226364208d5eb/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:312d522caeb8a1a42ebdec87118d99b22667782b67898a76c963c058a7e41d4f", size = 3385755, upload-time = "2024-11-05T17:31:21.778Z" }, + { url = "https://files.pythonhosted.org/packages/9e/65/c83cb3545a65a9eaa2e13b22c93d5e00bd7624b354a44adbdc93d5d9bd91/tokenizers-0.20.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2b7cb962564785a83dafbba0144ecb7f579f1d57d8c406cdaa7f32fe32f18ad", size = 2997679, upload-time = "2024-11-05T17:31:23.134Z" }, + { url = "https://files.pythonhosted.org/packages/55/e9/a80d4e592307688a67c7c59ab77e03687b6a8bd92eb5db763a2c80f93f57/tokenizers-0.20.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:124c5882ebb88dadae1fc788a582299fcd3a8bd84fc3e260b9918cf28b8751f5", size = 8989296, upload-time = "2024-11-05T17:31:24.953Z" }, + { url = "https://files.pythonhosted.org/packages/90/af/60c957af8d2244321124e893828f1a4817cde1a2d08d09d423b73f19bd2f/tokenizers-0.20.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2b6e54e71f84c4202111a489879005cb14b92616a87417f6c102c833af961ea2", size = 9303621, upload-time = "2024-11-05T17:31:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/be/a9/96172310ee141009646d63a1ca267c099c462d747fe5ef7e33f74e27a683/tokenizers-0.20.3-cp312-none-win32.whl", hash = "sha256:83d9bfbe9af86f2d9df4833c22e94d94750f1d0cd9bfb22a7bb90a86f61cdb1c", size = 2188979, upload-time = "2024-11-05T17:31:29.483Z" }, + { url = "https://files.pythonhosted.org/packages/bd/68/61d85ae7ae96dde7d0974ff3538db75d5cdc29be2e4329cd7fc51a283e22/tokenizers-0.20.3-cp312-none-win_amd64.whl", hash = "sha256:44def74cee574d609a36e17c8914311d1b5dbcfe37c55fd29369d42591b91cf2", size = 2380725, upload-time = "2024-11-05T17:31:31.315Z" }, + { url = "https://files.pythonhosted.org/packages/07/19/36e9eaafb229616cb8502b42030fa7fe347550e76cb618de71b498fc3222/tokenizers-0.20.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e0b630e0b536ef0e3c8b42c685c1bc93bd19e98c0f1543db52911f8ede42cf84", size = 2666813, upload-time = "2024-11-05T17:31:32.783Z" }, + { url = "https://files.pythonhosted.org/packages/b9/c7/e2ce1d4f756c8a62ef93fdb4df877c2185339b6d63667b015bf70ea9d34b/tokenizers-0.20.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a02d160d2b19bcbfdf28bd9a4bf11be4cb97d0499c000d95d4c4b1a4312740b6", size = 2555354, upload-time = "2024-11-05T17:31:34.208Z" }, + { url = "https://files.pythonhosted.org/packages/7c/cf/5309c2d173a6a67f9ec8697d8e710ea32418de6fd8541778032c202a1c3e/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e3d80d89b068bc30034034b5319218c7c0a91b00af19679833f55f3becb6945", size = 2897745, upload-time = "2024-11-05T17:31:35.733Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e5/af3078e32f225e680e69d61f78855880edb8d53f5850a1834d519b2b103f/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:174a54910bed1b089226512b4458ea60d6d6fd93060254734d3bc3540953c51c", size = 2794385, upload-time = "2024-11-05T17:31:37.497Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a7/bc421fe46650cc4eb4a913a236b88c243204f32c7480684d2f138925899e/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:098b8a632b8656aa5802c46689462c5c48f02510f24029d71c208ec2c822e771", size = 3084580, upload-time = "2024-11-05T17:31:39.456Z" }, + { url = "https://files.pythonhosted.org/packages/c6/22/97e1e95ee81f75922c9f569c23cb2b1fdc7f5a7a29c4c9fae17e63f751a6/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:78c8c143e3ae41e718588281eb3e212c2b31623c9d6d40410ec464d7d6221fb5", size = 3093581, upload-time = "2024-11-05T17:31:41.224Z" }, + { url = "https://files.pythonhosted.org/packages/d5/14/f0df0ee3b9e516121e23c0099bccd7b9f086ba9150021a750e99b16ce56f/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b26b0aadb18cd8701077362ba359a06683662d5cafe3e8e8aba10eb05c037f1", size = 3385934, upload-time = "2024-11-05T17:31:43.811Z" }, + { url = "https://files.pythonhosted.org/packages/66/52/7a171bd4929e3ffe61a29b4340fe5b73484709f92a8162a18946e124c34c/tokenizers-0.20.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07d7851a72717321022f3774e84aa9d595a041d643fafa2e87fbc9b18711dac0", size = 2997311, upload-time = "2024-11-05T17:31:46.224Z" }, + { url = "https://files.pythonhosted.org/packages/7c/64/f1993bb8ebf775d56875ca0d50a50f2648bfbbb143da92fe2e6ceeb4abd5/tokenizers-0.20.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:bd44e48a430ada902c6266a8245f5036c4fe744fcb51f699999fbe82aa438797", size = 8988601, upload-time = "2024-11-05T17:31:47.907Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3f/49fa63422159bbc2f2a4ac5bfc597d04d4ec0ad3d2ef46649b5e9a340e37/tokenizers-0.20.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:a4c186bb006ccbe1f5cc4e0380d1ce7806f5955c244074fd96abc55e27b77f01", size = 9303950, upload-time = "2024-11-05T17:31:50.674Z" }, + { url = "https://files.pythonhosted.org/packages/66/11/79d91aeb2817ad1993ef61c690afe73e6dbedbfb21918b302ef5a2ba9bfb/tokenizers-0.20.3-cp313-none-win32.whl", hash = "sha256:6e19e0f1d854d6ab7ea0c743d06e764d1d9a546932be0a67f33087645f00fe13", size = 2188941, upload-time = "2024-11-05T17:31:53.334Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ff/ac8410f868fb8b14b5e619efa304aa119cb8a40bd7df29fc81a898e64f99/tokenizers-0.20.3-cp313-none-win_amd64.whl", hash = "sha256:d50ede425c7e60966a9680d41b58b3a0950afa1bb570488e2972fa61662c4273", size = 2380269, upload-time = "2024-11-05T17:31:54.796Z" }, + { url = "https://files.pythonhosted.org/packages/29/cd/ff1586dd572aaf1637d59968df3f6f6532fa255f4638fbc29f6d27e0b690/tokenizers-0.20.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e919f2e3e68bb51dc31de4fcbbeff3bdf9c1cad489044c75e2b982a91059bd3c", size = 2672044, upload-time = "2024-11-05T17:33:07.796Z" }, + { url = "https://files.pythonhosted.org/packages/b5/9e/7a2c00abbc8edb021ee0b1f12aab76a7b7824b49f94bcd9f075d0818d4b0/tokenizers-0.20.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b8e9608f2773996cc272156e305bd79066163a66b0390fe21750aff62df1ac07", size = 2558841, upload-time = "2024-11-05T17:33:09.542Z" }, + { url = "https://files.pythonhosted.org/packages/8e/c1/6af62ef61316f33ecf785bbb2bee4292f34ea62b491d4480ad9b09acf6b6/tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39270a7050deaf50f7caff4c532c01b3c48f6608d42b3eacdebdc6795478c8df", size = 2897936, upload-time = "2024-11-05T17:33:11.413Z" }, + { url = "https://files.pythonhosted.org/packages/9a/0b/c076b2ff3ee6dc70c805181fbe325668b89cfee856f8dfa24cc9aa293c84/tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e005466632b1c5d2d2120f6de8aa768cc9d36cd1ab7d51d0c27a114c91a1e6ee", size = 3082688, upload-time = "2024-11-05T17:33:13.538Z" }, + { url = "https://files.pythonhosted.org/packages/0a/60/56510124933136c2e90879e1c81603cfa753ae5a87830e3ef95056b20d8f/tokenizers-0.20.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a07962340b36189b6c8feda552ea1bfeee6cf067ff922a1d7760662c2ee229e5", size = 2998924, upload-time = "2024-11-05T17:33:16.249Z" }, + { url = "https://files.pythonhosted.org/packages/68/60/4107b618b7b9155cb34ad2e0fc90946b7e71f041b642122fb6314f660688/tokenizers-0.20.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:55046ad3dd5f2b3c67501fcc8c9cbe3e901d8355f08a3b745e9b57894855f85b", size = 8989514, upload-time = "2024-11-05T17:33:18.161Z" }, + { url = "https://files.pythonhosted.org/packages/e8/bd/48475818e614b73316baf37ac1e4e51b578bbdf58651812d7e55f43b88d8/tokenizers-0.20.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:efcf0eb939988b627558aaf2b9dc3e56d759cad2e0cfa04fcab378e4b48fc4fd", size = 9303476, upload-time = "2024-11-05T17:33:21.251Z" }, ] [[package]] name = "tomli" version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, - { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, - { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, - { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, - { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, - { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, - { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, - { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, - { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, - { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, - { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, - { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, - { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, - { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, - { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, - { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, - { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, - { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, - { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, - { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, - { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, - { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, - { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, - { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, - { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, - { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, - { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, - { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, - { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, - { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, - { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, ] [[package]] name = "tomli-w" version = "1.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184 } +sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184, upload-time = "2025-01-15T12:07:24.262Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675 }, + { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" }, ] [[package]] @@ -4376,18 +4471,18 @@ 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 } +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 }, + { 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 = "traitlets" version = "5.14.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621 } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359 }, + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, ] [[package]] @@ -4403,9 +4498,9 @@ dependencies = [ { name = "sniffio" }, { name = "sortedcontainers" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/01/c1/68d582b4d3a1c1f8118e18042464bb12a7c1b75d64d75111b297687041e3/trio-0.30.0.tar.gz", hash = "sha256:0781c857c0c81f8f51e0089929a26b5bb63d57f927728a5586f7e36171f064df", size = 593776 } +sdist = { url = "https://files.pythonhosted.org/packages/01/c1/68d582b4d3a1c1f8118e18042464bb12a7c1b75d64d75111b297687041e3/trio-0.30.0.tar.gz", hash = "sha256:0781c857c0c81f8f51e0089929a26b5bb63d57f927728a5586f7e36171f064df", size = 593776, upload-time = "2025-04-21T00:48:19.507Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/8e/3f6dfda475ecd940e786defe6df6c500734e686c9cd0a0f8ef6821e9b2f2/trio-0.30.0-py3-none-any.whl", hash = "sha256:3bf4f06b8decf8d3cf00af85f40a89824669e2d033bb32469d34840edcfc22a5", size = 499194 }, + { url = "https://files.pythonhosted.org/packages/69/8e/3f6dfda475ecd940e786defe6df6c500734e686c9cd0a0f8ef6821e9b2f2/trio-0.30.0-py3-none-any.whl", hash = "sha256:3bf4f06b8decf8d3cf00af85f40a89824669e2d033bb32469d34840edcfc22a5", size = 499194, upload-time = "2025-04-21T00:48:17.167Z" }, ] [[package]] @@ -4418,27 +4513,27 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6c/89/c527e6c848739be8ceb5c44eb8208c52ea3515c6cf6406aa61932887bf58/typer-0.15.4.tar.gz", hash = "sha256:89507b104f9b6a0730354f27c39fae5b63ccd0c95b1ce1f1a6ba0cfd329997c3", size = 101559 } +sdist = { url = "https://files.pythonhosted.org/packages/6c/89/c527e6c848739be8ceb5c44eb8208c52ea3515c6cf6406aa61932887bf58/typer-0.15.4.tar.gz", hash = "sha256:89507b104f9b6a0730354f27c39fae5b63ccd0c95b1ce1f1a6ba0cfd329997c3", size = 101559, upload-time = "2025-05-14T16:34:57.704Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/62/d4ba7afe2096d5659ec3db8b15d8665bdcb92a3c6ff0b95e99895b335a9c/typer-0.15.4-py3-none-any.whl", hash = "sha256:eb0651654dcdea706780c466cf06d8f174405a659ffff8f163cfbfee98c0e173", size = 45258 }, + { url = "https://files.pythonhosted.org/packages/c9/62/d4ba7afe2096d5659ec3db8b15d8665bdcb92a3c6ff0b95e99895b335a9c/typer-0.15.4-py3-none-any.whl", hash = "sha256:eb0651654dcdea706780c466cf06d8f174405a659ffff8f163cfbfee98c0e173", size = 45258, upload-time = "2025-05-14T16:34:55.583Z" }, ] [[package]] name = "types-awscrt" version = "0.27.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/36/6c/583522cfb3c330e92e726af517a91c13247e555e021791a60f1b03c6ff16/types_awscrt-0.27.2.tar.gz", hash = "sha256:acd04f57119eb15626ab0ba9157fc24672421de56e7bd7b9f61681fedee44e91", size = 16304 } +sdist = { url = "https://files.pythonhosted.org/packages/36/6c/583522cfb3c330e92e726af517a91c13247e555e021791a60f1b03c6ff16/types_awscrt-0.27.2.tar.gz", hash = "sha256:acd04f57119eb15626ab0ba9157fc24672421de56e7bd7b9f61681fedee44e91", size = 16304, upload-time = "2025-05-16T03:10:08.712Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/82/1ee2e5c9d28deac086ab3a6ff07c8bc393ef013a083f546c623699881715/types_awscrt-0.27.2-py3-none-any.whl", hash = "sha256:49a045f25bbd5ad2865f314512afced933aed35ddbafc252e2268efa8a787e4e", size = 37761 }, + { url = "https://files.pythonhosted.org/packages/4c/82/1ee2e5c9d28deac086ab3a6ff07c8bc393ef013a083f546c623699881715/types_awscrt-0.27.2-py3-none-any.whl", hash = "sha256:49a045f25bbd5ad2865f314512afced933aed35ddbafc252e2268efa8a787e4e", size = 37761, upload-time = "2025-05-16T03:10:07.466Z" }, ] [[package]] name = "types-protobuf" version = "6.30.2.20250516" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ac/6c/5cf088aaa3927d1cc39910f60f220f5ff573ab1a6485b2836e8b26beb58c/types_protobuf-6.30.2.20250516.tar.gz", hash = "sha256:aecd1881770a9bb225ede66872ef7f0da4505edd0b193108edd9892e48d49a41", size = 62254 } +sdist = { url = "https://files.pythonhosted.org/packages/ac/6c/5cf088aaa3927d1cc39910f60f220f5ff573ab1a6485b2836e8b26beb58c/types_protobuf-6.30.2.20250516.tar.gz", hash = "sha256:aecd1881770a9bb225ede66872ef7f0da4505edd0b193108edd9892e48d49a41", size = 62254, upload-time = "2025-05-16T03:06:50.794Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/66/06a9c161f5dd5deb4f5c016ba29106a8f1903eb9a1ba77d407dd6588fecb/types_protobuf-6.30.2.20250516-py3-none-any.whl", hash = "sha256:8c226d05b5e8b2623111765fa32d6e648bbc24832b4c2fddf0fa340ba5d5b722", size = 76480 }, + { url = "https://files.pythonhosted.org/packages/c0/66/06a9c161f5dd5deb4f5c016ba29106a8f1903eb9a1ba77d407dd6588fecb/types_protobuf-6.30.2.20250516-py3-none-any.whl", hash = "sha256:8c226d05b5e8b2623111765fa32d6e648bbc24832b4c2fddf0fa340ba5d5b722", size = 76480, upload-time = "2025-05-16T03:06:49.444Z" }, ] [[package]] @@ -4448,27 +4543,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/c1/cdc4f9b8cfd9130fbe6276db574f114541f4231fcc6fb29648289e6e3390/types_requests-2.32.0.20250515.tar.gz", hash = "sha256:09c8b63c11318cb2460813871aaa48b671002e59fda67ca909e9883777787581", size = 23012 } +sdist = { url = "https://files.pythonhosted.org/packages/06/c1/cdc4f9b8cfd9130fbe6276db574f114541f4231fcc6fb29648289e6e3390/types_requests-2.32.0.20250515.tar.gz", hash = "sha256:09c8b63c11318cb2460813871aaa48b671002e59fda67ca909e9883777787581", size = 23012, upload-time = "2025-05-15T03:04:31.817Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/0f/68a997c73a129287785f418c1ebb6004f81e46b53b3caba88c0e03fcd04a/types_requests-2.32.0.20250515-py3-none-any.whl", hash = "sha256:f8eba93b3a892beee32643ff836993f15a785816acca21ea0ffa006f05ef0fb2", size = 20635 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/68a997c73a129287785f418c1ebb6004f81e46b53b3caba88c0e03fcd04a/types_requests-2.32.0.20250515-py3-none-any.whl", hash = "sha256:f8eba93b3a892beee32643ff836993f15a785816acca21ea0ffa006f05ef0fb2", size = 20635, upload-time = "2025-05-15T03:04:30.5Z" }, ] [[package]] name = "types-s3transfer" version = "0.12.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fb/d5/830e9efe91a26601a2bebde6f299239d2d26e542f5d4b3bc7e8c23c81a3f/types_s3transfer-0.12.0.tar.gz", hash = "sha256:f8f59201481e904362873bf0be3267f259d60ad946ebdfcb847d092a1fa26f98", size = 14096 } +sdist = { url = "https://files.pythonhosted.org/packages/fb/d5/830e9efe91a26601a2bebde6f299239d2d26e542f5d4b3bc7e8c23c81a3f/types_s3transfer-0.12.0.tar.gz", hash = "sha256:f8f59201481e904362873bf0be3267f259d60ad946ebdfcb847d092a1fa26f98", size = 14096, upload-time = "2025-04-23T00:38:19.131Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/43/6097275152463ac9bacf1e00aab30bc6682bf45f6a031be8bf029c030ba2/types_s3transfer-0.12.0-py3-none-any.whl", hash = "sha256:101bbc5b7f00b71512374df881f480fc6bf63c948b5098ab024bf3370fbfb0e8", size = 19553 }, + { url = "https://files.pythonhosted.org/packages/fc/43/6097275152463ac9bacf1e00aab30bc6682bf45f6a031be8bf029c030ba2/types_s3transfer-0.12.0-py3-none-any.whl", hash = "sha256:101bbc5b7f00b71512374df881f480fc6bf63c948b5098ab024bf3370fbfb0e8", size = 19553, upload-time = "2025-04-23T00:38:17.865Z" }, ] [[package]] name = "typing-extensions" version = "4.13.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967 } +sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806 }, + { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, ] [[package]] @@ -4478,43 +4573,43 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726 } +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552 }, + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] [[package]] name = "urllib3" version = "2.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672 } +sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 }, + { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, ] [[package]] name = "uv" version = "0.7.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/67/35/360a4aa325254b7f11d0898d30588861428659011b34f1e19c40fdd15db6/uv-0.7.12.tar.gz", hash = "sha256:4aa152e6a70d5662ca66a918f697bf8fb710f391068aa7d04e032af2edebb095", size = 3298683 } +sdist = { url = "https://files.pythonhosted.org/packages/67/35/360a4aa325254b7f11d0898d30588861428659011b34f1e19c40fdd15db6/uv-0.7.12.tar.gz", hash = "sha256:4aa152e6a70d5662ca66a918f697bf8fb710f391068aa7d04e032af2edebb095", size = 3298683, upload-time = "2025-06-06T20:39:04.308Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/64/ee9f1b27f006c49a6765e9655ab93e7c8cbd6f0bf8b731f30f608b0be9fd/uv-0.7.12-py3-none-linux_armv6l.whl", hash = "sha256:81824caf5756ffee54b4c937d92d7c8c224c416270c90a83b9b4a973f6e4e559", size = 17024991 }, - { url = "https://files.pythonhosted.org/packages/43/aa/f42707faa13a9c1b4f662456b2dca4bde169eb921f135319d8856c6e5e8e/uv-0.7.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:02e67c5f9d141fb25976cddb28abceaf715412ed83070cb9b87c5c488c8451af", size = 17097383 }, - { url = "https://files.pythonhosted.org/packages/b9/a9/0f27e16e161f98240a328b5201b8abf178b751fde4fc56c54c1321812cd5/uv-0.7.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e70a4393fd6a09b056e1ac500fe2b796d26c30783194868c6801ea08c3bbf863", size = 15812649 }, - { url = "https://files.pythonhosted.org/packages/0b/eb/605d8f1d08606024209d0e31c3799c696199a887260ee1db52663e4da2e8/uv-0.7.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:bb47326b9c4802db28e11f1aab174d5c9c0a8b26ed0a83094d3882dd8f5049ad", size = 16344497 }, - { url = "https://files.pythonhosted.org/packages/b7/86/3503eb869fa17d607cc296a6514db52ec73c2ec85ad608952a207fd2e8ff/uv-0.7.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14214a51e0ae0f0e8dbcac35a29722c45dbf40d0fd37309897642f7989af6caf", size = 16773525 }, - { url = "https://files.pythonhosted.org/packages/9b/d6/868fb3f0b9f2a0d2f14cb8079171b862adbd782e47e0469dad3d3d71c938/uv-0.7.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fa630d865111c26f26c5e6f4547a73b13284f098471a4ca982d7b0caf0e658b", size = 17551173 }, - { url = "https://files.pythonhosted.org/packages/d4/a8/b5be1c67c7894caf178e850903ac25f465e3508a6eada2ae735b187dc39d/uv-0.7.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1557a154d2c36030ff0b707f3c2bfafd977e54fcd4d628dd0fa8a265449e9f13", size = 18359491 }, - { url = "https://files.pythonhosted.org/packages/95/23/f62bab13f67ed785f7ad01546c499809d1db71b03f94950380f0bc407625/uv-0.7.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e0ba7767b21d58d65703c3cd43814ccfe06d7664ac42b3589d5f2b72486b903", size = 18098855 }, - { url = "https://files.pythonhosted.org/packages/a6/4a/db21a5d3839771799af2df366cc5ed0933ebe9fc9e920f212e33dc00136e/uv-0.7.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0672dc5dc1b0ae7191d11ecae8bb794c7e860936b66c2bc3855bd0dee17fca1", size = 18206282 }, - { url = "https://files.pythonhosted.org/packages/bc/ae/fcfd916cbc109c5626dc25b208395b47ba12b27af82f3bb8e247b4e95692/uv-0.7.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e34b4ad4288828210c2e075934009903514ca97bd603aced7d0755040b4d0489", size = 17777690 }, - { url = "https://files.pythonhosted.org/packages/92/78/608163b35ffaf1054cd10197646b6336e7be7b6a51dfef6d98a91600c6be/uv-0.7.12-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:8a7ed9e94ec409bfc7181ee274d1b0ed6292698a20df0ae035ce422224863af5", size = 16599406 }, - { url = "https://files.pythonhosted.org/packages/d4/d6/6fe3b16390472a9d31dd1e0e7e3759b884d71e8a0dff1baf4a753b4adaaa/uv-0.7.12-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:85e8d3dea95016a45ed8c48343f98734d1b5c4be7bba26257d4c8873059646fa", size = 16714823 }, - { url = "https://files.pythonhosted.org/packages/b3/a5/b0432a25eaa23e9f909649321784b8e4be4579e9957eb5d369aa30c79164/uv-0.7.12-py3-none-musllinux_1_1_i686.whl", hash = "sha256:01310c45d55f6e7580124c9b1f7e3586b9609c4f8e5a78558a75951b03541bb2", size = 17086446 }, - { url = "https://files.pythonhosted.org/packages/da/d8/673591f34f897aa4216144a513e60c2004399155c47e7b550612960359c6/uv-0.7.12-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:4c697ef9d9f6b6f42df5a661efa8a745c0e4c330039d45b549b2ca7e7b66f8a5", size = 17903789 }, - { url = "https://files.pythonhosted.org/packages/15/09/e476187c0a1da78b9c2021f3c3ab31ed2469a70d222bde5dc892236b3c4f/uv-0.7.12-py3-none-win32.whl", hash = "sha256:6008abf92c8d37060944377d89bf9f514aa18370391d9d63dc7d449dac94aca1", size = 17344011 }, - { url = "https://files.pythonhosted.org/packages/08/9e/c52c7f50280e57110ca79b6805877f50514d9a777d31a683a4eb1de52312/uv-0.7.12-py3-none-win_amd64.whl", hash = "sha256:bb57bd26becd86194788f832af373b6ba431314fa0f6f7e904c90cac1818a7dc", size = 18803328 }, - { url = "https://files.pythonhosted.org/packages/8e/35/4800ff7bc1663d9f967eabc8440074f906c8a98ea28d1aae66d2d19b7ae9/uv-0.7.12-py3-none-win_arm64.whl", hash = "sha256:8aba24e12ded2f2974a2f213e55daabf78002613d3772c1396fc924c6682cd27", size = 17450522 }, + { url = "https://files.pythonhosted.org/packages/f8/64/ee9f1b27f006c49a6765e9655ab93e7c8cbd6f0bf8b731f30f608b0be9fd/uv-0.7.12-py3-none-linux_armv6l.whl", hash = "sha256:81824caf5756ffee54b4c937d92d7c8c224c416270c90a83b9b4a973f6e4e559", size = 17024991, upload-time = "2025-06-06T20:38:17.053Z" }, + { url = "https://files.pythonhosted.org/packages/43/aa/f42707faa13a9c1b4f662456b2dca4bde169eb921f135319d8856c6e5e8e/uv-0.7.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:02e67c5f9d141fb25976cddb28abceaf715412ed83070cb9b87c5c488c8451af", size = 17097383, upload-time = "2025-06-06T20:38:21.174Z" }, + { url = "https://files.pythonhosted.org/packages/b9/a9/0f27e16e161f98240a328b5201b8abf178b751fde4fc56c54c1321812cd5/uv-0.7.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e70a4393fd6a09b056e1ac500fe2b796d26c30783194868c6801ea08c3bbf863", size = 15812649, upload-time = "2025-06-06T20:38:23.51Z" }, + { url = "https://files.pythonhosted.org/packages/0b/eb/605d8f1d08606024209d0e31c3799c696199a887260ee1db52663e4da2e8/uv-0.7.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:bb47326b9c4802db28e11f1aab174d5c9c0a8b26ed0a83094d3882dd8f5049ad", size = 16344497, upload-time = "2025-06-06T20:38:25.899Z" }, + { url = "https://files.pythonhosted.org/packages/b7/86/3503eb869fa17d607cc296a6514db52ec73c2ec85ad608952a207fd2e8ff/uv-0.7.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14214a51e0ae0f0e8dbcac35a29722c45dbf40d0fd37309897642f7989af6caf", size = 16773525, upload-time = "2025-06-06T20:38:28.619Z" }, + { url = "https://files.pythonhosted.org/packages/9b/d6/868fb3f0b9f2a0d2f14cb8079171b862adbd782e47e0469dad3d3d71c938/uv-0.7.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fa630d865111c26f26c5e6f4547a73b13284f098471a4ca982d7b0caf0e658b", size = 17551173, upload-time = "2025-06-06T20:38:31.166Z" }, + { url = "https://files.pythonhosted.org/packages/d4/a8/b5be1c67c7894caf178e850903ac25f465e3508a6eada2ae735b187dc39d/uv-0.7.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1557a154d2c36030ff0b707f3c2bfafd977e54fcd4d628dd0fa8a265449e9f13", size = 18359491, upload-time = "2025-06-06T20:38:33.569Z" }, + { url = "https://files.pythonhosted.org/packages/95/23/f62bab13f67ed785f7ad01546c499809d1db71b03f94950380f0bc407625/uv-0.7.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e0ba7767b21d58d65703c3cd43814ccfe06d7664ac42b3589d5f2b72486b903", size = 18098855, upload-time = "2025-06-06T20:38:36.029Z" }, + { url = "https://files.pythonhosted.org/packages/a6/4a/db21a5d3839771799af2df366cc5ed0933ebe9fc9e920f212e33dc00136e/uv-0.7.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0672dc5dc1b0ae7191d11ecae8bb794c7e860936b66c2bc3855bd0dee17fca1", size = 18206282, upload-time = "2025-06-06T20:38:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/bc/ae/fcfd916cbc109c5626dc25b208395b47ba12b27af82f3bb8e247b4e95692/uv-0.7.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e34b4ad4288828210c2e075934009903514ca97bd603aced7d0755040b4d0489", size = 17777690, upload-time = "2025-06-06T20:38:41.021Z" }, + { url = "https://files.pythonhosted.org/packages/92/78/608163b35ffaf1054cd10197646b6336e7be7b6a51dfef6d98a91600c6be/uv-0.7.12-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:8a7ed9e94ec409bfc7181ee274d1b0ed6292698a20df0ae035ce422224863af5", size = 16599406, upload-time = "2025-06-06T20:38:43.72Z" }, + { url = "https://files.pythonhosted.org/packages/d4/d6/6fe3b16390472a9d31dd1e0e7e3759b884d71e8a0dff1baf4a753b4adaaa/uv-0.7.12-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:85e8d3dea95016a45ed8c48343f98734d1b5c4be7bba26257d4c8873059646fa", size = 16714823, upload-time = "2025-06-06T20:38:45.949Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a5/b0432a25eaa23e9f909649321784b8e4be4579e9957eb5d369aa30c79164/uv-0.7.12-py3-none-musllinux_1_1_i686.whl", hash = "sha256:01310c45d55f6e7580124c9b1f7e3586b9609c4f8e5a78558a75951b03541bb2", size = 17086446, upload-time = "2025-06-06T20:38:48.648Z" }, + { url = "https://files.pythonhosted.org/packages/da/d8/673591f34f897aa4216144a513e60c2004399155c47e7b550612960359c6/uv-0.7.12-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:4c697ef9d9f6b6f42df5a661efa8a745c0e4c330039d45b549b2ca7e7b66f8a5", size = 17903789, upload-time = "2025-06-06T20:38:51.864Z" }, + { url = "https://files.pythonhosted.org/packages/15/09/e476187c0a1da78b9c2021f3c3ab31ed2469a70d222bde5dc892236b3c4f/uv-0.7.12-py3-none-win32.whl", hash = "sha256:6008abf92c8d37060944377d89bf9f514aa18370391d9d63dc7d449dac94aca1", size = 17344011, upload-time = "2025-06-06T20:38:54.276Z" }, + { url = "https://files.pythonhosted.org/packages/08/9e/c52c7f50280e57110ca79b6805877f50514d9a777d31a683a4eb1de52312/uv-0.7.12-py3-none-win_amd64.whl", hash = "sha256:bb57bd26becd86194788f832af373b6ba431314fa0f6f7e904c90cac1818a7dc", size = 18803328, upload-time = "2025-06-06T20:38:59.368Z" }, + { url = "https://files.pythonhosted.org/packages/8e/35/4800ff7bc1663d9f967eabc8440074f906c8a98ea28d1aae66d2d19b7ae9/uv-0.7.12-py3-none-win_arm64.whl", hash = "sha256:8aba24e12ded2f2974a2f213e55daabf78002613d3772c1396fc924c6682cd27", size = 17450522, upload-time = "2025-06-06T20:39:01.963Z" }, ] [[package]] @@ -4526,9 +4621,9 @@ dependencies = [ { name = "h11" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815 } +sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload-time = "2025-04-19T06:02:50.101Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483 }, + { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload-time = "2025-04-19T06:02:48.42Z" }, ] [package.optional-dependencies] @@ -4546,32 +4641,32 @@ standard = [ name = "uvloop" version = "0.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/76/44a55515e8c9505aa1420aebacf4dd82552e5e15691654894e90d0bd051a/uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f", size = 1442019 }, - { url = "https://files.pythonhosted.org/packages/35/5a/62d5800358a78cc25c8a6c72ef8b10851bdb8cca22e14d9c74167b7f86da/uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d", size = 801898 }, - { url = "https://files.pythonhosted.org/packages/f3/96/63695e0ebd7da6c741ccd4489b5947394435e198a1382349c17b1146bb97/uvloop-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26", size = 3827735 }, - { url = "https://files.pythonhosted.org/packages/61/e0/f0f8ec84979068ffae132c58c79af1de9cceeb664076beea86d941af1a30/uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb", size = 3825126 }, - { url = "https://files.pythonhosted.org/packages/bf/fe/5e94a977d058a54a19df95f12f7161ab6e323ad49f4dabc28822eb2df7ea/uvloop-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f", size = 3705789 }, - { url = "https://files.pythonhosted.org/packages/26/dd/c7179618e46092a77e036650c1f056041a028a35c4d76945089fcfc38af8/uvloop-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c", size = 3800523 }, - { url = "https://files.pythonhosted.org/packages/57/a7/4cf0334105c1160dd6819f3297f8700fda7fc30ab4f61fbf3e725acbc7cc/uvloop-0.21.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", size = 1447410 }, - { url = "https://files.pythonhosted.org/packages/8c/7c/1517b0bbc2dbe784b563d6ab54f2ef88c890fdad77232c98ed490aa07132/uvloop-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", size = 805476 }, - { url = "https://files.pythonhosted.org/packages/ee/ea/0bfae1aceb82a503f358d8d2fa126ca9dbdb2ba9c7866974faec1cb5875c/uvloop-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", size = 3960855 }, - { url = "https://files.pythonhosted.org/packages/8a/ca/0864176a649838b838f36d44bf31c451597ab363b60dc9e09c9630619d41/uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", size = 3973185 }, - { url = "https://files.pythonhosted.org/packages/30/bf/08ad29979a936d63787ba47a540de2132169f140d54aa25bc8c3df3e67f4/uvloop-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", size = 3820256 }, - { url = "https://files.pythonhosted.org/packages/da/e2/5cf6ef37e3daf2f06e651aae5ea108ad30df3cb269102678b61ebf1fdf42/uvloop-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", size = 3937323 }, - { url = "https://files.pythonhosted.org/packages/8c/4c/03f93178830dc7ce8b4cdee1d36770d2f5ebb6f3d37d354e061eefc73545/uvloop-0.21.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c", size = 1471284 }, - { url = "https://files.pythonhosted.org/packages/43/3e/92c03f4d05e50f09251bd8b2b2b584a2a7f8fe600008bcc4523337abe676/uvloop-0.21.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2", size = 821349 }, - { url = "https://files.pythonhosted.org/packages/a6/ef/a02ec5da49909dbbfb1fd205a9a1ac4e88ea92dcae885e7c961847cd51e2/uvloop-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d", size = 4580089 }, - { url = "https://files.pythonhosted.org/packages/06/a7/b4e6a19925c900be9f98bec0a75e6e8f79bb53bdeb891916609ab3958967/uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc", size = 4693770 }, - { url = "https://files.pythonhosted.org/packages/ce/0c/f07435a18a4b94ce6bd0677d8319cd3de61f3a9eeb1e5f8ab4e8b5edfcb3/uvloop-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb", size = 4451321 }, - { url = "https://files.pythonhosted.org/packages/8f/eb/f7032be105877bcf924709c97b1bf3b90255b4ec251f9340cef912559f28/uvloop-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f", size = 4659022 }, - { url = "https://files.pythonhosted.org/packages/3f/8d/2cbef610ca21539f0f36e2b34da49302029e7c9f09acef0b1c3b5839412b/uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", size = 1468123 }, - { url = "https://files.pythonhosted.org/packages/93/0d/b0038d5a469f94ed8f2b2fce2434a18396d8fbfb5da85a0a9781ebbdec14/uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", size = 819325 }, - { url = "https://files.pythonhosted.org/packages/50/94/0a687f39e78c4c1e02e3272c6b2ccdb4e0085fda3b8352fecd0410ccf915/uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", size = 4582806 }, - { url = "https://files.pythonhosted.org/packages/d2/19/f5b78616566ea68edd42aacaf645adbf71fbd83fc52281fba555dc27e3f1/uvloop-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", size = 4701068 }, - { url = "https://files.pythonhosted.org/packages/47/57/66f061ee118f413cd22a656de622925097170b9380b30091b78ea0c6ea75/uvloop-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", size = 4454428 }, - { url = "https://files.pythonhosted.org/packages/63/9a/0962b05b308494e3202d3f794a6e85abe471fe3cafdbcf95c2e8c713aabd/uvloop-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", size = 4660018 }, +sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741, upload-time = "2024-10-14T23:38:35.489Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/76/44a55515e8c9505aa1420aebacf4dd82552e5e15691654894e90d0bd051a/uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f", size = 1442019, upload-time = "2024-10-14T23:37:20.068Z" }, + { url = "https://files.pythonhosted.org/packages/35/5a/62d5800358a78cc25c8a6c72ef8b10851bdb8cca22e14d9c74167b7f86da/uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d", size = 801898, upload-time = "2024-10-14T23:37:22.663Z" }, + { url = "https://files.pythonhosted.org/packages/f3/96/63695e0ebd7da6c741ccd4489b5947394435e198a1382349c17b1146bb97/uvloop-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26", size = 3827735, upload-time = "2024-10-14T23:37:25.129Z" }, + { url = "https://files.pythonhosted.org/packages/61/e0/f0f8ec84979068ffae132c58c79af1de9cceeb664076beea86d941af1a30/uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb", size = 3825126, upload-time = "2024-10-14T23:37:27.59Z" }, + { url = "https://files.pythonhosted.org/packages/bf/fe/5e94a977d058a54a19df95f12f7161ab6e323ad49f4dabc28822eb2df7ea/uvloop-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f", size = 3705789, upload-time = "2024-10-14T23:37:29.385Z" }, + { url = "https://files.pythonhosted.org/packages/26/dd/c7179618e46092a77e036650c1f056041a028a35c4d76945089fcfc38af8/uvloop-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c", size = 3800523, upload-time = "2024-10-14T23:37:32.048Z" }, + { url = "https://files.pythonhosted.org/packages/57/a7/4cf0334105c1160dd6819f3297f8700fda7fc30ab4f61fbf3e725acbc7cc/uvloop-0.21.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", size = 1447410, upload-time = "2024-10-14T23:37:33.612Z" }, + { url = "https://files.pythonhosted.org/packages/8c/7c/1517b0bbc2dbe784b563d6ab54f2ef88c890fdad77232c98ed490aa07132/uvloop-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", size = 805476, upload-time = "2024-10-14T23:37:36.11Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ea/0bfae1aceb82a503f358d8d2fa126ca9dbdb2ba9c7866974faec1cb5875c/uvloop-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", size = 3960855, upload-time = "2024-10-14T23:37:37.683Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ca/0864176a649838b838f36d44bf31c451597ab363b60dc9e09c9630619d41/uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", size = 3973185, upload-time = "2024-10-14T23:37:40.226Z" }, + { url = "https://files.pythonhosted.org/packages/30/bf/08ad29979a936d63787ba47a540de2132169f140d54aa25bc8c3df3e67f4/uvloop-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", size = 3820256, upload-time = "2024-10-14T23:37:42.839Z" }, + { url = "https://files.pythonhosted.org/packages/da/e2/5cf6ef37e3daf2f06e651aae5ea108ad30df3cb269102678b61ebf1fdf42/uvloop-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", size = 3937323, upload-time = "2024-10-14T23:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/8c/4c/03f93178830dc7ce8b4cdee1d36770d2f5ebb6f3d37d354e061eefc73545/uvloop-0.21.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c", size = 1471284, upload-time = "2024-10-14T23:37:47.833Z" }, + { url = "https://files.pythonhosted.org/packages/43/3e/92c03f4d05e50f09251bd8b2b2b584a2a7f8fe600008bcc4523337abe676/uvloop-0.21.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2", size = 821349, upload-time = "2024-10-14T23:37:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/a6/ef/a02ec5da49909dbbfb1fd205a9a1ac4e88ea92dcae885e7c961847cd51e2/uvloop-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d", size = 4580089, upload-time = "2024-10-14T23:37:51.703Z" }, + { url = "https://files.pythonhosted.org/packages/06/a7/b4e6a19925c900be9f98bec0a75e6e8f79bb53bdeb891916609ab3958967/uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc", size = 4693770, upload-time = "2024-10-14T23:37:54.122Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0c/f07435a18a4b94ce6bd0677d8319cd3de61f3a9eeb1e5f8ab4e8b5edfcb3/uvloop-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb", size = 4451321, upload-time = "2024-10-14T23:37:55.766Z" }, + { url = "https://files.pythonhosted.org/packages/8f/eb/f7032be105877bcf924709c97b1bf3b90255b4ec251f9340cef912559f28/uvloop-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f", size = 4659022, upload-time = "2024-10-14T23:37:58.195Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8d/2cbef610ca21539f0f36e2b34da49302029e7c9f09acef0b1c3b5839412b/uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", size = 1468123, upload-time = "2024-10-14T23:38:00.688Z" }, + { url = "https://files.pythonhosted.org/packages/93/0d/b0038d5a469f94ed8f2b2fce2434a18396d8fbfb5da85a0a9781ebbdec14/uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", size = 819325, upload-time = "2024-10-14T23:38:02.309Z" }, + { url = "https://files.pythonhosted.org/packages/50/94/0a687f39e78c4c1e02e3272c6b2ccdb4e0085fda3b8352fecd0410ccf915/uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", size = 4582806, upload-time = "2024-10-14T23:38:04.711Z" }, + { url = "https://files.pythonhosted.org/packages/d2/19/f5b78616566ea68edd42aacaf645adbf71fbd83fc52281fba555dc27e3f1/uvloop-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", size = 4701068, upload-time = "2024-10-14T23:38:06.385Z" }, + { url = "https://files.pythonhosted.org/packages/47/57/66f061ee118f413cd22a656de622925097170b9380b30091b78ea0c6ea75/uvloop-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", size = 4454428, upload-time = "2024-10-14T23:38:08.416Z" }, + { url = "https://files.pythonhosted.org/packages/63/9a/0962b05b308494e3202d3f794a6e85abe471fe3cafdbcf95c2e8c713aabd/uvloop-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", size = 4660018, upload-time = "2024-10-14T23:38:10.888Z" }, ] [[package]] @@ -4583,41 +4678,41 @@ dependencies = [ { name = "filelock" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/56/2c/444f465fb2c65f40c3a104fd0c495184c4f2336d65baf398e3c75d72ea94/virtualenv-20.31.2.tar.gz", hash = "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af", size = 6076316 } +sdist = { url = "https://files.pythonhosted.org/packages/56/2c/444f465fb2c65f40c3a104fd0c495184c4f2336d65baf398e3c75d72ea94/virtualenv-20.31.2.tar.gz", hash = "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af", size = 6076316, upload-time = "2025-05-08T17:58:23.811Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/40/b1c265d4b2b62b58576588510fc4d1fe60a86319c8de99fd8e9fec617d2c/virtualenv-20.31.2-py3-none-any.whl", hash = "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", size = 6057982 }, + { url = "https://files.pythonhosted.org/packages/f3/40/b1c265d4b2b62b58576588510fc4d1fe60a86319c8de99fd8e9fec617d2c/virtualenv-20.31.2-py3-none-any.whl", hash = "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", size = 6057982, upload-time = "2025-05-08T17:58:21.15Z" }, ] [[package]] name = "watchdog" version = "6.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390 }, - { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389 }, - { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020 }, - { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393 }, - { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392 }, - { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019 }, - { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471 }, - { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449 }, - { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054 }, - { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480 }, - { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451 }, - { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057 }, - { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902 }, - { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380 }, - { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079 }, - { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078 }, - { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076 }, - { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077 }, - { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078 }, - { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077 }, - { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078 }, - { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065 }, - { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070 }, - { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067 }, +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390, upload-time = "2024-11-01T14:06:24.793Z" }, + { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389, upload-time = "2024-11-01T14:06:27.112Z" }, + { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020, upload-time = "2024-11-01T14:06:29.876Z" }, + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902, upload-time = "2024-11-01T14:06:53.119Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380, upload-time = "2024-11-01T14:06:55.19Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, ] [[package]] @@ -4627,203 +4722,203 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/e2/8ed598c42057de7aa5d97c472254af4906ff0a59a66699d426fc9ef795d7/watchfiles-1.0.5.tar.gz", hash = "sha256:b7529b5dcc114679d43827d8c35a07c493ad6f083633d573d81c660abc5979e9", size = 94537 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/4d/d02e6ea147bb7fff5fd109c694a95109612f419abed46548a930e7f7afa3/watchfiles-1.0.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5c40fe7dd9e5f81e0847b1ea64e1f5dd79dd61afbedb57759df06767ac719b40", size = 405632 }, - { url = "https://files.pythonhosted.org/packages/60/31/9ee50e29129d53a9a92ccf1d3992751dc56fc3c8f6ee721be1c7b9c81763/watchfiles-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c0db396e6003d99bb2d7232c957b5f0b5634bbd1b24e381a5afcc880f7373fb", size = 395734 }, - { url = "https://files.pythonhosted.org/packages/ad/8c/759176c97195306f028024f878e7f1c776bda66ccc5c68fa51e699cf8f1d/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b551d4fb482fc57d852b4541f911ba28957d051c8776e79c3b4a51eb5e2a1b11", size = 455008 }, - { url = "https://files.pythonhosted.org/packages/55/1a/5e977250c795ee79a0229e3b7f5e3a1b664e4e450756a22da84d2f4979fe/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:830aa432ba5c491d52a15b51526c29e4a4b92bf4f92253787f9726fe01519487", size = 459029 }, - { url = "https://files.pythonhosted.org/packages/e6/17/884cf039333605c1d6e296cf5be35fad0836953c3dfd2adb71b72f9dbcd0/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a16512051a822a416b0d477d5f8c0e67b67c1a20d9acecb0aafa3aa4d6e7d256", size = 488916 }, - { url = "https://files.pythonhosted.org/packages/ef/e0/bcb6e64b45837056c0a40f3a2db3ef51c2ced19fda38484fa7508e00632c/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe0cbc787770e52a96c6fda6726ace75be7f840cb327e1b08d7d54eadc3bc85", size = 523763 }, - { url = "https://files.pythonhosted.org/packages/24/e9/f67e9199f3bb35c1837447ecf07e9830ec00ff5d35a61e08c2cd67217949/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d363152c5e16b29d66cbde8fa614f9e313e6f94a8204eaab268db52231fe5358", size = 502891 }, - { url = "https://files.pythonhosted.org/packages/23/ed/a6cf815f215632f5c8065e9c41fe872025ffea35aa1f80499f86eae922db/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ee32c9a9bee4d0b7bd7cbeb53cb185cf0b622ac761efaa2eba84006c3b3a614", size = 454921 }, - { url = "https://files.pythonhosted.org/packages/92/4c/e14978599b80cde8486ab5a77a821e8a982ae8e2fcb22af7b0886a033ec8/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29c7fd632ccaf5517c16a5188e36f6612d6472ccf55382db6c7fe3fcccb7f59f", size = 631422 }, - { url = "https://files.pythonhosted.org/packages/b2/1a/9263e34c3458f7614b657f974f4ee61fd72f58adce8b436e16450e054efd/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e637810586e6fe380c8bc1b3910accd7f1d3a9a7262c8a78d4c8fb3ba6a2b3d", size = 625675 }, - { url = "https://files.pythonhosted.org/packages/96/1f/1803a18bd6ab04a0766386a19bcfe64641381a04939efdaa95f0e3b0eb58/watchfiles-1.0.5-cp310-cp310-win32.whl", hash = "sha256:cd47d063fbeabd4c6cae1d4bcaa38f0902f8dc5ed168072874ea11d0c7afc1ff", size = 277921 }, - { url = "https://files.pythonhosted.org/packages/c2/3b/29a89de074a7d6e8b4dc67c26e03d73313e4ecf0d6e97e942a65fa7c195e/watchfiles-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:86c0df05b47a79d80351cd179893f2f9c1b1cae49d96e8b3290c7f4bd0ca0a92", size = 291526 }, - { url = "https://files.pythonhosted.org/packages/39/f4/41b591f59021786ef517e1cdc3b510383551846703e03f204827854a96f8/watchfiles-1.0.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:237f9be419e977a0f8f6b2e7b0475ababe78ff1ab06822df95d914a945eac827", size = 405336 }, - { url = "https://files.pythonhosted.org/packages/ae/06/93789c135be4d6d0e4f63e96eea56dc54050b243eacc28439a26482b5235/watchfiles-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0da39ff917af8b27a4bdc5a97ac577552a38aac0d260a859c1517ea3dc1a7c4", size = 395977 }, - { url = "https://files.pythonhosted.org/packages/d2/db/1cd89bd83728ca37054512d4d35ab69b5f12b8aa2ac9be3b0276b3bf06cc/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cfcb3952350e95603f232a7a15f6c5f86c5375e46f0bd4ae70d43e3e063c13d", size = 455232 }, - { url = "https://files.pythonhosted.org/packages/40/90/d8a4d44ffe960517e487c9c04f77b06b8abf05eb680bed71c82b5f2cad62/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b2dddba7a4e6151384e252a5632efcaa9bc5d1c4b567f3cb621306b2ca9f63", size = 459151 }, - { url = "https://files.pythonhosted.org/packages/6c/da/267a1546f26465dead1719caaba3ce660657f83c9d9c052ba98fb8856e13/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95cf944fcfc394c5f9de794ce581914900f82ff1f855326f25ebcf24d5397418", size = 489054 }, - { url = "https://files.pythonhosted.org/packages/b1/31/33850dfd5c6efb6f27d2465cc4c6b27c5a6f5ed53c6fa63b7263cf5f60f6/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf6cd9f83d7c023b1aba15d13f705ca7b7d38675c121f3cc4a6e25bd0857ee9", size = 523955 }, - { url = "https://files.pythonhosted.org/packages/09/84/b7d7b67856efb183a421f1416b44ca975cb2ea6c4544827955dfb01f7dc2/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:852de68acd6212cd6d33edf21e6f9e56e5d98c6add46f48244bd479d97c967c6", size = 502234 }, - { url = "https://files.pythonhosted.org/packages/71/87/6dc5ec6882a2254cfdd8b0718b684504e737273903b65d7338efaba08b52/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5730f3aa35e646103b53389d5bc77edfbf578ab6dab2e005142b5b80a35ef25", size = 454750 }, - { url = "https://files.pythonhosted.org/packages/3d/6c/3786c50213451a0ad15170d091570d4a6554976cf0df19878002fc96075a/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:18b3bd29954bc4abeeb4e9d9cf0b30227f0f206c86657674f544cb032296acd5", size = 631591 }, - { url = "https://files.pythonhosted.org/packages/1b/b3/1427425ade4e359a0deacce01a47a26024b2ccdb53098f9d64d497f6684c/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ba5552a1b07c8edbf197055bc9d518b8f0d98a1c6a73a293bc0726dce068ed01", size = 625370 }, - { url = "https://files.pythonhosted.org/packages/15/ba/f60e053b0b5b8145d682672024aa91370a29c5c921a88977eb565de34086/watchfiles-1.0.5-cp311-cp311-win32.whl", hash = "sha256:2f1fefb2e90e89959447bc0420fddd1e76f625784340d64a2f7d5983ef9ad246", size = 277791 }, - { url = "https://files.pythonhosted.org/packages/50/ed/7603c4e164225c12c0d4e8700b64bb00e01a6c4eeea372292a3856be33a4/watchfiles-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b6e76ceb1dd18c8e29c73f47d41866972e891fc4cc7ba014f487def72c1cf096", size = 291622 }, - { url = "https://files.pythonhosted.org/packages/a2/c2/99bb7c96b4450e36877fde33690ded286ff555b5a5c1d925855d556968a1/watchfiles-1.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:266710eb6fddc1f5e51843c70e3bebfb0f5e77cf4f27129278c70554104d19ed", size = 283699 }, - { url = "https://files.pythonhosted.org/packages/2a/8c/4f0b9bdb75a1bfbd9c78fad7d8854369283f74fe7cf03eb16be77054536d/watchfiles-1.0.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5eb568c2aa6018e26da9e6c86f3ec3fd958cee7f0311b35c2630fa4217d17f2", size = 401511 }, - { url = "https://files.pythonhosted.org/packages/dc/4e/7e15825def77f8bd359b6d3f379f0c9dac4eb09dd4ddd58fd7d14127179c/watchfiles-1.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a04059f4923ce4e856b4b4e5e783a70f49d9663d22a4c3b3298165996d1377f", size = 392715 }, - { url = "https://files.pythonhosted.org/packages/58/65/b72fb817518728e08de5840d5d38571466c1b4a3f724d190cec909ee6f3f/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e380c89983ce6e6fe2dd1e1921b9952fb4e6da882931abd1824c092ed495dec", size = 454138 }, - { url = "https://files.pythonhosted.org/packages/3e/a4/86833fd2ea2e50ae28989f5950b5c3f91022d67092bfec08f8300d8b347b/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fe43139b2c0fdc4a14d4f8d5b5d967f7a2777fd3d38ecf5b1ec669b0d7e43c21", size = 458592 }, - { url = "https://files.pythonhosted.org/packages/38/7e/42cb8df8be9a37e50dd3a818816501cf7a20d635d76d6bd65aae3dbbff68/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee0822ce1b8a14fe5a066f93edd20aada932acfe348bede8aa2149f1a4489512", size = 487532 }, - { url = "https://files.pythonhosted.org/packages/fc/fd/13d26721c85d7f3df6169d8b495fcac8ab0dc8f0945ebea8845de4681dab/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0dbcb1c2d8f2ab6e0a81c6699b236932bd264d4cef1ac475858d16c403de74d", size = 522865 }, - { url = "https://files.pythonhosted.org/packages/a1/0d/7f9ae243c04e96c5455d111e21b09087d0eeaf9a1369e13a01c7d3d82478/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2014a2b18ad3ca53b1f6c23f8cd94a18ce930c1837bd891262c182640eb40a6", size = 499887 }, - { url = "https://files.pythonhosted.org/packages/8e/0f/a257766998e26aca4b3acf2ae97dff04b57071e991a510857d3799247c67/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6ae86d5cb647bf58f9f655fcf577f713915a5d69057a0371bc257e2553234", size = 454498 }, - { url = "https://files.pythonhosted.org/packages/81/79/8bf142575a03e0af9c3d5f8bcae911ee6683ae93a625d349d4ecf4c8f7df/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1a7bac2bde1d661fb31f4d4e8e539e178774b76db3c2c17c4bb3e960a5de07a2", size = 630663 }, - { url = "https://files.pythonhosted.org/packages/f1/80/abe2e79f610e45c63a70d271caea90c49bbf93eb00fa947fa9b803a1d51f/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ab626da2fc1ac277bbf752446470b367f84b50295264d2d313e28dc4405d663", size = 625410 }, - { url = "https://files.pythonhosted.org/packages/91/6f/bc7fbecb84a41a9069c2c6eb6319f7f7df113adf113e358c57fc1aff7ff5/watchfiles-1.0.5-cp312-cp312-win32.whl", hash = "sha256:9f4571a783914feda92018ef3901dab8caf5b029325b5fe4558c074582815249", size = 277965 }, - { url = "https://files.pythonhosted.org/packages/99/a5/bf1c297ea6649ec59e935ab311f63d8af5faa8f0b86993e3282b984263e3/watchfiles-1.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:360a398c3a19672cf93527f7e8d8b60d8275119c5d900f2e184d32483117a705", size = 291693 }, - { url = "https://files.pythonhosted.org/packages/7f/7b/fd01087cc21db5c47e5beae507b87965db341cce8a86f9eb12bf5219d4e0/watchfiles-1.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:1a2902ede862969077b97523987c38db28abbe09fb19866e711485d9fbf0d417", size = 283287 }, - { url = "https://files.pythonhosted.org/packages/c7/62/435766874b704f39b2fecd8395a29042db2b5ec4005bd34523415e9bd2e0/watchfiles-1.0.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0b289572c33a0deae62daa57e44a25b99b783e5f7aed81b314232b3d3c81a11d", size = 401531 }, - { url = "https://files.pythonhosted.org/packages/6e/a6/e52a02c05411b9cb02823e6797ef9bbba0bfaf1bb627da1634d44d8af833/watchfiles-1.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a056c2f692d65bf1e99c41045e3bdcaea3cb9e6b5a53dcaf60a5f3bd95fc9763", size = 392417 }, - { url = "https://files.pythonhosted.org/packages/3f/53/c4af6819770455932144e0109d4854437769672d7ad897e76e8e1673435d/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9dca99744991fc9850d18015c4f0438865414e50069670f5f7eee08340d8b40", size = 453423 }, - { url = "https://files.pythonhosted.org/packages/cb/d1/8e88df58bbbf819b8bc5cfbacd3c79e01b40261cad0fc84d1e1ebd778a07/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:894342d61d355446d02cd3988a7326af344143eb33a2fd5d38482a92072d9563", size = 458185 }, - { url = "https://files.pythonhosted.org/packages/ff/70/fffaa11962dd5429e47e478a18736d4e42bec42404f5ee3b92ef1b87ad60/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab44e1580924d1ffd7b3938e02716d5ad190441965138b4aa1d1f31ea0877f04", size = 486696 }, - { url = "https://files.pythonhosted.org/packages/39/db/723c0328e8b3692d53eb273797d9a08be6ffb1d16f1c0ba2bdbdc2a3852c/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6f9367b132078b2ceb8d066ff6c93a970a18c3029cea37bfd7b2d3dd2e5db8f", size = 522327 }, - { url = "https://files.pythonhosted.org/packages/cd/05/9fccc43c50c39a76b68343484b9da7b12d42d0859c37c61aec018c967a32/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2e55a9b162e06e3f862fb61e399fe9f05d908d019d87bf5b496a04ef18a970a", size = 499741 }, - { url = "https://files.pythonhosted.org/packages/23/14/499e90c37fa518976782b10a18b18db9f55ea73ca14641615056f8194bb3/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0125f91f70e0732a9f8ee01e49515c35d38ba48db507a50c5bdcad9503af5827", size = 453995 }, - { url = "https://files.pythonhosted.org/packages/61/d9/f75d6840059320df5adecd2c687fbc18960a7f97b55c300d20f207d48aef/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:13bb21f8ba3248386337c9fa51c528868e6c34a707f729ab041c846d52a0c69a", size = 629693 }, - { url = "https://files.pythonhosted.org/packages/fc/17/180ca383f5061b61406477218c55d66ec118e6c0c51f02d8142895fcf0a9/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936", size = 624677 }, - { url = "https://files.pythonhosted.org/packages/bf/15/714d6ef307f803f236d69ee9d421763707899d6298d9f3183e55e366d9af/watchfiles-1.0.5-cp313-cp313-win32.whl", hash = "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc", size = 277804 }, - { url = "https://files.pythonhosted.org/packages/a8/b4/c57b99518fadf431f3ef47a610839e46e5f8abf9814f969859d1c65c02c7/watchfiles-1.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11", size = 291087 }, - { url = "https://files.pythonhosted.org/packages/1a/03/81f9fcc3963b3fc415cd4b0b2b39ee8cc136c42fb10a36acf38745e9d283/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f59b870db1f1ae5a9ac28245707d955c8721dd6565e7f411024fa374b5362d1d", size = 405947 }, - { url = "https://files.pythonhosted.org/packages/54/97/8c4213a852feb64807ec1d380f42d4fc8bfaef896bdbd94318f8fd7f3e4e/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9475b0093767e1475095f2aeb1d219fb9664081d403d1dff81342df8cd707034", size = 397276 }, - { url = "https://files.pythonhosted.org/packages/78/12/d4464d19860cb9672efa45eec1b08f8472c478ed67dcd30647c51ada7aef/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc533aa50664ebd6c628b2f30591956519462f5d27f951ed03d6c82b2dfd9965", size = 455550 }, - { url = "https://files.pythonhosted.org/packages/90/fb/b07bcdf1034d8edeaef4c22f3e9e3157d37c5071b5f9492ffdfa4ad4bed7/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed1cd825158dcaae36acce7b2db33dcbfd12b30c34317a88b8ed80f0541cc57", size = 455542 }, +sdist = { url = "https://files.pythonhosted.org/packages/03/e2/8ed598c42057de7aa5d97c472254af4906ff0a59a66699d426fc9ef795d7/watchfiles-1.0.5.tar.gz", hash = "sha256:b7529b5dcc114679d43827d8c35a07c493ad6f083633d573d81c660abc5979e9", size = 94537, upload-time = "2025-04-08T10:36:26.722Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/4d/d02e6ea147bb7fff5fd109c694a95109612f419abed46548a930e7f7afa3/watchfiles-1.0.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5c40fe7dd9e5f81e0847b1ea64e1f5dd79dd61afbedb57759df06767ac719b40", size = 405632, upload-time = "2025-04-08T10:34:41.832Z" }, + { url = "https://files.pythonhosted.org/packages/60/31/9ee50e29129d53a9a92ccf1d3992751dc56fc3c8f6ee721be1c7b9c81763/watchfiles-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c0db396e6003d99bb2d7232c957b5f0b5634bbd1b24e381a5afcc880f7373fb", size = 395734, upload-time = "2025-04-08T10:34:44.236Z" }, + { url = "https://files.pythonhosted.org/packages/ad/8c/759176c97195306f028024f878e7f1c776bda66ccc5c68fa51e699cf8f1d/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b551d4fb482fc57d852b4541f911ba28957d051c8776e79c3b4a51eb5e2a1b11", size = 455008, upload-time = "2025-04-08T10:34:45.617Z" }, + { url = "https://files.pythonhosted.org/packages/55/1a/5e977250c795ee79a0229e3b7f5e3a1b664e4e450756a22da84d2f4979fe/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:830aa432ba5c491d52a15b51526c29e4a4b92bf4f92253787f9726fe01519487", size = 459029, upload-time = "2025-04-08T10:34:46.814Z" }, + { url = "https://files.pythonhosted.org/packages/e6/17/884cf039333605c1d6e296cf5be35fad0836953c3dfd2adb71b72f9dbcd0/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a16512051a822a416b0d477d5f8c0e67b67c1a20d9acecb0aafa3aa4d6e7d256", size = 488916, upload-time = "2025-04-08T10:34:48.571Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e0/bcb6e64b45837056c0a40f3a2db3ef51c2ced19fda38484fa7508e00632c/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe0cbc787770e52a96c6fda6726ace75be7f840cb327e1b08d7d54eadc3bc85", size = 523763, upload-time = "2025-04-08T10:34:50.268Z" }, + { url = "https://files.pythonhosted.org/packages/24/e9/f67e9199f3bb35c1837447ecf07e9830ec00ff5d35a61e08c2cd67217949/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d363152c5e16b29d66cbde8fa614f9e313e6f94a8204eaab268db52231fe5358", size = 502891, upload-time = "2025-04-08T10:34:51.419Z" }, + { url = "https://files.pythonhosted.org/packages/23/ed/a6cf815f215632f5c8065e9c41fe872025ffea35aa1f80499f86eae922db/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ee32c9a9bee4d0b7bd7cbeb53cb185cf0b622ac761efaa2eba84006c3b3a614", size = 454921, upload-time = "2025-04-08T10:34:52.67Z" }, + { url = "https://files.pythonhosted.org/packages/92/4c/e14978599b80cde8486ab5a77a821e8a982ae8e2fcb22af7b0886a033ec8/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29c7fd632ccaf5517c16a5188e36f6612d6472ccf55382db6c7fe3fcccb7f59f", size = 631422, upload-time = "2025-04-08T10:34:53.985Z" }, + { url = "https://files.pythonhosted.org/packages/b2/1a/9263e34c3458f7614b657f974f4ee61fd72f58adce8b436e16450e054efd/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e637810586e6fe380c8bc1b3910accd7f1d3a9a7262c8a78d4c8fb3ba6a2b3d", size = 625675, upload-time = "2025-04-08T10:34:55.173Z" }, + { url = "https://files.pythonhosted.org/packages/96/1f/1803a18bd6ab04a0766386a19bcfe64641381a04939efdaa95f0e3b0eb58/watchfiles-1.0.5-cp310-cp310-win32.whl", hash = "sha256:cd47d063fbeabd4c6cae1d4bcaa38f0902f8dc5ed168072874ea11d0c7afc1ff", size = 277921, upload-time = "2025-04-08T10:34:56.318Z" }, + { url = "https://files.pythonhosted.org/packages/c2/3b/29a89de074a7d6e8b4dc67c26e03d73313e4ecf0d6e97e942a65fa7c195e/watchfiles-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:86c0df05b47a79d80351cd179893f2f9c1b1cae49d96e8b3290c7f4bd0ca0a92", size = 291526, upload-time = "2025-04-08T10:34:57.95Z" }, + { url = "https://files.pythonhosted.org/packages/39/f4/41b591f59021786ef517e1cdc3b510383551846703e03f204827854a96f8/watchfiles-1.0.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:237f9be419e977a0f8f6b2e7b0475ababe78ff1ab06822df95d914a945eac827", size = 405336, upload-time = "2025-04-08T10:34:59.359Z" }, + { url = "https://files.pythonhosted.org/packages/ae/06/93789c135be4d6d0e4f63e96eea56dc54050b243eacc28439a26482b5235/watchfiles-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0da39ff917af8b27a4bdc5a97ac577552a38aac0d260a859c1517ea3dc1a7c4", size = 395977, upload-time = "2025-04-08T10:35:00.522Z" }, + { url = "https://files.pythonhosted.org/packages/d2/db/1cd89bd83728ca37054512d4d35ab69b5f12b8aa2ac9be3b0276b3bf06cc/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cfcb3952350e95603f232a7a15f6c5f86c5375e46f0bd4ae70d43e3e063c13d", size = 455232, upload-time = "2025-04-08T10:35:01.698Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/d8a4d44ffe960517e487c9c04f77b06b8abf05eb680bed71c82b5f2cad62/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b2dddba7a4e6151384e252a5632efcaa9bc5d1c4b567f3cb621306b2ca9f63", size = 459151, upload-time = "2025-04-08T10:35:03.358Z" }, + { url = "https://files.pythonhosted.org/packages/6c/da/267a1546f26465dead1719caaba3ce660657f83c9d9c052ba98fb8856e13/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95cf944fcfc394c5f9de794ce581914900f82ff1f855326f25ebcf24d5397418", size = 489054, upload-time = "2025-04-08T10:35:04.561Z" }, + { url = "https://files.pythonhosted.org/packages/b1/31/33850dfd5c6efb6f27d2465cc4c6b27c5a6f5ed53c6fa63b7263cf5f60f6/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf6cd9f83d7c023b1aba15d13f705ca7b7d38675c121f3cc4a6e25bd0857ee9", size = 523955, upload-time = "2025-04-08T10:35:05.786Z" }, + { url = "https://files.pythonhosted.org/packages/09/84/b7d7b67856efb183a421f1416b44ca975cb2ea6c4544827955dfb01f7dc2/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:852de68acd6212cd6d33edf21e6f9e56e5d98c6add46f48244bd479d97c967c6", size = 502234, upload-time = "2025-04-08T10:35:07.187Z" }, + { url = "https://files.pythonhosted.org/packages/71/87/6dc5ec6882a2254cfdd8b0718b684504e737273903b65d7338efaba08b52/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5730f3aa35e646103b53389d5bc77edfbf578ab6dab2e005142b5b80a35ef25", size = 454750, upload-time = "2025-04-08T10:35:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/3d/6c/3786c50213451a0ad15170d091570d4a6554976cf0df19878002fc96075a/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:18b3bd29954bc4abeeb4e9d9cf0b30227f0f206c86657674f544cb032296acd5", size = 631591, upload-time = "2025-04-08T10:35:10.64Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b3/1427425ade4e359a0deacce01a47a26024b2ccdb53098f9d64d497f6684c/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ba5552a1b07c8edbf197055bc9d518b8f0d98a1c6a73a293bc0726dce068ed01", size = 625370, upload-time = "2025-04-08T10:35:12.412Z" }, + { url = "https://files.pythonhosted.org/packages/15/ba/f60e053b0b5b8145d682672024aa91370a29c5c921a88977eb565de34086/watchfiles-1.0.5-cp311-cp311-win32.whl", hash = "sha256:2f1fefb2e90e89959447bc0420fddd1e76f625784340d64a2f7d5983ef9ad246", size = 277791, upload-time = "2025-04-08T10:35:13.719Z" }, + { url = "https://files.pythonhosted.org/packages/50/ed/7603c4e164225c12c0d4e8700b64bb00e01a6c4eeea372292a3856be33a4/watchfiles-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b6e76ceb1dd18c8e29c73f47d41866972e891fc4cc7ba014f487def72c1cf096", size = 291622, upload-time = "2025-04-08T10:35:15.071Z" }, + { url = "https://files.pythonhosted.org/packages/a2/c2/99bb7c96b4450e36877fde33690ded286ff555b5a5c1d925855d556968a1/watchfiles-1.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:266710eb6fddc1f5e51843c70e3bebfb0f5e77cf4f27129278c70554104d19ed", size = 283699, upload-time = "2025-04-08T10:35:16.732Z" }, + { url = "https://files.pythonhosted.org/packages/2a/8c/4f0b9bdb75a1bfbd9c78fad7d8854369283f74fe7cf03eb16be77054536d/watchfiles-1.0.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5eb568c2aa6018e26da9e6c86f3ec3fd958cee7f0311b35c2630fa4217d17f2", size = 401511, upload-time = "2025-04-08T10:35:17.956Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4e/7e15825def77f8bd359b6d3f379f0c9dac4eb09dd4ddd58fd7d14127179c/watchfiles-1.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a04059f4923ce4e856b4b4e5e783a70f49d9663d22a4c3b3298165996d1377f", size = 392715, upload-time = "2025-04-08T10:35:19.202Z" }, + { url = "https://files.pythonhosted.org/packages/58/65/b72fb817518728e08de5840d5d38571466c1b4a3f724d190cec909ee6f3f/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e380c89983ce6e6fe2dd1e1921b9952fb4e6da882931abd1824c092ed495dec", size = 454138, upload-time = "2025-04-08T10:35:20.586Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a4/86833fd2ea2e50ae28989f5950b5c3f91022d67092bfec08f8300d8b347b/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fe43139b2c0fdc4a14d4f8d5b5d967f7a2777fd3d38ecf5b1ec669b0d7e43c21", size = 458592, upload-time = "2025-04-08T10:35:21.87Z" }, + { url = "https://files.pythonhosted.org/packages/38/7e/42cb8df8be9a37e50dd3a818816501cf7a20d635d76d6bd65aae3dbbff68/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee0822ce1b8a14fe5a066f93edd20aada932acfe348bede8aa2149f1a4489512", size = 487532, upload-time = "2025-04-08T10:35:23.143Z" }, + { url = "https://files.pythonhosted.org/packages/fc/fd/13d26721c85d7f3df6169d8b495fcac8ab0dc8f0945ebea8845de4681dab/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0dbcb1c2d8f2ab6e0a81c6699b236932bd264d4cef1ac475858d16c403de74d", size = 522865, upload-time = "2025-04-08T10:35:24.702Z" }, + { url = "https://files.pythonhosted.org/packages/a1/0d/7f9ae243c04e96c5455d111e21b09087d0eeaf9a1369e13a01c7d3d82478/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2014a2b18ad3ca53b1f6c23f8cd94a18ce930c1837bd891262c182640eb40a6", size = 499887, upload-time = "2025-04-08T10:35:25.969Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0f/a257766998e26aca4b3acf2ae97dff04b57071e991a510857d3799247c67/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6ae86d5cb647bf58f9f655fcf577f713915a5d69057a0371bc257e2553234", size = 454498, upload-time = "2025-04-08T10:35:27.353Z" }, + { url = "https://files.pythonhosted.org/packages/81/79/8bf142575a03e0af9c3d5f8bcae911ee6683ae93a625d349d4ecf4c8f7df/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1a7bac2bde1d661fb31f4d4e8e539e178774b76db3c2c17c4bb3e960a5de07a2", size = 630663, upload-time = "2025-04-08T10:35:28.685Z" }, + { url = "https://files.pythonhosted.org/packages/f1/80/abe2e79f610e45c63a70d271caea90c49bbf93eb00fa947fa9b803a1d51f/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ab626da2fc1ac277bbf752446470b367f84b50295264d2d313e28dc4405d663", size = 625410, upload-time = "2025-04-08T10:35:30.42Z" }, + { url = "https://files.pythonhosted.org/packages/91/6f/bc7fbecb84a41a9069c2c6eb6319f7f7df113adf113e358c57fc1aff7ff5/watchfiles-1.0.5-cp312-cp312-win32.whl", hash = "sha256:9f4571a783914feda92018ef3901dab8caf5b029325b5fe4558c074582815249", size = 277965, upload-time = "2025-04-08T10:35:32.023Z" }, + { url = "https://files.pythonhosted.org/packages/99/a5/bf1c297ea6649ec59e935ab311f63d8af5faa8f0b86993e3282b984263e3/watchfiles-1.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:360a398c3a19672cf93527f7e8d8b60d8275119c5d900f2e184d32483117a705", size = 291693, upload-time = "2025-04-08T10:35:33.225Z" }, + { url = "https://files.pythonhosted.org/packages/7f/7b/fd01087cc21db5c47e5beae507b87965db341cce8a86f9eb12bf5219d4e0/watchfiles-1.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:1a2902ede862969077b97523987c38db28abbe09fb19866e711485d9fbf0d417", size = 283287, upload-time = "2025-04-08T10:35:34.568Z" }, + { url = "https://files.pythonhosted.org/packages/c7/62/435766874b704f39b2fecd8395a29042db2b5ec4005bd34523415e9bd2e0/watchfiles-1.0.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0b289572c33a0deae62daa57e44a25b99b783e5f7aed81b314232b3d3c81a11d", size = 401531, upload-time = "2025-04-08T10:35:35.792Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a6/e52a02c05411b9cb02823e6797ef9bbba0bfaf1bb627da1634d44d8af833/watchfiles-1.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a056c2f692d65bf1e99c41045e3bdcaea3cb9e6b5a53dcaf60a5f3bd95fc9763", size = 392417, upload-time = "2025-04-08T10:35:37.048Z" }, + { url = "https://files.pythonhosted.org/packages/3f/53/c4af6819770455932144e0109d4854437769672d7ad897e76e8e1673435d/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9dca99744991fc9850d18015c4f0438865414e50069670f5f7eee08340d8b40", size = 453423, upload-time = "2025-04-08T10:35:38.357Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d1/8e88df58bbbf819b8bc5cfbacd3c79e01b40261cad0fc84d1e1ebd778a07/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:894342d61d355446d02cd3988a7326af344143eb33a2fd5d38482a92072d9563", size = 458185, upload-time = "2025-04-08T10:35:39.708Z" }, + { url = "https://files.pythonhosted.org/packages/ff/70/fffaa11962dd5429e47e478a18736d4e42bec42404f5ee3b92ef1b87ad60/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab44e1580924d1ffd7b3938e02716d5ad190441965138b4aa1d1f31ea0877f04", size = 486696, upload-time = "2025-04-08T10:35:41.469Z" }, + { url = "https://files.pythonhosted.org/packages/39/db/723c0328e8b3692d53eb273797d9a08be6ffb1d16f1c0ba2bdbdc2a3852c/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6f9367b132078b2ceb8d066ff6c93a970a18c3029cea37bfd7b2d3dd2e5db8f", size = 522327, upload-time = "2025-04-08T10:35:43.289Z" }, + { url = "https://files.pythonhosted.org/packages/cd/05/9fccc43c50c39a76b68343484b9da7b12d42d0859c37c61aec018c967a32/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2e55a9b162e06e3f862fb61e399fe9f05d908d019d87bf5b496a04ef18a970a", size = 499741, upload-time = "2025-04-08T10:35:44.574Z" }, + { url = "https://files.pythonhosted.org/packages/23/14/499e90c37fa518976782b10a18b18db9f55ea73ca14641615056f8194bb3/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0125f91f70e0732a9f8ee01e49515c35d38ba48db507a50c5bdcad9503af5827", size = 453995, upload-time = "2025-04-08T10:35:46.336Z" }, + { url = "https://files.pythonhosted.org/packages/61/d9/f75d6840059320df5adecd2c687fbc18960a7f97b55c300d20f207d48aef/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:13bb21f8ba3248386337c9fa51c528868e6c34a707f729ab041c846d52a0c69a", size = 629693, upload-time = "2025-04-08T10:35:48.161Z" }, + { url = "https://files.pythonhosted.org/packages/fc/17/180ca383f5061b61406477218c55d66ec118e6c0c51f02d8142895fcf0a9/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936", size = 624677, upload-time = "2025-04-08T10:35:49.65Z" }, + { url = "https://files.pythonhosted.org/packages/bf/15/714d6ef307f803f236d69ee9d421763707899d6298d9f3183e55e366d9af/watchfiles-1.0.5-cp313-cp313-win32.whl", hash = "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc", size = 277804, upload-time = "2025-04-08T10:35:51.093Z" }, + { url = "https://files.pythonhosted.org/packages/a8/b4/c57b99518fadf431f3ef47a610839e46e5f8abf9814f969859d1c65c02c7/watchfiles-1.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11", size = 291087, upload-time = "2025-04-08T10:35:52.458Z" }, + { url = "https://files.pythonhosted.org/packages/1a/03/81f9fcc3963b3fc415cd4b0b2b39ee8cc136c42fb10a36acf38745e9d283/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f59b870db1f1ae5a9ac28245707d955c8721dd6565e7f411024fa374b5362d1d", size = 405947, upload-time = "2025-04-08T10:36:13.721Z" }, + { url = "https://files.pythonhosted.org/packages/54/97/8c4213a852feb64807ec1d380f42d4fc8bfaef896bdbd94318f8fd7f3e4e/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9475b0093767e1475095f2aeb1d219fb9664081d403d1dff81342df8cd707034", size = 397276, upload-time = "2025-04-08T10:36:15.131Z" }, + { url = "https://files.pythonhosted.org/packages/78/12/d4464d19860cb9672efa45eec1b08f8472c478ed67dcd30647c51ada7aef/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc533aa50664ebd6c628b2f30591956519462f5d27f951ed03d6c82b2dfd9965", size = 455550, upload-time = "2025-04-08T10:36:16.635Z" }, + { url = "https://files.pythonhosted.org/packages/90/fb/b07bcdf1034d8edeaef4c22f3e9e3157d37c5071b5f9492ffdfa4ad4bed7/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed1cd825158dcaae36acce7b2db33dcbfd12b30c34317a88b8ed80f0541cc57", size = 455542, upload-time = "2025-04-08T10:36:18.655Z" }, ] [[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 } +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 }, + { 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 = "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 } +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 }, + { 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 = "15.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", size = 175423 }, - { url = "https://files.pythonhosted.org/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", size = 173080 }, - { url = "https://files.pythonhosted.org/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", size = 173329 }, - { url = "https://files.pythonhosted.org/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", size = 182312 }, - { url = "https://files.pythonhosted.org/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", size = 181319 }, - { url = "https://files.pythonhosted.org/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", size = 181631 }, - { url = "https://files.pythonhosted.org/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", size = 182016 }, - { url = "https://files.pythonhosted.org/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", size = 181426 }, - { url = "https://files.pythonhosted.org/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", size = 181360 }, - { url = "https://files.pythonhosted.org/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", size = 176388 }, - { url = "https://files.pythonhosted.org/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", size = 176830 }, - { url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423 }, - { url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082 }, - { url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330 }, - { url = "https://files.pythonhosted.org/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878 }, - { url = "https://files.pythonhosted.org/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883 }, - { url = "https://files.pythonhosted.org/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252 }, - { url = "https://files.pythonhosted.org/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521 }, - { url = "https://files.pythonhosted.org/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958 }, - { url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918 }, - { url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388 }, - { url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828 }, - { url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437 }, - { url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096 }, - { url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332 }, - { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152 }, - { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096 }, - { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523 }, - { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790 }, - { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165 }, - { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160 }, - { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395 }, - { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841 }, - { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440 }, - { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098 }, - { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329 }, - { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111 }, - { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054 }, - { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496 }, - { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829 }, - { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217 }, - { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195 }, - { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393 }, - { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837 }, - { url = "https://files.pythonhosted.org/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109 }, - { url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343 }, - { url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599 }, - { url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207 }, - { url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155 }, - { url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884 }, - { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743 }, +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", size = 175423, upload-time = "2025-03-05T20:01:35.363Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", size = 173080, upload-time = "2025-03-05T20:01:37.304Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", size = 173329, upload-time = "2025-03-05T20:01:39.668Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", size = 182312, upload-time = "2025-03-05T20:01:41.815Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", size = 181319, upload-time = "2025-03-05T20:01:43.967Z" }, + { url = "https://files.pythonhosted.org/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", size = 181631, upload-time = "2025-03-05T20:01:46.104Z" }, + { url = "https://files.pythonhosted.org/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", size = 182016, upload-time = "2025-03-05T20:01:47.603Z" }, + { url = "https://files.pythonhosted.org/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", size = 181426, upload-time = "2025-03-05T20:01:48.949Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", size = 181360, upload-time = "2025-03-05T20:01:50.938Z" }, + { url = "https://files.pythonhosted.org/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", size = 176388, upload-time = "2025-03-05T20:01:52.213Z" }, + { url = "https://files.pythonhosted.org/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", size = 176830, upload-time = "2025-03-05T20:01:53.922Z" }, + { url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423, upload-time = "2025-03-05T20:01:56.276Z" }, + { url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082, upload-time = "2025-03-05T20:01:57.563Z" }, + { url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330, upload-time = "2025-03-05T20:01:59.063Z" }, + { url = "https://files.pythonhosted.org/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878, upload-time = "2025-03-05T20:02:00.305Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883, upload-time = "2025-03-05T20:02:03.148Z" }, + { url = "https://files.pythonhosted.org/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252, upload-time = "2025-03-05T20:02:05.29Z" }, + { url = "https://files.pythonhosted.org/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521, upload-time = "2025-03-05T20:02:07.458Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958, upload-time = "2025-03-05T20:02:09.842Z" }, + { url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918, upload-time = "2025-03-05T20:02:11.968Z" }, + { url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388, upload-time = "2025-03-05T20:02:13.32Z" }, + { url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828, upload-time = "2025-03-05T20:02:14.585Z" }, + { url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload-time = "2025-03-05T20:02:16.706Z" }, + { url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload-time = "2025-03-05T20:02:18.832Z" }, + { url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload-time = "2025-03-05T20:02:20.187Z" }, + { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" }, + { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" }, + { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" }, + { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" }, + { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" }, + { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, + { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109, upload-time = "2025-03-05T20:03:17.769Z" }, + { url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343, upload-time = "2025-03-05T20:03:19.094Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599, upload-time = "2025-03-05T20:03:21.1Z" }, + { url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207, upload-time = "2025-03-05T20:03:23.221Z" }, + { url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155, upload-time = "2025-03-05T20:03:25.321Z" }, + { url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884, upload-time = "2025-03-05T20:03:27.934Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, ] [[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 } -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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/4b/0d/9d4b5219ae4393f718699ca1c05f5ebc0c40d076f7e65fd48f5f693294fb/wrapt-1.17.2-cp310-cp310-win32.whl", hash = "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563", size = 36427 }, - { url = "https://files.pythonhosted.org/packages/72/6a/c5a83e8f61aec1e1aeef939807602fb880e5872371e95df2137142f5c58e/wrapt-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f", size = 38774 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/8f/fa/9fb6e594f2ce03ef03eddbdb5f4f90acb1452221a5351116c7c4708ac865/wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317", size = 36419 }, - { url = "https://files.pythonhosted.org/packages/47/f8/fb1773491a253cbc123c5d5dc15c86041f746ed30416535f2a8df1f4a392/wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3", size = 38773 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/17/27/4fe749a54e7fae6e7146f1c7d914d28ef599dacd4416566c055564080fe2/wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", size = 36672 }, - { url = "https://files.pythonhosted.org/packages/15/06/1dbf478ea45c03e78a6a8c4be4fdc3c3bddea5c8de8a93bc971415e47f0f/wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", size = 38865 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/f9/f0/13925f4bd6548013038cdeb11ee2cbd4e37c30f8bfd5db9e5a2a370d6e20/wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", size = 36676 }, - { url = "https://files.pythonhosted.org/packages/bf/ae/743f16ef8c2e3628df3ddfd652b7d4c555d12c84b53f3d8218498f4ade9b/wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", size = 38871 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/6a/e1/0122853035b40b3f333bbb25f1939fc1045e21dd518f7f0922b60c156f7c/wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", size = 37986 }, - { url = "https://files.pythonhosted.org/packages/09/5e/1655cf481e079c1f22d0cabdd4e51733679932718dc23bf2db175f329b76/wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", size = 40750 }, - { url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594 }, +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]] @@ -4835,103 +4930,103 @@ dependencies = [ { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/51/c0edba5219027f6eab262e139f73e2417b0f4efffa23bf562f6e18f76ca5/yarl-1.20.0.tar.gz", hash = "sha256:686d51e51ee5dfe62dec86e4866ee0e9ed66df700d55c828a615640adc885307", size = 185258 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/00/ab/66082639f99d7ef647a86b2ff4ca20f8ae13bd68a6237e6e166b8eb92edf/yarl-1.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f1f6670b9ae3daedb325fa55fbe31c22c8228f6e0b513772c2e1c623caa6ab22", size = 145054 }, - { url = "https://files.pythonhosted.org/packages/3d/c2/4e78185c453c3ca02bd11c7907394d0410d26215f9e4b7378648b3522a30/yarl-1.20.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85a231fa250dfa3308f3c7896cc007a47bc76e9e8e8595c20b7426cac4884c62", size = 96811 }, - { url = "https://files.pythonhosted.org/packages/c7/45/91e31dccdcf5b7232dcace78bd51a1bb2d7b4b96c65eece0078b620587d1/yarl-1.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a06701b647c9939d7019acdfa7ebbfbb78ba6aa05985bb195ad716ea759a569", size = 94566 }, - { url = "https://files.pythonhosted.org/packages/c8/21/e0aa650bcee881fb804331faa2c0f9a5d6be7609970b2b6e3cdd414e174b/yarl-1.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7595498d085becc8fb9203aa314b136ab0516c7abd97e7d74f7bb4eb95042abe", size = 327297 }, - { url = "https://files.pythonhosted.org/packages/1a/a4/58f10870f5c17595c5a37da4c6a0b321589b7d7976e10570088d445d0f47/yarl-1.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af5607159085dcdb055d5678fc2d34949bd75ae6ea6b4381e784bbab1c3aa195", size = 323578 }, - { url = "https://files.pythonhosted.org/packages/07/df/2506b1382cc0c4bb0d22a535dc3e7ccd53da9a59b411079013a7904ac35c/yarl-1.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:95b50910e496567434cb77a577493c26bce0f31c8a305135f3bda6a2483b8e10", size = 343212 }, - { url = "https://files.pythonhosted.org/packages/ba/4a/d1c901d0e2158ad06bb0b9a92473e32d992f98673b93c8a06293e091bab0/yarl-1.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b594113a301ad537766b4e16a5a6750fcbb1497dcc1bc8a4daae889e6402a634", size = 337956 }, - { url = "https://files.pythonhosted.org/packages/8b/fd/10fcf7d86f49b1a11096d6846257485ef32e3d3d322e8a7fdea5b127880c/yarl-1.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:083ce0393ea173cd37834eb84df15b6853b555d20c52703e21fbababa8c129d2", size = 333889 }, - { url = "https://files.pythonhosted.org/packages/e2/cd/bae926a25154ba31c5fd15f2aa6e50a545c840e08d85e2e2e0807197946b/yarl-1.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f1a350a652bbbe12f666109fbddfdf049b3ff43696d18c9ab1531fbba1c977a", size = 322282 }, - { url = "https://files.pythonhosted.org/packages/e2/c6/c3ac3597dfde746c63c637c5422cf3954ebf622a8de7f09892d20a68900d/yarl-1.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fb0caeac4a164aadce342f1597297ec0ce261ec4532bbc5a9ca8da5622f53867", size = 336270 }, - { url = "https://files.pythonhosted.org/packages/dd/42/417fd7b8da5846def29712370ea8916a4be2553de42a2c969815153717be/yarl-1.20.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d88cc43e923f324203f6ec14434fa33b85c06d18d59c167a0637164863b8e995", size = 335500 }, - { url = "https://files.pythonhosted.org/packages/37/aa/c2339683f8f05f4be16831b6ad58d04406cf1c7730e48a12f755da9f5ac5/yarl-1.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e52d6ed9ea8fd3abf4031325dc714aed5afcbfa19ee4a89898d663c9976eb487", size = 339672 }, - { url = "https://files.pythonhosted.org/packages/be/12/ab6c4df95f00d7bc9502bf07a92d5354f11d9d3cb855222a6a8d2bd6e8da/yarl-1.20.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce360ae48a5e9961d0c730cf891d40698a82804e85f6e74658fb175207a77cb2", size = 351840 }, - { url = "https://files.pythonhosted.org/packages/83/3c/08d58c51bbd3899be3e7e83cd7a691fdcf3b9f78b8699d663ecc2c090ab7/yarl-1.20.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:06d06c9d5b5bc3eb56542ceeba6658d31f54cf401e8468512447834856fb0e61", size = 359550 }, - { url = "https://files.pythonhosted.org/packages/8a/15/de7906c506f85fb476f0edac4bd74569f49e5ffdcf98e246a0313bf593b9/yarl-1.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c27d98f4e5c4060582f44e58309c1e55134880558f1add7a87c1bc36ecfade19", size = 351108 }, - { url = "https://files.pythonhosted.org/packages/25/04/c6754f5ae2cdf057ac094ac01137c17875b629b1c29ed75354626a755375/yarl-1.20.0-cp310-cp310-win32.whl", hash = "sha256:f4d3fa9b9f013f7050326e165c3279e22850d02ae544ace285674cb6174b5d6d", size = 86733 }, - { url = "https://files.pythonhosted.org/packages/db/1f/5c1952f3d983ac3f5fb079b5b13b62728f8a73fd27d03e1cef7e476addff/yarl-1.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:bc906b636239631d42eb8a07df8359905da02704a868983265603887ed68c076", size = 92916 }, - { url = "https://files.pythonhosted.org/packages/60/82/a59d8e21b20ffc836775fa7daedac51d16bb8f3010c4fcb495c4496aa922/yarl-1.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fdb5204d17cb32b2de2d1e21c7461cabfacf17f3645e4b9039f210c5d3378bf3", size = 145178 }, - { url = "https://files.pythonhosted.org/packages/ba/81/315a3f6f95947cfbf37c92d6fbce42a1a6207b6c38e8c2b452499ec7d449/yarl-1.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eaddd7804d8e77d67c28d154ae5fab203163bd0998769569861258e525039d2a", size = 96859 }, - { url = "https://files.pythonhosted.org/packages/ad/17/9b64e575583158551b72272a1023cdbd65af54fe13421d856b2850a6ddb7/yarl-1.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:634b7ba6b4a85cf67e9df7c13a7fb2e44fa37b5d34501038d174a63eaac25ee2", size = 94647 }, - { url = "https://files.pythonhosted.org/packages/2c/29/8f291e7922a58a21349683f6120a85701aeefaa02e9f7c8a2dc24fe3f431/yarl-1.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d409e321e4addf7d97ee84162538c7258e53792eb7c6defd0c33647d754172e", size = 355788 }, - { url = "https://files.pythonhosted.org/packages/26/6d/b4892c80b805c42c228c6d11e03cafabf81662d371b0853e7f0f513837d5/yarl-1.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ea52f7328a36960ba3231c6677380fa67811b414798a6e071c7085c57b6d20a9", size = 344613 }, - { url = "https://files.pythonhosted.org/packages/d7/0e/517aa28d3f848589bae9593717b063a544b86ba0a807d943c70f48fcf3bb/yarl-1.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8703517b924463994c344dcdf99a2d5ce9eca2b6882bb640aa555fb5efc706a", size = 370953 }, - { url = "https://files.pythonhosted.org/packages/5f/9b/5bd09d2f1ad6e6f7c2beae9e50db78edd2cca4d194d227b958955573e240/yarl-1.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:077989b09ffd2f48fb2d8f6a86c5fef02f63ffe6b1dd4824c76de7bb01e4f2e2", size = 369204 }, - { url = "https://files.pythonhosted.org/packages/9c/85/d793a703cf4bd0d4cd04e4b13cc3d44149470f790230430331a0c1f52df5/yarl-1.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0acfaf1da020253f3533526e8b7dd212838fdc4109959a2c53cafc6db611bff2", size = 358108 }, - { url = "https://files.pythonhosted.org/packages/6f/54/b6c71e13549c1f6048fbc14ce8d930ac5fb8bafe4f1a252e621a24f3f1f9/yarl-1.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4230ac0b97ec5eeb91d96b324d66060a43fd0d2a9b603e3327ed65f084e41f8", size = 346610 }, - { url = "https://files.pythonhosted.org/packages/a0/1a/d6087d58bdd0d8a2a37bbcdffac9d9721af6ebe50d85304d9f9b57dfd862/yarl-1.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a6a1e6ae21cdd84011c24c78d7a126425148b24d437b5702328e4ba640a8902", size = 365378 }, - { url = "https://files.pythonhosted.org/packages/02/84/e25ddff4cbc001dbc4af76f8d41a3e23818212dd1f0a52044cbc60568872/yarl-1.20.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:86de313371ec04dd2531f30bc41a5a1a96f25a02823558ee0f2af0beaa7ca791", size = 356919 }, - { url = "https://files.pythonhosted.org/packages/04/76/898ae362353bf8f64636495d222c8014c8e5267df39b1a9fe1e1572fb7d0/yarl-1.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dd59c9dd58ae16eaa0f48c3d0cbe6be8ab4dc7247c3ff7db678edecbaf59327f", size = 364248 }, - { url = "https://files.pythonhosted.org/packages/1b/b0/9d9198d83a622f1c40fdbf7bd13b224a6979f2e1fc2cf50bfb1d8773c495/yarl-1.20.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a0bc5e05f457b7c1994cc29e83b58f540b76234ba6b9648a4971ddc7f6aa52da", size = 378418 }, - { url = "https://files.pythonhosted.org/packages/c7/ce/1f50c1cc594cf5d3f5bf4a9b616fca68680deaec8ad349d928445ac52eb8/yarl-1.20.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c9471ca18e6aeb0e03276b5e9b27b14a54c052d370a9c0c04a68cefbd1455eb4", size = 383850 }, - { url = "https://files.pythonhosted.org/packages/89/1e/a59253a87b35bfec1a25bb5801fb69943330b67cfd266278eb07e0609012/yarl-1.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:40ed574b4df723583a26c04b298b283ff171bcc387bc34c2683235e2487a65a5", size = 381218 }, - { url = "https://files.pythonhosted.org/packages/85/b0/26f87df2b3044b0ef1a7cf66d321102bdca091db64c5ae853fcb2171c031/yarl-1.20.0-cp311-cp311-win32.whl", hash = "sha256:db243357c6c2bf3cd7e17080034ade668d54ce304d820c2a58514a4e51d0cfd6", size = 86606 }, - { url = "https://files.pythonhosted.org/packages/33/46/ca335c2e1f90446a77640a45eeb1cd8f6934f2c6e4df7db0f0f36ef9f025/yarl-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c12cd754d9dbd14204c328915e23b0c361b88f3cffd124129955e60a4fbfcfb", size = 93374 }, - { url = "https://files.pythonhosted.org/packages/c3/e8/3efdcb83073df978bb5b1a9cc0360ce596680e6c3fac01f2a994ccbb8939/yarl-1.20.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e06b9f6cdd772f9b665e5ba8161968e11e403774114420737f7884b5bd7bdf6f", size = 147089 }, - { url = "https://files.pythonhosted.org/packages/60/c3/9e776e98ea350f76f94dd80b408eaa54e5092643dbf65fd9babcffb60509/yarl-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b9ae2fbe54d859b3ade40290f60fe40e7f969d83d482e84d2c31b9bff03e359e", size = 97706 }, - { url = "https://files.pythonhosted.org/packages/0c/5b/45cdfb64a3b855ce074ae607b9fc40bc82e7613b94e7612b030255c93a09/yarl-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d12b8945250d80c67688602c891237994d203d42427cb14e36d1a732eda480e", size = 95719 }, - { url = "https://files.pythonhosted.org/packages/2d/4e/929633b249611eeed04e2f861a14ed001acca3ef9ec2a984a757b1515889/yarl-1.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087e9731884621b162a3e06dc0d2d626e1542a617f65ba7cc7aeab279d55ad33", size = 343972 }, - { url = "https://files.pythonhosted.org/packages/49/fd/047535d326c913f1a90407a3baf7ff535b10098611eaef2c527e32e81ca1/yarl-1.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:69df35468b66c1a6e6556248e6443ef0ec5f11a7a4428cf1f6281f1879220f58", size = 339639 }, - { url = "https://files.pythonhosted.org/packages/48/2f/11566f1176a78f4bafb0937c0072410b1b0d3640b297944a6a7a556e1d0b/yarl-1.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2992fe29002fd0d4cbaea9428b09af9b8686a9024c840b8a2b8f4ea4abc16f", size = 353745 }, - { url = "https://files.pythonhosted.org/packages/26/17/07dfcf034d6ae8837b33988be66045dd52f878dfb1c4e8f80a7343f677be/yarl-1.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c903e0b42aab48abfbac668b5a9d7b6938e721a6341751331bcd7553de2dcae", size = 354178 }, - { url = "https://files.pythonhosted.org/packages/15/45/212604d3142d84b4065d5f8cab6582ed3d78e4cc250568ef2a36fe1cf0a5/yarl-1.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf099e2432131093cc611623e0b0bcc399b8cddd9a91eded8bfb50402ec35018", size = 349219 }, - { url = "https://files.pythonhosted.org/packages/e6/e0/a10b30f294111c5f1c682461e9459935c17d467a760c21e1f7db400ff499/yarl-1.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a7f62f5dc70a6c763bec9ebf922be52aa22863d9496a9a30124d65b489ea672", size = 337266 }, - { url = "https://files.pythonhosted.org/packages/33/a6/6efa1d85a675d25a46a167f9f3e80104cde317dfdf7f53f112ae6b16a60a/yarl-1.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:54ac15a8b60382b2bcefd9a289ee26dc0920cf59b05368c9b2b72450751c6eb8", size = 360873 }, - { url = "https://files.pythonhosted.org/packages/77/67/c8ab718cb98dfa2ae9ba0f97bf3cbb7d45d37f13fe1fbad25ac92940954e/yarl-1.20.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:25b3bc0763a7aca16a0f1b5e8ef0f23829df11fb539a1b70476dcab28bd83da7", size = 360524 }, - { url = "https://files.pythonhosted.org/packages/bd/e8/c3f18660cea1bc73d9f8a2b3ef423def8dadbbae6c4afabdb920b73e0ead/yarl-1.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2586e36dc070fc8fad6270f93242124df68b379c3a251af534030a4a33ef594", size = 365370 }, - { url = "https://files.pythonhosted.org/packages/c9/99/33f3b97b065e62ff2d52817155a89cfa030a1a9b43fee7843ef560ad9603/yarl-1.20.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:866349da9d8c5290cfefb7fcc47721e94de3f315433613e01b435473be63daa6", size = 373297 }, - { url = "https://files.pythonhosted.org/packages/3d/89/7519e79e264a5f08653d2446b26d4724b01198a93a74d2e259291d538ab1/yarl-1.20.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:33bb660b390a0554d41f8ebec5cd4475502d84104b27e9b42f5321c5192bfcd1", size = 378771 }, - { url = "https://files.pythonhosted.org/packages/3a/58/6c460bbb884abd2917c3eef6f663a4a873f8dc6f498561fc0ad92231c113/yarl-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737e9f171e5a07031cbee5e9180f6ce21a6c599b9d4b2c24d35df20a52fabf4b", size = 375000 }, - { url = "https://files.pythonhosted.org/packages/3b/2a/dd7ed1aa23fea996834278d7ff178f215b24324ee527df53d45e34d21d28/yarl-1.20.0-cp312-cp312-win32.whl", hash = "sha256:839de4c574169b6598d47ad61534e6981979ca2c820ccb77bf70f4311dd2cc64", size = 86355 }, - { url = "https://files.pythonhosted.org/packages/ca/c6/333fe0338305c0ac1c16d5aa7cc4841208d3252bbe62172e0051006b5445/yarl-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7dbbe44b443b0c4aa0971cb07dcb2c2060e4a9bf8d1301140a33a93c98e18c", size = 92904 }, - { url = "https://files.pythonhosted.org/packages/0f/6f/514c9bff2900c22a4f10e06297714dbaf98707143b37ff0bcba65a956221/yarl-1.20.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2137810a20b933b1b1b7e5cf06a64c3ed3b4747b0e5d79c9447c00db0e2f752f", size = 145030 }, - { url = "https://files.pythonhosted.org/packages/4e/9d/f88da3fa319b8c9c813389bfb3463e8d777c62654c7168e580a13fadff05/yarl-1.20.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:447c5eadd750db8389804030d15f43d30435ed47af1313303ed82a62388176d3", size = 96894 }, - { url = "https://files.pythonhosted.org/packages/cd/57/92e83538580a6968b2451d6c89c5579938a7309d4785748e8ad42ddafdce/yarl-1.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42fbe577272c203528d402eec8bf4b2d14fd49ecfec92272334270b850e9cd7d", size = 94457 }, - { url = "https://files.pythonhosted.org/packages/e9/ee/7ee43bd4cf82dddd5da97fcaddb6fa541ab81f3ed564c42f146c83ae17ce/yarl-1.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18e321617de4ab170226cd15006a565d0fa0d908f11f724a2c9142d6b2812ab0", size = 343070 }, - { url = "https://files.pythonhosted.org/packages/4a/12/b5eccd1109e2097bcc494ba7dc5de156e41cf8309fab437ebb7c2b296ce3/yarl-1.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4345f58719825bba29895011e8e3b545e6e00257abb984f9f27fe923afca2501", size = 337739 }, - { url = "https://files.pythonhosted.org/packages/7d/6b/0eade8e49af9fc2585552f63c76fa59ef469c724cc05b29519b19aa3a6d5/yarl-1.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d9b980d7234614bc4674468ab173ed77d678349c860c3af83b1fffb6a837ddc", size = 351338 }, - { url = "https://files.pythonhosted.org/packages/45/cb/aaaa75d30087b5183c7b8a07b4fb16ae0682dd149a1719b3a28f54061754/yarl-1.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af4baa8a445977831cbaa91a9a84cc09debb10bc8391f128da2f7bd070fc351d", size = 353636 }, - { url = "https://files.pythonhosted.org/packages/98/9d/d9cb39ec68a91ba6e66fa86d97003f58570327d6713833edf7ad6ce9dde5/yarl-1.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123393db7420e71d6ce40d24885a9e65eb1edefc7a5228db2d62bcab3386a5c0", size = 348061 }, - { url = "https://files.pythonhosted.org/packages/72/6b/103940aae893d0cc770b4c36ce80e2ed86fcb863d48ea80a752b8bda9303/yarl-1.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab47acc9332f3de1b39e9b702d9c916af7f02656b2a86a474d9db4e53ef8fd7a", size = 334150 }, - { url = "https://files.pythonhosted.org/packages/ef/b2/986bd82aa222c3e6b211a69c9081ba46484cffa9fab2a5235e8d18ca7a27/yarl-1.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4a34c52ed158f89876cba9c600b2c964dfc1ca52ba7b3ab6deb722d1d8be6df2", size = 362207 }, - { url = "https://files.pythonhosted.org/packages/14/7c/63f5922437b873795d9422cbe7eb2509d4b540c37ae5548a4bb68fd2c546/yarl-1.20.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:04d8cfb12714158abf2618f792c77bc5c3d8c5f37353e79509608be4f18705c9", size = 361277 }, - { url = "https://files.pythonhosted.org/packages/81/83/450938cccf732466953406570bdb42c62b5ffb0ac7ac75a1f267773ab5c8/yarl-1.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7dc63ad0d541c38b6ae2255aaa794434293964677d5c1ec5d0116b0e308031f5", size = 364990 }, - { url = "https://files.pythonhosted.org/packages/b4/de/af47d3a47e4a833693b9ec8e87debb20f09d9fdc9139b207b09a3e6cbd5a/yarl-1.20.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d02b591a64e4e6ca18c5e3d925f11b559c763b950184a64cf47d74d7e41877", size = 374684 }, - { url = "https://files.pythonhosted.org/packages/62/0b/078bcc2d539f1faffdc7d32cb29a2d7caa65f1a6f7e40795d8485db21851/yarl-1.20.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:95fc9876f917cac7f757df80a5dda9de59d423568460fe75d128c813b9af558e", size = 382599 }, - { url = "https://files.pythonhosted.org/packages/74/a9/4fdb1a7899f1fb47fd1371e7ba9e94bff73439ce87099d5dd26d285fffe0/yarl-1.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb769ae5760cd1c6a712135ee7915f9d43f11d9ef769cb3f75a23e398a92d384", size = 378573 }, - { url = "https://files.pythonhosted.org/packages/fd/be/29f5156b7a319e4d2e5b51ce622b4dfb3aa8d8204cd2a8a339340fbfad40/yarl-1.20.0-cp313-cp313-win32.whl", hash = "sha256:70e0c580a0292c7414a1cead1e076c9786f685c1fc4757573d2967689b370e62", size = 86051 }, - { url = "https://files.pythonhosted.org/packages/52/56/05fa52c32c301da77ec0b5f63d2d9605946fe29defacb2a7ebd473c23b81/yarl-1.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:4c43030e4b0af775a85be1fa0433119b1565673266a70bf87ef68a9d5ba3174c", size = 92742 }, - { url = "https://files.pythonhosted.org/packages/d4/2f/422546794196519152fc2e2f475f0e1d4d094a11995c81a465faf5673ffd/yarl-1.20.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b6c4c3d0d6a0ae9b281e492b1465c72de433b782e6b5001c8e7249e085b69051", size = 163575 }, - { url = "https://files.pythonhosted.org/packages/90/fc/67c64ddab6c0b4a169d03c637fb2d2a212b536e1989dec8e7e2c92211b7f/yarl-1.20.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8681700f4e4df891eafa4f69a439a6e7d480d64e52bf460918f58e443bd3da7d", size = 106121 }, - { url = "https://files.pythonhosted.org/packages/6d/00/29366b9eba7b6f6baed7d749f12add209b987c4cfbfa418404dbadc0f97c/yarl-1.20.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:84aeb556cb06c00652dbf87c17838eb6d92cfd317799a8092cee0e570ee11229", size = 103815 }, - { url = "https://files.pythonhosted.org/packages/28/f4/a2a4c967c8323c03689383dff73396281ced3b35d0ed140580825c826af7/yarl-1.20.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f166eafa78810ddb383e930d62e623d288fb04ec566d1b4790099ae0f31485f1", size = 408231 }, - { url = "https://files.pythonhosted.org/packages/0f/a1/66f7ffc0915877d726b70cc7a896ac30b6ac5d1d2760613603b022173635/yarl-1.20.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5d3d6d14754aefc7a458261027a562f024d4f6b8a798adb472277f675857b1eb", size = 390221 }, - { url = "https://files.pythonhosted.org/packages/41/15/cc248f0504610283271615e85bf38bc014224122498c2016d13a3a1b8426/yarl-1.20.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a8f64df8ed5d04c51260dbae3cc82e5649834eebea9eadfd829837b8093eb00", size = 411400 }, - { url = "https://files.pythonhosted.org/packages/5c/af/f0823d7e092bfb97d24fce6c7269d67fcd1aefade97d0a8189c4452e4d5e/yarl-1.20.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d9949eaf05b4d30e93e4034a7790634bbb41b8be2d07edd26754f2e38e491de", size = 411714 }, - { url = "https://files.pythonhosted.org/packages/83/70/be418329eae64b9f1b20ecdaac75d53aef098797d4c2299d82ae6f8e4663/yarl-1.20.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c366b254082d21cc4f08f522ac201d0d83a8b8447ab562732931d31d80eb2a5", size = 404279 }, - { url = "https://files.pythonhosted.org/packages/19/f5/52e02f0075f65b4914eb890eea1ba97e6fd91dd821cc33a623aa707b2f67/yarl-1.20.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91bc450c80a2e9685b10e34e41aef3d44ddf99b3a498717938926d05ca493f6a", size = 384044 }, - { url = "https://files.pythonhosted.org/packages/6a/36/b0fa25226b03d3f769c68d46170b3e92b00ab3853d73127273ba22474697/yarl-1.20.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c2aa4387de4bc3a5fe158080757748d16567119bef215bec643716b4fbf53f9", size = 416236 }, - { url = "https://files.pythonhosted.org/packages/cb/3a/54c828dd35f6831dfdd5a79e6c6b4302ae2c5feca24232a83cb75132b205/yarl-1.20.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d2cbca6760a541189cf87ee54ff891e1d9ea6406079c66341008f7ef6ab61145", size = 402034 }, - { url = "https://files.pythonhosted.org/packages/10/97/c7bf5fba488f7e049f9ad69c1b8fdfe3daa2e8916b3d321aa049e361a55a/yarl-1.20.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:798a5074e656f06b9fad1a162be5a32da45237ce19d07884d0b67a0aa9d5fdda", size = 407943 }, - { url = "https://files.pythonhosted.org/packages/fd/a4/022d2555c1e8fcff08ad7f0f43e4df3aba34f135bff04dd35d5526ce54ab/yarl-1.20.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f106e75c454288472dbe615accef8248c686958c2e7dd3b8d8ee2669770d020f", size = 423058 }, - { url = "https://files.pythonhosted.org/packages/4c/f6/0873a05563e5df29ccf35345a6ae0ac9e66588b41fdb7043a65848f03139/yarl-1.20.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:3b60a86551669c23dc5445010534d2c5d8a4e012163218fc9114e857c0586fdd", size = 423792 }, - { url = "https://files.pythonhosted.org/packages/9e/35/43fbbd082708fa42e923f314c24f8277a28483d219e049552e5007a9aaca/yarl-1.20.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e429857e341d5e8e15806118e0294f8073ba9c4580637e59ab7b238afca836f", size = 422242 }, - { url = "https://files.pythonhosted.org/packages/ed/f7/f0f2500cf0c469beb2050b522c7815c575811627e6d3eb9ec7550ddd0bfe/yarl-1.20.0-cp313-cp313t-win32.whl", hash = "sha256:65a4053580fe88a63e8e4056b427224cd01edfb5f951498bfefca4052f0ce0ac", size = 93816 }, - { url = "https://files.pythonhosted.org/packages/3f/93/f73b61353b2a699d489e782c3f5998b59f974ec3156a2050a52dfd7e8946/yarl-1.20.0-cp313-cp313t-win_amd64.whl", hash = "sha256:53b2da3a6ca0a541c1ae799c349788d480e5144cac47dba0266c7cb6c76151fe", size = 101093 }, - { url = "https://files.pythonhosted.org/packages/ea/1f/70c57b3d7278e94ed22d85e09685d3f0a38ebdd8c5c73b65ba4c0d0fe002/yarl-1.20.0-py3-none-any.whl", hash = "sha256:5d0fe6af927a47a230f31e6004621fd0959eaa915fc62acfafa67ff7229a3124", size = 46124 }, +sdist = { url = "https://files.pythonhosted.org/packages/62/51/c0edba5219027f6eab262e139f73e2417b0f4efffa23bf562f6e18f76ca5/yarl-1.20.0.tar.gz", hash = "sha256:686d51e51ee5dfe62dec86e4866ee0e9ed66df700d55c828a615640adc885307", size = 185258, upload-time = "2025-04-17T00:45:14.661Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/ab/66082639f99d7ef647a86b2ff4ca20f8ae13bd68a6237e6e166b8eb92edf/yarl-1.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f1f6670b9ae3daedb325fa55fbe31c22c8228f6e0b513772c2e1c623caa6ab22", size = 145054, upload-time = "2025-04-17T00:41:27.071Z" }, + { url = "https://files.pythonhosted.org/packages/3d/c2/4e78185c453c3ca02bd11c7907394d0410d26215f9e4b7378648b3522a30/yarl-1.20.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85a231fa250dfa3308f3c7896cc007a47bc76e9e8e8595c20b7426cac4884c62", size = 96811, upload-time = "2025-04-17T00:41:30.235Z" }, + { url = "https://files.pythonhosted.org/packages/c7/45/91e31dccdcf5b7232dcace78bd51a1bb2d7b4b96c65eece0078b620587d1/yarl-1.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a06701b647c9939d7019acdfa7ebbfbb78ba6aa05985bb195ad716ea759a569", size = 94566, upload-time = "2025-04-17T00:41:32.023Z" }, + { url = "https://files.pythonhosted.org/packages/c8/21/e0aa650bcee881fb804331faa2c0f9a5d6be7609970b2b6e3cdd414e174b/yarl-1.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7595498d085becc8fb9203aa314b136ab0516c7abd97e7d74f7bb4eb95042abe", size = 327297, upload-time = "2025-04-17T00:41:34.03Z" }, + { url = "https://files.pythonhosted.org/packages/1a/a4/58f10870f5c17595c5a37da4c6a0b321589b7d7976e10570088d445d0f47/yarl-1.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af5607159085dcdb055d5678fc2d34949bd75ae6ea6b4381e784bbab1c3aa195", size = 323578, upload-time = "2025-04-17T00:41:36.492Z" }, + { url = "https://files.pythonhosted.org/packages/07/df/2506b1382cc0c4bb0d22a535dc3e7ccd53da9a59b411079013a7904ac35c/yarl-1.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:95b50910e496567434cb77a577493c26bce0f31c8a305135f3bda6a2483b8e10", size = 343212, upload-time = "2025-04-17T00:41:38.396Z" }, + { url = "https://files.pythonhosted.org/packages/ba/4a/d1c901d0e2158ad06bb0b9a92473e32d992f98673b93c8a06293e091bab0/yarl-1.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b594113a301ad537766b4e16a5a6750fcbb1497dcc1bc8a4daae889e6402a634", size = 337956, upload-time = "2025-04-17T00:41:40.519Z" }, + { url = "https://files.pythonhosted.org/packages/8b/fd/10fcf7d86f49b1a11096d6846257485ef32e3d3d322e8a7fdea5b127880c/yarl-1.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:083ce0393ea173cd37834eb84df15b6853b555d20c52703e21fbababa8c129d2", size = 333889, upload-time = "2025-04-17T00:41:42.437Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cd/bae926a25154ba31c5fd15f2aa6e50a545c840e08d85e2e2e0807197946b/yarl-1.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f1a350a652bbbe12f666109fbddfdf049b3ff43696d18c9ab1531fbba1c977a", size = 322282, upload-time = "2025-04-17T00:41:44.641Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c6/c3ac3597dfde746c63c637c5422cf3954ebf622a8de7f09892d20a68900d/yarl-1.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fb0caeac4a164aadce342f1597297ec0ce261ec4532bbc5a9ca8da5622f53867", size = 336270, upload-time = "2025-04-17T00:41:46.812Z" }, + { url = "https://files.pythonhosted.org/packages/dd/42/417fd7b8da5846def29712370ea8916a4be2553de42a2c969815153717be/yarl-1.20.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d88cc43e923f324203f6ec14434fa33b85c06d18d59c167a0637164863b8e995", size = 335500, upload-time = "2025-04-17T00:41:48.896Z" }, + { url = "https://files.pythonhosted.org/packages/37/aa/c2339683f8f05f4be16831b6ad58d04406cf1c7730e48a12f755da9f5ac5/yarl-1.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e52d6ed9ea8fd3abf4031325dc714aed5afcbfa19ee4a89898d663c9976eb487", size = 339672, upload-time = "2025-04-17T00:41:50.965Z" }, + { url = "https://files.pythonhosted.org/packages/be/12/ab6c4df95f00d7bc9502bf07a92d5354f11d9d3cb855222a6a8d2bd6e8da/yarl-1.20.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce360ae48a5e9961d0c730cf891d40698a82804e85f6e74658fb175207a77cb2", size = 351840, upload-time = "2025-04-17T00:41:53.074Z" }, + { url = "https://files.pythonhosted.org/packages/83/3c/08d58c51bbd3899be3e7e83cd7a691fdcf3b9f78b8699d663ecc2c090ab7/yarl-1.20.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:06d06c9d5b5bc3eb56542ceeba6658d31f54cf401e8468512447834856fb0e61", size = 359550, upload-time = "2025-04-17T00:41:55.517Z" }, + { url = "https://files.pythonhosted.org/packages/8a/15/de7906c506f85fb476f0edac4bd74569f49e5ffdcf98e246a0313bf593b9/yarl-1.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c27d98f4e5c4060582f44e58309c1e55134880558f1add7a87c1bc36ecfade19", size = 351108, upload-time = "2025-04-17T00:41:57.582Z" }, + { url = "https://files.pythonhosted.org/packages/25/04/c6754f5ae2cdf057ac094ac01137c17875b629b1c29ed75354626a755375/yarl-1.20.0-cp310-cp310-win32.whl", hash = "sha256:f4d3fa9b9f013f7050326e165c3279e22850d02ae544ace285674cb6174b5d6d", size = 86733, upload-time = "2025-04-17T00:41:59.757Z" }, + { url = "https://files.pythonhosted.org/packages/db/1f/5c1952f3d983ac3f5fb079b5b13b62728f8a73fd27d03e1cef7e476addff/yarl-1.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:bc906b636239631d42eb8a07df8359905da02704a868983265603887ed68c076", size = 92916, upload-time = "2025-04-17T00:42:02.177Z" }, + { url = "https://files.pythonhosted.org/packages/60/82/a59d8e21b20ffc836775fa7daedac51d16bb8f3010c4fcb495c4496aa922/yarl-1.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fdb5204d17cb32b2de2d1e21c7461cabfacf17f3645e4b9039f210c5d3378bf3", size = 145178, upload-time = "2025-04-17T00:42:04.511Z" }, + { url = "https://files.pythonhosted.org/packages/ba/81/315a3f6f95947cfbf37c92d6fbce42a1a6207b6c38e8c2b452499ec7d449/yarl-1.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eaddd7804d8e77d67c28d154ae5fab203163bd0998769569861258e525039d2a", size = 96859, upload-time = "2025-04-17T00:42:06.43Z" }, + { url = "https://files.pythonhosted.org/packages/ad/17/9b64e575583158551b72272a1023cdbd65af54fe13421d856b2850a6ddb7/yarl-1.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:634b7ba6b4a85cf67e9df7c13a7fb2e44fa37b5d34501038d174a63eaac25ee2", size = 94647, upload-time = "2025-04-17T00:42:07.976Z" }, + { url = "https://files.pythonhosted.org/packages/2c/29/8f291e7922a58a21349683f6120a85701aeefaa02e9f7c8a2dc24fe3f431/yarl-1.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d409e321e4addf7d97ee84162538c7258e53792eb7c6defd0c33647d754172e", size = 355788, upload-time = "2025-04-17T00:42:09.902Z" }, + { url = "https://files.pythonhosted.org/packages/26/6d/b4892c80b805c42c228c6d11e03cafabf81662d371b0853e7f0f513837d5/yarl-1.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ea52f7328a36960ba3231c6677380fa67811b414798a6e071c7085c57b6d20a9", size = 344613, upload-time = "2025-04-17T00:42:11.768Z" }, + { url = "https://files.pythonhosted.org/packages/d7/0e/517aa28d3f848589bae9593717b063a544b86ba0a807d943c70f48fcf3bb/yarl-1.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8703517b924463994c344dcdf99a2d5ce9eca2b6882bb640aa555fb5efc706a", size = 370953, upload-time = "2025-04-17T00:42:13.983Z" }, + { url = "https://files.pythonhosted.org/packages/5f/9b/5bd09d2f1ad6e6f7c2beae9e50db78edd2cca4d194d227b958955573e240/yarl-1.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:077989b09ffd2f48fb2d8f6a86c5fef02f63ffe6b1dd4824c76de7bb01e4f2e2", size = 369204, upload-time = "2025-04-17T00:42:16.386Z" }, + { url = "https://files.pythonhosted.org/packages/9c/85/d793a703cf4bd0d4cd04e4b13cc3d44149470f790230430331a0c1f52df5/yarl-1.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0acfaf1da020253f3533526e8b7dd212838fdc4109959a2c53cafc6db611bff2", size = 358108, upload-time = "2025-04-17T00:42:18.622Z" }, + { url = "https://files.pythonhosted.org/packages/6f/54/b6c71e13549c1f6048fbc14ce8d930ac5fb8bafe4f1a252e621a24f3f1f9/yarl-1.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4230ac0b97ec5eeb91d96b324d66060a43fd0d2a9b603e3327ed65f084e41f8", size = 346610, upload-time = "2025-04-17T00:42:20.9Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1a/d6087d58bdd0d8a2a37bbcdffac9d9721af6ebe50d85304d9f9b57dfd862/yarl-1.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a6a1e6ae21cdd84011c24c78d7a126425148b24d437b5702328e4ba640a8902", size = 365378, upload-time = "2025-04-17T00:42:22.926Z" }, + { url = "https://files.pythonhosted.org/packages/02/84/e25ddff4cbc001dbc4af76f8d41a3e23818212dd1f0a52044cbc60568872/yarl-1.20.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:86de313371ec04dd2531f30bc41a5a1a96f25a02823558ee0f2af0beaa7ca791", size = 356919, upload-time = "2025-04-17T00:42:25.145Z" }, + { url = "https://files.pythonhosted.org/packages/04/76/898ae362353bf8f64636495d222c8014c8e5267df39b1a9fe1e1572fb7d0/yarl-1.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dd59c9dd58ae16eaa0f48c3d0cbe6be8ab4dc7247c3ff7db678edecbaf59327f", size = 364248, upload-time = "2025-04-17T00:42:27.475Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b0/9d9198d83a622f1c40fdbf7bd13b224a6979f2e1fc2cf50bfb1d8773c495/yarl-1.20.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a0bc5e05f457b7c1994cc29e83b58f540b76234ba6b9648a4971ddc7f6aa52da", size = 378418, upload-time = "2025-04-17T00:42:29.333Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ce/1f50c1cc594cf5d3f5bf4a9b616fca68680deaec8ad349d928445ac52eb8/yarl-1.20.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c9471ca18e6aeb0e03276b5e9b27b14a54c052d370a9c0c04a68cefbd1455eb4", size = 383850, upload-time = "2025-04-17T00:42:31.668Z" }, + { url = "https://files.pythonhosted.org/packages/89/1e/a59253a87b35bfec1a25bb5801fb69943330b67cfd266278eb07e0609012/yarl-1.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:40ed574b4df723583a26c04b298b283ff171bcc387bc34c2683235e2487a65a5", size = 381218, upload-time = "2025-04-17T00:42:33.523Z" }, + { url = "https://files.pythonhosted.org/packages/85/b0/26f87df2b3044b0ef1a7cf66d321102bdca091db64c5ae853fcb2171c031/yarl-1.20.0-cp311-cp311-win32.whl", hash = "sha256:db243357c6c2bf3cd7e17080034ade668d54ce304d820c2a58514a4e51d0cfd6", size = 86606, upload-time = "2025-04-17T00:42:35.873Z" }, + { url = "https://files.pythonhosted.org/packages/33/46/ca335c2e1f90446a77640a45eeb1cd8f6934f2c6e4df7db0f0f36ef9f025/yarl-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c12cd754d9dbd14204c328915e23b0c361b88f3cffd124129955e60a4fbfcfb", size = 93374, upload-time = "2025-04-17T00:42:37.586Z" }, + { url = "https://files.pythonhosted.org/packages/c3/e8/3efdcb83073df978bb5b1a9cc0360ce596680e6c3fac01f2a994ccbb8939/yarl-1.20.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e06b9f6cdd772f9b665e5ba8161968e11e403774114420737f7884b5bd7bdf6f", size = 147089, upload-time = "2025-04-17T00:42:39.602Z" }, + { url = "https://files.pythonhosted.org/packages/60/c3/9e776e98ea350f76f94dd80b408eaa54e5092643dbf65fd9babcffb60509/yarl-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b9ae2fbe54d859b3ade40290f60fe40e7f969d83d482e84d2c31b9bff03e359e", size = 97706, upload-time = "2025-04-17T00:42:41.469Z" }, + { url = "https://files.pythonhosted.org/packages/0c/5b/45cdfb64a3b855ce074ae607b9fc40bc82e7613b94e7612b030255c93a09/yarl-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d12b8945250d80c67688602c891237994d203d42427cb14e36d1a732eda480e", size = 95719, upload-time = "2025-04-17T00:42:43.666Z" }, + { url = "https://files.pythonhosted.org/packages/2d/4e/929633b249611eeed04e2f861a14ed001acca3ef9ec2a984a757b1515889/yarl-1.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087e9731884621b162a3e06dc0d2d626e1542a617f65ba7cc7aeab279d55ad33", size = 343972, upload-time = "2025-04-17T00:42:45.391Z" }, + { url = "https://files.pythonhosted.org/packages/49/fd/047535d326c913f1a90407a3baf7ff535b10098611eaef2c527e32e81ca1/yarl-1.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:69df35468b66c1a6e6556248e6443ef0ec5f11a7a4428cf1f6281f1879220f58", size = 339639, upload-time = "2025-04-17T00:42:47.552Z" }, + { url = "https://files.pythonhosted.org/packages/48/2f/11566f1176a78f4bafb0937c0072410b1b0d3640b297944a6a7a556e1d0b/yarl-1.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2992fe29002fd0d4cbaea9428b09af9b8686a9024c840b8a2b8f4ea4abc16f", size = 353745, upload-time = "2025-04-17T00:42:49.406Z" }, + { url = "https://files.pythonhosted.org/packages/26/17/07dfcf034d6ae8837b33988be66045dd52f878dfb1c4e8f80a7343f677be/yarl-1.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c903e0b42aab48abfbac668b5a9d7b6938e721a6341751331bcd7553de2dcae", size = 354178, upload-time = "2025-04-17T00:42:51.588Z" }, + { url = "https://files.pythonhosted.org/packages/15/45/212604d3142d84b4065d5f8cab6582ed3d78e4cc250568ef2a36fe1cf0a5/yarl-1.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf099e2432131093cc611623e0b0bcc399b8cddd9a91eded8bfb50402ec35018", size = 349219, upload-time = "2025-04-17T00:42:53.674Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e0/a10b30f294111c5f1c682461e9459935c17d467a760c21e1f7db400ff499/yarl-1.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a7f62f5dc70a6c763bec9ebf922be52aa22863d9496a9a30124d65b489ea672", size = 337266, upload-time = "2025-04-17T00:42:55.49Z" }, + { url = "https://files.pythonhosted.org/packages/33/a6/6efa1d85a675d25a46a167f9f3e80104cde317dfdf7f53f112ae6b16a60a/yarl-1.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:54ac15a8b60382b2bcefd9a289ee26dc0920cf59b05368c9b2b72450751c6eb8", size = 360873, upload-time = "2025-04-17T00:42:57.895Z" }, + { url = "https://files.pythonhosted.org/packages/77/67/c8ab718cb98dfa2ae9ba0f97bf3cbb7d45d37f13fe1fbad25ac92940954e/yarl-1.20.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:25b3bc0763a7aca16a0f1b5e8ef0f23829df11fb539a1b70476dcab28bd83da7", size = 360524, upload-time = "2025-04-17T00:43:00.094Z" }, + { url = "https://files.pythonhosted.org/packages/bd/e8/c3f18660cea1bc73d9f8a2b3ef423def8dadbbae6c4afabdb920b73e0ead/yarl-1.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2586e36dc070fc8fad6270f93242124df68b379c3a251af534030a4a33ef594", size = 365370, upload-time = "2025-04-17T00:43:02.242Z" }, + { url = "https://files.pythonhosted.org/packages/c9/99/33f3b97b065e62ff2d52817155a89cfa030a1a9b43fee7843ef560ad9603/yarl-1.20.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:866349da9d8c5290cfefb7fcc47721e94de3f315433613e01b435473be63daa6", size = 373297, upload-time = "2025-04-17T00:43:04.189Z" }, + { url = "https://files.pythonhosted.org/packages/3d/89/7519e79e264a5f08653d2446b26d4724b01198a93a74d2e259291d538ab1/yarl-1.20.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:33bb660b390a0554d41f8ebec5cd4475502d84104b27e9b42f5321c5192bfcd1", size = 378771, upload-time = "2025-04-17T00:43:06.609Z" }, + { url = "https://files.pythonhosted.org/packages/3a/58/6c460bbb884abd2917c3eef6f663a4a873f8dc6f498561fc0ad92231c113/yarl-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737e9f171e5a07031cbee5e9180f6ce21a6c599b9d4b2c24d35df20a52fabf4b", size = 375000, upload-time = "2025-04-17T00:43:09.01Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2a/dd7ed1aa23fea996834278d7ff178f215b24324ee527df53d45e34d21d28/yarl-1.20.0-cp312-cp312-win32.whl", hash = "sha256:839de4c574169b6598d47ad61534e6981979ca2c820ccb77bf70f4311dd2cc64", size = 86355, upload-time = "2025-04-17T00:43:11.311Z" }, + { url = "https://files.pythonhosted.org/packages/ca/c6/333fe0338305c0ac1c16d5aa7cc4841208d3252bbe62172e0051006b5445/yarl-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7dbbe44b443b0c4aa0971cb07dcb2c2060e4a9bf8d1301140a33a93c98e18c", size = 92904, upload-time = "2025-04-17T00:43:13.087Z" }, + { url = "https://files.pythonhosted.org/packages/0f/6f/514c9bff2900c22a4f10e06297714dbaf98707143b37ff0bcba65a956221/yarl-1.20.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2137810a20b933b1b1b7e5cf06a64c3ed3b4747b0e5d79c9447c00db0e2f752f", size = 145030, upload-time = "2025-04-17T00:43:15.083Z" }, + { url = "https://files.pythonhosted.org/packages/4e/9d/f88da3fa319b8c9c813389bfb3463e8d777c62654c7168e580a13fadff05/yarl-1.20.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:447c5eadd750db8389804030d15f43d30435ed47af1313303ed82a62388176d3", size = 96894, upload-time = "2025-04-17T00:43:17.372Z" }, + { url = "https://files.pythonhosted.org/packages/cd/57/92e83538580a6968b2451d6c89c5579938a7309d4785748e8ad42ddafdce/yarl-1.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42fbe577272c203528d402eec8bf4b2d14fd49ecfec92272334270b850e9cd7d", size = 94457, upload-time = "2025-04-17T00:43:19.431Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ee/7ee43bd4cf82dddd5da97fcaddb6fa541ab81f3ed564c42f146c83ae17ce/yarl-1.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18e321617de4ab170226cd15006a565d0fa0d908f11f724a2c9142d6b2812ab0", size = 343070, upload-time = "2025-04-17T00:43:21.426Z" }, + { url = "https://files.pythonhosted.org/packages/4a/12/b5eccd1109e2097bcc494ba7dc5de156e41cf8309fab437ebb7c2b296ce3/yarl-1.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4345f58719825bba29895011e8e3b545e6e00257abb984f9f27fe923afca2501", size = 337739, upload-time = "2025-04-17T00:43:23.634Z" }, + { url = "https://files.pythonhosted.org/packages/7d/6b/0eade8e49af9fc2585552f63c76fa59ef469c724cc05b29519b19aa3a6d5/yarl-1.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d9b980d7234614bc4674468ab173ed77d678349c860c3af83b1fffb6a837ddc", size = 351338, upload-time = "2025-04-17T00:43:25.695Z" }, + { url = "https://files.pythonhosted.org/packages/45/cb/aaaa75d30087b5183c7b8a07b4fb16ae0682dd149a1719b3a28f54061754/yarl-1.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af4baa8a445977831cbaa91a9a84cc09debb10bc8391f128da2f7bd070fc351d", size = 353636, upload-time = "2025-04-17T00:43:27.876Z" }, + { url = "https://files.pythonhosted.org/packages/98/9d/d9cb39ec68a91ba6e66fa86d97003f58570327d6713833edf7ad6ce9dde5/yarl-1.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123393db7420e71d6ce40d24885a9e65eb1edefc7a5228db2d62bcab3386a5c0", size = 348061, upload-time = "2025-04-17T00:43:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/72/6b/103940aae893d0cc770b4c36ce80e2ed86fcb863d48ea80a752b8bda9303/yarl-1.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab47acc9332f3de1b39e9b702d9c916af7f02656b2a86a474d9db4e53ef8fd7a", size = 334150, upload-time = "2025-04-17T00:43:31.742Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b2/986bd82aa222c3e6b211a69c9081ba46484cffa9fab2a5235e8d18ca7a27/yarl-1.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4a34c52ed158f89876cba9c600b2c964dfc1ca52ba7b3ab6deb722d1d8be6df2", size = 362207, upload-time = "2025-04-17T00:43:34.099Z" }, + { url = "https://files.pythonhosted.org/packages/14/7c/63f5922437b873795d9422cbe7eb2509d4b540c37ae5548a4bb68fd2c546/yarl-1.20.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:04d8cfb12714158abf2618f792c77bc5c3d8c5f37353e79509608be4f18705c9", size = 361277, upload-time = "2025-04-17T00:43:36.202Z" }, + { url = "https://files.pythonhosted.org/packages/81/83/450938cccf732466953406570bdb42c62b5ffb0ac7ac75a1f267773ab5c8/yarl-1.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7dc63ad0d541c38b6ae2255aaa794434293964677d5c1ec5d0116b0e308031f5", size = 364990, upload-time = "2025-04-17T00:43:38.551Z" }, + { url = "https://files.pythonhosted.org/packages/b4/de/af47d3a47e4a833693b9ec8e87debb20f09d9fdc9139b207b09a3e6cbd5a/yarl-1.20.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d02b591a64e4e6ca18c5e3d925f11b559c763b950184a64cf47d74d7e41877", size = 374684, upload-time = "2025-04-17T00:43:40.481Z" }, + { url = "https://files.pythonhosted.org/packages/62/0b/078bcc2d539f1faffdc7d32cb29a2d7caa65f1a6f7e40795d8485db21851/yarl-1.20.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:95fc9876f917cac7f757df80a5dda9de59d423568460fe75d128c813b9af558e", size = 382599, upload-time = "2025-04-17T00:43:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/74/a9/4fdb1a7899f1fb47fd1371e7ba9e94bff73439ce87099d5dd26d285fffe0/yarl-1.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb769ae5760cd1c6a712135ee7915f9d43f11d9ef769cb3f75a23e398a92d384", size = 378573, upload-time = "2025-04-17T00:43:44.797Z" }, + { url = "https://files.pythonhosted.org/packages/fd/be/29f5156b7a319e4d2e5b51ce622b4dfb3aa8d8204cd2a8a339340fbfad40/yarl-1.20.0-cp313-cp313-win32.whl", hash = "sha256:70e0c580a0292c7414a1cead1e076c9786f685c1fc4757573d2967689b370e62", size = 86051, upload-time = "2025-04-17T00:43:47.076Z" }, + { url = "https://files.pythonhosted.org/packages/52/56/05fa52c32c301da77ec0b5f63d2d9605946fe29defacb2a7ebd473c23b81/yarl-1.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:4c43030e4b0af775a85be1fa0433119b1565673266a70bf87ef68a9d5ba3174c", size = 92742, upload-time = "2025-04-17T00:43:49.193Z" }, + { url = "https://files.pythonhosted.org/packages/d4/2f/422546794196519152fc2e2f475f0e1d4d094a11995c81a465faf5673ffd/yarl-1.20.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b6c4c3d0d6a0ae9b281e492b1465c72de433b782e6b5001c8e7249e085b69051", size = 163575, upload-time = "2025-04-17T00:43:51.533Z" }, + { url = "https://files.pythonhosted.org/packages/90/fc/67c64ddab6c0b4a169d03c637fb2d2a212b536e1989dec8e7e2c92211b7f/yarl-1.20.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8681700f4e4df891eafa4f69a439a6e7d480d64e52bf460918f58e443bd3da7d", size = 106121, upload-time = "2025-04-17T00:43:53.506Z" }, + { url = "https://files.pythonhosted.org/packages/6d/00/29366b9eba7b6f6baed7d749f12add209b987c4cfbfa418404dbadc0f97c/yarl-1.20.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:84aeb556cb06c00652dbf87c17838eb6d92cfd317799a8092cee0e570ee11229", size = 103815, upload-time = "2025-04-17T00:43:55.41Z" }, + { url = "https://files.pythonhosted.org/packages/28/f4/a2a4c967c8323c03689383dff73396281ced3b35d0ed140580825c826af7/yarl-1.20.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f166eafa78810ddb383e930d62e623d288fb04ec566d1b4790099ae0f31485f1", size = 408231, upload-time = "2025-04-17T00:43:57.825Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a1/66f7ffc0915877d726b70cc7a896ac30b6ac5d1d2760613603b022173635/yarl-1.20.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5d3d6d14754aefc7a458261027a562f024d4f6b8a798adb472277f675857b1eb", size = 390221, upload-time = "2025-04-17T00:44:00.526Z" }, + { url = "https://files.pythonhosted.org/packages/41/15/cc248f0504610283271615e85bf38bc014224122498c2016d13a3a1b8426/yarl-1.20.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a8f64df8ed5d04c51260dbae3cc82e5649834eebea9eadfd829837b8093eb00", size = 411400, upload-time = "2025-04-17T00:44:02.853Z" }, + { url = "https://files.pythonhosted.org/packages/5c/af/f0823d7e092bfb97d24fce6c7269d67fcd1aefade97d0a8189c4452e4d5e/yarl-1.20.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d9949eaf05b4d30e93e4034a7790634bbb41b8be2d07edd26754f2e38e491de", size = 411714, upload-time = "2025-04-17T00:44:04.904Z" }, + { url = "https://files.pythonhosted.org/packages/83/70/be418329eae64b9f1b20ecdaac75d53aef098797d4c2299d82ae6f8e4663/yarl-1.20.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c366b254082d21cc4f08f522ac201d0d83a8b8447ab562732931d31d80eb2a5", size = 404279, upload-time = "2025-04-17T00:44:07.721Z" }, + { url = "https://files.pythonhosted.org/packages/19/f5/52e02f0075f65b4914eb890eea1ba97e6fd91dd821cc33a623aa707b2f67/yarl-1.20.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91bc450c80a2e9685b10e34e41aef3d44ddf99b3a498717938926d05ca493f6a", size = 384044, upload-time = "2025-04-17T00:44:09.708Z" }, + { url = "https://files.pythonhosted.org/packages/6a/36/b0fa25226b03d3f769c68d46170b3e92b00ab3853d73127273ba22474697/yarl-1.20.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c2aa4387de4bc3a5fe158080757748d16567119bef215bec643716b4fbf53f9", size = 416236, upload-time = "2025-04-17T00:44:11.734Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3a/54c828dd35f6831dfdd5a79e6c6b4302ae2c5feca24232a83cb75132b205/yarl-1.20.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d2cbca6760a541189cf87ee54ff891e1d9ea6406079c66341008f7ef6ab61145", size = 402034, upload-time = "2025-04-17T00:44:13.975Z" }, + { url = "https://files.pythonhosted.org/packages/10/97/c7bf5fba488f7e049f9ad69c1b8fdfe3daa2e8916b3d321aa049e361a55a/yarl-1.20.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:798a5074e656f06b9fad1a162be5a32da45237ce19d07884d0b67a0aa9d5fdda", size = 407943, upload-time = "2025-04-17T00:44:16.052Z" }, + { url = "https://files.pythonhosted.org/packages/fd/a4/022d2555c1e8fcff08ad7f0f43e4df3aba34f135bff04dd35d5526ce54ab/yarl-1.20.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f106e75c454288472dbe615accef8248c686958c2e7dd3b8d8ee2669770d020f", size = 423058, upload-time = "2025-04-17T00:44:18.547Z" }, + { url = "https://files.pythonhosted.org/packages/4c/f6/0873a05563e5df29ccf35345a6ae0ac9e66588b41fdb7043a65848f03139/yarl-1.20.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:3b60a86551669c23dc5445010534d2c5d8a4e012163218fc9114e857c0586fdd", size = 423792, upload-time = "2025-04-17T00:44:20.639Z" }, + { url = "https://files.pythonhosted.org/packages/9e/35/43fbbd082708fa42e923f314c24f8277a28483d219e049552e5007a9aaca/yarl-1.20.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e429857e341d5e8e15806118e0294f8073ba9c4580637e59ab7b238afca836f", size = 422242, upload-time = "2025-04-17T00:44:22.851Z" }, + { url = "https://files.pythonhosted.org/packages/ed/f7/f0f2500cf0c469beb2050b522c7815c575811627e6d3eb9ec7550ddd0bfe/yarl-1.20.0-cp313-cp313t-win32.whl", hash = "sha256:65a4053580fe88a63e8e4056b427224cd01edfb5f951498bfefca4052f0ce0ac", size = 93816, upload-time = "2025-04-17T00:44:25.491Z" }, + { url = "https://files.pythonhosted.org/packages/3f/93/f73b61353b2a699d489e782c3f5998b59f974ec3156a2050a52dfd7e8946/yarl-1.20.0-cp313-cp313t-win_amd64.whl", hash = "sha256:53b2da3a6ca0a541c1ae799c349788d480e5144cac47dba0266c7cb6c76151fe", size = 101093, upload-time = "2025-04-17T00:44:27.418Z" }, + { url = "https://files.pythonhosted.org/packages/ea/1f/70c57b3d7278e94ed22d85e09685d3f0a38ebdd8c5c73b65ba4c0d0fe002/yarl-1.20.0-py3-none-any.whl", hash = "sha256:5d0fe6af927a47a230f31e6004621fd0959eaa915fc62acfafa67ff7229a3124", size = 46124, upload-time = "2025-04-17T00:45:12.199Z" }, ] [[package]] name = "zipp" version = "3.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545 } +sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545, upload-time = "2024-11-10T15:05:20.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630 }, + { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630, upload-time = "2024-11-10T15:05:19.275Z" }, ] [[package]] @@ -4941,70 +5036,70 @@ 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 } -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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/65/3a/8f715b97bd7bcfc7342d8adcd99a026cb2fb550e44866a3b6c348e1b0f02/zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813", size = 430596 }, - { url = "https://files.pythonhosted.org/packages/19/b7/b2b9eca5e5a01111e4fe8a8ffb56bdcdf56b12448a24effe6cfe4a252034/zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4", size = 495498 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/79/02/6f6a42cc84459d399bd1a4e1adfc78d4dfe45e56d05b072008d10040e13b/zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160", size = 430586 }, - { url = "https://files.pythonhosted.org/packages/be/a2/4272175d47c623ff78196f3c10e9dc7045c1b9caf3735bf041e65271eca4/zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0", size = 495420 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/e7/54/967c478314e16af5baf849b6ee9d6ea724ae5b100eb506011f045d3d4e16/zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d", size = 430877 }, - { url = "https://files.pythonhosted.org/packages/75/37/872d74bd7739639c4553bf94c84af7d54d8211b626b352bc57f0fd8d1e3f/zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b", size = 495595 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/b0/4c/315ca5c32da7e2dc3455f3b2caee5c8c2246074a61aac6ec3378a97b7136/zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd", size = 430862 }, - { url = "https://files.pythonhosted.org/packages/a2/bf/c6aaba098e2d04781e8f4f7c0ba3c7aa73d00e4c436bcc0cf059a66691d1/zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b", size = 495578 }, +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" }, ] From e56866d7ba2dc0a4433c3e69ca2551b960bb01e4 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Wed, 8 Oct 2025 11:12:32 -0400 Subject: [PATCH 12/25] reformat --- examples/oauth/dynamic_auth/client.py | 5 +- examples/oauth/dynamic_auth/main.py | 118 ++++++++++-------- examples/oauth/preconfigured/main.py | 32 +++-- examples/oauth/preconfigured/oauth_demo.py | 82 +++++++----- .../oauth/preconfigured/workflow_example.py | 109 ++++++++-------- examples/oauth/workflow_pre_auth/client.py | 36 +++--- examples/oauth/workflow_pre_auth/main.py | 80 ++++++------ src/mcp_agent/oauth/flow.py | 23 ++-- src/mcp_agent/oauth/manager.py | 94 ++++++++++---- src/mcp_agent/server/app_server.py | 23 +++- tests/test_audience_validation.py | 16 +-- 11 files changed, 363 insertions(+), 255 deletions(-) diff --git a/examples/oauth/dynamic_auth/client.py b/examples/oauth/dynamic_auth/client.py index 4e7b67c3a..8280e933a 100644 --- a/examples/oauth/dynamic_auth/client.py +++ b/examples/oauth/dynamic_auth/client.py @@ -24,6 +24,7 @@ except Exception: # pragma: no cover _BrokenResourceError = None # type: ignore + async def main(): # Create MCPApp to get the server registry app = MCPApp( @@ -104,7 +105,9 @@ def make_session( data={"tools": [tool.name for tool in tools_result.tools]}, ) - print(await server.call_tool("github_org_search", {"query": "lastmileai"})) + print( + await server.call_tool("github_org_search", {"query": "lastmileai"}) + ) except Exception as e: # Tolerate benign shutdown races from stdio client (BrokenResourceError within ExceptionGroup) if _ExceptionGroup is not None and isinstance(e, _ExceptionGroup): diff --git a/examples/oauth/dynamic_auth/main.py b/examples/oauth/dynamic_auth/main.py index 3eb54728c..5772c595d 100644 --- a/examples/oauth/dynamic_auth/main.py +++ b/examples/oauth/dynamic_auth/main.py @@ -17,8 +17,17 @@ from mcp_agent.app import MCPApp from mcp_agent.server.app_server import create_mcp_server_for_app -from mcp_agent.config import MCPServerSettings, Settings, LoggerSettings, MCPSettings, MCPServerAuthSettings, \ - MCPOAuthClientSettings, OAuthSettings, OAuthTokenStoreSettings, TemporalSettings +from mcp_agent.config import ( + MCPServerSettings, + Settings, + LoggerSettings, + MCPSettings, + MCPServerAuthSettings, + MCPOAuthClientSettings, + OAuthSettings, + OAuthTokenStoreSettings, + TemporalSettings, +) # Note: This is purely optional: # if not provided, a default FastMCP server will be created by MCPApp using create_mcp_server_for_app() @@ -26,12 +35,14 @@ # Get client id and secret from environment variables -client_id = os.getenv('GITHUB_CLIENT_ID') -client_secret = os.getenv('GITHUB_CLIENT_SECRET') +client_id = os.getenv("GITHUB_CLIENT_ID") +client_secret = os.getenv("GITHUB_CLIENT_SECRET") if not client_id or not client_secret: - print("\nGitHub client id and/or secret not found in GITHUB_CLIENT_Id and GITHUB_CLIENT_SECRET " - "environment variables.") + print( + "\nGitHub client id and/or secret not found in GITHUB_CLIENT_Id and GITHUB_CLIENT_SECRET " + "environment variables." + ) print("\nTo create these:") print("\n1. Open your profile on github.com and navigate to 'Developer Settings'") print("\n2. Create a new OAuth app and create a client secret for it.") @@ -41,44 +52,46 @@ settings = Settings( - execution_engine="temporal", - temporal=TemporalSettings( - host="localhost:7233", - namespace="default", - task_queue="mcp-agent", - max_concurrent_activities=10, - ), - logger=LoggerSettings(level="info"), - oauth=OAuthSettings( - callback_base_url=AnyHttpUrl("http://localhost:8000"), - flow_timeout_seconds=300, - token_store=OAuthTokenStoreSettings(refresh_leeway_seconds=60), - ), - mcp=MCPSettings( - servers={ - "github": MCPServerSettings( - name="github", - transport="streamable_http", - url="https://api.githubcopilot.com/mcp/", - auth=MCPServerAuthSettings( - oauth=MCPOAuthClientSettings( - client_id=client_id, - client_secret=client_secret, - use_internal_callback=True, - enabled=True, - scopes= [ - "read:org", # Required for search_orgs tool - "public_repo", # Access to public repositories - "user:email" # User information access - ], - authorization_server=AnyHttpUrl("https://github.com/login/oauth"), - resource=AnyHttpUrl("https://api.githubcopilot.com/mcp") - ) + execution_engine="temporal", + temporal=TemporalSettings( + host="localhost:7233", + namespace="default", + task_queue="mcp-agent", + max_concurrent_activities=10, + ), + logger=LoggerSettings(level="info"), + oauth=OAuthSettings( + callback_base_url=AnyHttpUrl("http://localhost:8000"), + flow_timeout_seconds=300, + token_store=OAuthTokenStoreSettings(refresh_leeway_seconds=60), + ), + mcp=MCPSettings( + servers={ + "github": MCPServerSettings( + name="github", + transport="streamable_http", + url="https://api.githubcopilot.com/mcp/", + auth=MCPServerAuthSettings( + oauth=MCPOAuthClientSettings( + client_id=client_id, + client_secret=client_secret, + use_internal_callback=True, + enabled=True, + scopes=[ + "read:org", # Required for search_orgs tool + "public_repo", # Access to public repositories + "user:email", # User information access + ], + authorization_server=AnyHttpUrl( + "https://github.com/login/oauth" + ), + resource=AnyHttpUrl("https://api.githubcopilot.com/mcp"), ) - ) - } - ), - ) + ), + ) + } + ), +) # Define the MCPApp instance. The server created for this app will advertise the # MCP logging capability and forward structured logs upstream to connected clients. @@ -97,29 +110,22 @@ async def github_org_search_activity(query: str) -> str: print("running activity)") try: async with gen_client( - "github", - server_registry=app.context.server_registry, - context=app.context + "github", server_registry=app.context.server_registry, context=app.context ) as github_client: print("got client") result = await github_client.call_tool( "search_orgs", - { - "query": query, - "perPage": 10, - "sort": "best-match", - "order": "desc" - } + {"query": query, "perPage": 10, "sort": "best-match", "order": "desc"}, ) organizations = [] if result.content: for content_item in result.content: - if hasattr(content_item, 'text'): + if hasattr(content_item, "text"): try: data = json.loads(content_item.text) - if isinstance(data, dict) and 'items' in data: - organizations.extend(data['items']) + if isinstance(data, dict) and "items" in data: + organizations.extend(data["items"]) elif isinstance(data, list): organizations.extend(data) except json.JSONDecodeError: @@ -129,9 +135,11 @@ async def github_org_search_activity(query: str) -> str: return str(organizations) except Exception as e: import traceback + traceback.print_exc() return f"Error: {e}" + @app.tool(name="github_org_search") async def github_org_search(query: str) -> str: if app._logger and hasattr(app._logger, "_bound_context"): diff --git a/examples/oauth/preconfigured/main.py b/examples/oauth/preconfigured/main.py index c20e164e7..12fd60356 100644 --- a/examples/oauth/preconfigured/main.py +++ b/examples/oauth/preconfigured/main.py @@ -22,6 +22,7 @@ # Create the MCP app with OAuth configuration app = MCPApp(name="oauth_github_example") + async def search_github_orgs(query: str, limit: int = 5) -> List[Dict[str, Any]]: """ Search for GitHub organizations using the GitHub MCP server with OAuth. @@ -42,9 +43,7 @@ async def search_github_orgs(query: str, limit: int = 5) -> List[Dict[str, Any]] try: # Connect to the GitHub MCP server with OAuth async with gen_client( - "github", - server_registry=context.server_registry, - context=context + "github", server_registry=context.server_registry, context=context ) as github_client: logger.info("Connected to GitHub MCP server with OAuth") @@ -72,8 +71,8 @@ async def search_github_orgs(query: str, limit: int = 5) -> List[Dict[str, Any]] "query": query, "perPage": min(limit, 100), # GitHub API max is 100 "sort": "best-match", - "order": "desc" - } + "order": "desc", + }, ) logger.info("Search completed, processing results...") @@ -83,12 +82,12 @@ async def search_github_orgs(query: str, limit: int = 5) -> List[Dict[str, Any]] # The result content should contain the organization data organizations = [] for content_item in result.content: - if hasattr(content_item, 'text'): + if hasattr(content_item, "text"): try: # Try to parse as JSON if it's structured data data = json.loads(content_item.text) - if isinstance(data, dict) and 'items' in data: - organizations.extend(data['items'][:limit]) + if isinstance(data, dict) and "items" in data: + organizations.extend(data["items"][:limit]) elif isinstance(data, list): organizations.extend(data[:limit]) else: @@ -126,9 +125,9 @@ async def demonstrate_org_search(): ] for query in search_queries: - print(f"\n{'='*50}") + print(f"\n{'=' * 50}") print(f"Searching for: {query}") - print('='*50) + print("=" * 50) try: orgs = await search_github_orgs(query, limit=3) @@ -136,13 +135,13 @@ async def demonstrate_org_search(): if orgs: for i, org in enumerate(orgs, 1): print(f"\n{i}. {org.get('login', 'Unknown')}") - if 'description' in org and org['description']: + if "description" in org and org["description"]: print(f" Description: {org['description']}") - if 'html_url' in org: + if "html_url" in org: print(f" URL: {org['html_url']}") - if 'public_repos' in org: + if "public_repos" in org: print(f" Public repos: {org['public_repos']}") - if 'location' in org and org['location']: + if "location" in org and org["location"]: print(f" Location: {org['location']}") else: print("No organizations found.") @@ -152,7 +151,6 @@ async def demonstrate_org_search(): continue - async def main(): """ Main function demonstrating various OAuth MCP agent usage patterns. @@ -180,7 +178,7 @@ async def main(): # Set up logging to show detailed information logging.basicConfig( level=logging.INFO, - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", ) - asyncio.run(main()) \ No newline at end of file + asyncio.run(main()) diff --git a/examples/oauth/preconfigured/oauth_demo.py b/examples/oauth/preconfigured/oauth_demo.py index 913d6622b..37fbd6846 100644 --- a/examples/oauth/preconfigured/oauth_demo.py +++ b/examples/oauth/preconfigured/oauth_demo.py @@ -40,7 +40,9 @@ def __init__(self, client_id: str, client_secret: str, redirect_uri: str = None) """ self.client_id = client_id self.client_secret = client_secret - self.redirect_uri = redirect_uri or "http://localhost:8080/internal/oauth/callback" + self.redirect_uri = ( + redirect_uri or "http://localhost:8080/internal/oauth/callback" + ) self.state = secrets.token_urlsafe(32) # CSRF protection self.access_token: Optional[str] = None self.refresh_token: Optional[str] = None @@ -97,7 +99,7 @@ async def exchange_code_for_token(self, code: str, state: str) -> Dict[str, Any] headers = { "Accept": "application/json", - "User-Agent": "MCP-Agent-OAuth-Demo/1.0" + "User-Agent": "MCP-Agent-OAuth-Demo/1.0", } async with aiohttp.ClientSession() as session: @@ -136,12 +138,14 @@ async def test_token(self) -> Dict[str, Any]: headers = { "Authorization": f"Bearer {self.access_token}", "Accept": "application/vnd.github.v3+json", - "User-Agent": "MCP-Agent-OAuth-Demo/1.0" + "User-Agent": "MCP-Agent-OAuth-Demo/1.0", } async with aiohttp.ClientSession() as session: # Test with a simple user info call - async with session.get("https://api.github.com/user", headers=headers) as response: + async with session.get( + "https://api.github.com/user", headers=headers + ) as response: if response.status != 200: raise ValueError(f"Token test failed: {response.status}") @@ -165,7 +169,7 @@ def get_token_for_mcp_agent(self) -> Dict[str, Any]: "scopes": ["read:org", "public_repo"], "expires_at": self.token_expires_at, "authorization_server": "https://github.com/login/oauth/authorize", - "token_type": "Bearer" + "token_type": "Bearer", } async def save_token_to_file(self, filename: str = "github_oauth_token.json"): @@ -177,11 +181,13 @@ async def save_token_to_file(self, filename: str = "github_oauth_token.json"): """ token_data = self.get_token_for_mcp_agent() - with open(filename, 'w') as f: + with open(filename, "w") as f: json.dump(token_data, f, indent=2) print(f"Token saved to {filename}") - print("You can now use this token with the MCP agent workflow_pre_auth endpoint.") + print( + "You can now use this token with the MCP agent workflow_pre_auth endpoint." + ) async def run_oauth_flow(self, scopes: list = None) -> Dict[str, Any]: """ @@ -209,16 +215,18 @@ async def run_oauth_flow(self, scopes: list = None) -> Dict[str, Any]: async def handle_callback(request): nonlocal callback_data try: - code = request.query.get('code') - state = request.query.get('state') - error = request.query.get('error') + code = request.query.get("code") + state = request.query.get("state") + error = request.query.get("error") if error: - callback_data['error'] = error - callback_data['error_description'] = request.query.get('error_description', '') + callback_data["error"] = error + callback_data["error_description"] = request.query.get( + "error_description", "" + ) else: - callback_data['code'] = code - callback_data['state'] = state + callback_data["code"] = code + callback_data["state"] = state callback_received.set() @@ -232,7 +240,7 @@ async def handle_callback(request): """ - return web.Response(text=html, content_type='text/html') + return web.Response(text=html, content_type="text/html") except Exception as e: print(f"Error in callback handler: {e}") @@ -240,11 +248,11 @@ async def handle_callback(request): # Start local server app = web.Application() - app.router.add_get('/internal/oauth/callback', handle_callback) + app.router.add_get("/internal/oauth/callback", handle_callback) runner = web.AppRunner(app) await runner.setup() - site = web.TCPSite(runner, 'localhost', 8080) + site = web.TCPSite(runner, "localhost", 8080) await site.start() print("\n3. Local callback server started on http://localhost:8080") @@ -260,7 +268,9 @@ async def handle_callback(request): # Wait for callback with timeout try: - await asyncio.wait_for(callback_received.wait(), timeout=300) # 5 minute timeout + await asyncio.wait_for( + callback_received.wait(), timeout=300 + ) # 5 minute timeout except asyncio.TimeoutError: print(" Timeout waiting for authorization callback") await runner.cleanup() @@ -269,11 +279,13 @@ async def handle_callback(request): await runner.cleanup() # Step 3: Handle callback result - if 'error' in callback_data: - raise ValueError(f"OAuth error: {callback_data['error']} - {callback_data.get('error_description', '')}") + if "error" in callback_data: + raise ValueError( + f"OAuth error: {callback_data['error']} - {callback_data.get('error_description', '')}" + ) - code = callback_data.get('code') - state = callback_data.get('state') + code = callback_data.get("code") + state = callback_data.get("state") if not code: raise ValueError("No authorization code received") @@ -288,7 +300,7 @@ async def handle_callback(request): print("6. Testing access token...") try: user_info = await self.test_token() - username = user_info.get('login', 'unknown') + username = user_info.get("login", "unknown") print(f" ✓ Token test successful - authenticated as: {username}") except Exception as e: print(f" ⚠ Token test failed: {e}") @@ -304,14 +316,16 @@ async def main(): print("=" * 40) # Check for environment variables - client_id = os.getenv('GITHUB_CLIENT_ID') - client_secret = os.getenv('GITHUB_CLIENT_SECRET') + client_id = os.getenv("GITHUB_CLIENT_ID") + client_secret = os.getenv("GITHUB_CLIENT_SECRET") if not client_id or not client_secret: print("\nTo use this demo, you need to set up a GitHub OAuth App:") print("1. Go to GitHub Settings > Developer settings > OAuth Apps") print("2. Click 'New OAuth App'") - print("3. Set Authorization callback URL to: http://localhost:8080/internal/oauth/callback") + print( + "3. Set Authorization callback URL to: http://localhost:8080/internal/oauth/callback" + ) print("4. Set environment variables:") print(" export GITHUB_CLIENT_ID='your_client_id'") print(" export GITHUB_CLIENT_SECRET='your_client_secret'") @@ -339,8 +353,10 @@ async def main(): # Save token to file save_choice = input("\nSave token to file? (y/n): ").lower().strip() - if save_choice in ['y', 'yes']: - filename = input("Enter filename (default: github_oauth_token.json): ").strip() + if save_choice in ["y", "yes"]: + filename = input( + "Enter filename (default: github_oauth_token.json): " + ).strip() if not filename: filename = "github_oauth_token.json" await oauth_demo.save_token_to_file(filename) @@ -353,7 +369,7 @@ async def main(): example_usage = { "workflow_name": "github_analysis_workflow", - "tokens": [token_data] + "tokens": [token_data], } print(f" {json.dumps(example_usage, indent=2)}") @@ -364,9 +380,9 @@ async def main(): "github": { "auth": { "oauth": { - "access_token": token_data['access_token'], - "refresh_token": token_data.get('refresh_token'), - "scopes": token_data['scopes'] + "access_token": token_data["access_token"], + "refresh_token": token_data.get("refresh_token"), + "scopes": token_data["scopes"], } } } @@ -381,4 +397,4 @@ async def main(): if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file + asyncio.run(main()) diff --git a/examples/oauth/preconfigured/workflow_example.py b/examples/oauth/preconfigured/workflow_example.py index 59948bf7b..e161e41a3 100644 --- a/examples/oauth/preconfigured/workflow_example.py +++ b/examples/oauth/preconfigured/workflow_example.py @@ -32,9 +32,7 @@ def __init__(self, context: Context): self.name = "github_org_analyzer" async def analyze_organizations( - self, - queries: List[str], - detailed_analysis: bool = True + self, queries: List[str], detailed_analysis: bool = True ) -> Dict[str, Any]: """ Analyze multiple organizations based on search queries. @@ -86,7 +84,9 @@ async def analyze_organizations( # Generate summary results["summary"] = self._generate_summary(results["organizations"]) - logger.info(f"Analysis completed: {len(results['organizations'])} organizations analyzed") + logger.info( + f"Analysis completed: {len(results['organizations'])} organizations analyzed" + ) return results except Exception as e: @@ -98,28 +98,21 @@ async def _search_organizations(self, query: str) -> List[Dict[str, Any]]: from mcp_agent.mcp.gen_client import gen_client async with gen_client( - "github", - server_registry=self.context.server_registry, - context=self.context + "github", server_registry=self.context.server_registry, context=self.context ) as github_client: result = await github_client.call_tool( "search_orgs", - { - "query": query, - "perPage": 10, - "sort": "best-match", - "order": "desc" - } + {"query": query, "perPage": 10, "sort": "best-match", "order": "desc"}, ) organizations = [] if result.content: for content_item in result.content: - if hasattr(content_item, 'text'): + if hasattr(content_item, "text"): try: data = json.loads(content_item.text) - if isinstance(data, dict) and 'items' in data: - organizations.extend(data['items']) + if isinstance(data, dict) and "items" in data: + organizations.extend(data["items"]) elif isinstance(data, list): organizations.extend(data) except json.JSONDecodeError: @@ -127,7 +120,9 @@ async def _search_organizations(self, query: str) -> List[Dict[str, Any]]: return organizations - async def _analyze_organization_details(self, org: Dict[str, Any]) -> Dict[str, Any]: + async def _analyze_organization_details( + self, org: Dict[str, Any] + ) -> Dict[str, Any]: """Analyze detailed information about an organization.""" details = { "activity_score": self._calculate_activity_score(org), @@ -164,6 +159,7 @@ def _calculate_age(self, created_at: str) -> float: try: from datetime import datetime + created = datetime.fromisoformat(created_at.replace("Z", "+00:00")) now = datetime.now(created.tzinfo) return (now - created).days / 365.25 @@ -190,10 +186,8 @@ def _generate_summary(self, organizations: List[Dict[str, Any]]) -> Dict[str, An "average_repos_per_org": total_repos / len(organizations), "size_distribution": size_categories, "top_organizations": sorted( - organizations, - key=lambda x: x.get("activity_score", 0), - reverse=True - )[:5] + organizations, key=lambda x: x.get("activity_score", 0), reverse=True + )[:5], } @@ -203,9 +197,7 @@ def _generate_summary(self, organizations: List[Dict[str, Any]]) -> Dict[str, An @app.async_tool async def analyze_github_ecosystem( - app_ctx: Context, - focus_areas: List[str], - include_details: bool = True + app_ctx: Context, focus_areas: List[str], include_details: bool = True ) -> Dict[str, Any]: """ Analyze the GitHub ecosystem based on focus areas. @@ -228,13 +220,19 @@ async def analyze_github_ecosystem( # Map focus areas to search queries query_mapping = { - "AI/ML": ["machine-learning", "artificial-intelligence", "deep-learning", "tensorflow", "pytorch"], + "AI/ML": [ + "machine-learning", + "artificial-intelligence", + "deep-learning", + "tensorflow", + "pytorch", + ], "cloud": ["cloud-computing", "aws", "azure", "kubernetes", "docker"], "security": ["cybersecurity", "security", "encryption", "vulnerability"], "web": ["web-development", "javascript", "react", "vue", "angular"], "mobile": ["mobile-development", "android", "ios", "react-native", "flutter"], "data": ["data-science", "analytics", "big-data", "database", "sql"], - "devtools": ["developer-tools", "ci-cd", "testing", "monitoring", "automation"] + "devtools": ["developer-tools", "ci-cd", "testing", "monitoring", "automation"], } all_queries = [] @@ -250,8 +248,7 @@ async def analyze_github_ecosystem( try: # Perform the analysis analysis_results = await analyzer.analyze_organizations( - queries=unique_queries, - detailed_analysis=include_details + queries=unique_queries, detailed_analysis=include_details ) # Add ecosystem-level insights @@ -260,7 +257,7 @@ async def analyze_github_ecosystem( "timestamp": time.time(), "queries_executed": unique_queries, "results": analysis_results, - "insights": _generate_ecosystem_insights(analysis_results) + "insights": _generate_ecosystem_insights(analysis_results), } logger.info("GitHub ecosystem analysis completed successfully") @@ -283,7 +280,7 @@ def _generate_ecosystem_insights(results: Dict[str, Any]) -> Dict[str, Any]: "dominant_languages": _analyze_language_trends(organizations), "geographic_distribution": _analyze_geographic_distribution(organizations), "maturity_analysis": _analyze_organization_maturity(organizations), - "activity_patterns": _analyze_activity_patterns(organizations) + "activity_patterns": _analyze_activity_patterns(organizations), } return insights @@ -295,11 +292,13 @@ def _analyze_language_trends(organizations: List[Dict[str, Any]]) -> Dict[str, A # you might use additional GitHub API calls to get language data return { "message": "Language trend analysis would require additional API calls", - "suggestion": "Use repository listing and language detection APIs" + "suggestion": "Use repository listing and language detection APIs", } -def _analyze_geographic_distribution(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: +def _analyze_geographic_distribution( + organizations: List[Dict[str, Any]], +) -> Dict[str, Any]: """Analyze geographic distribution of organizations.""" locations = {} for org in organizations: @@ -308,22 +307,30 @@ def _analyze_geographic_distribution(organizations: List[Dict[str, Any]]) -> Dic locations[location] = locations.get(location, 0) + 1 return { - "total_with_location": len([org for org in organizations if org.get("location")]), - "top_locations": dict(sorted(locations.items(), key=lambda x: x[1], reverse=True)[:10]) + "total_with_location": len( + [org for org in organizations if org.get("location")] + ), + "top_locations": dict( + sorted(locations.items(), key=lambda x: x[1], reverse=True)[:10] + ), } -def _analyze_organization_maturity(organizations: List[Dict[str, Any]]) -> Dict[str, Any]: +def _analyze_organization_maturity( + organizations: List[Dict[str, Any]], +) -> Dict[str, Any]: """Analyze the maturity of organizations.""" mature_count = sum(1 for org in organizations if org.get("age_years", 0) > 5) - established_count = sum(1 for org in organizations if 2 <= org.get("age_years", 0) <= 5) + established_count = sum( + 1 for org in organizations if 2 <= org.get("age_years", 0) <= 5 + ) new_count = sum(1 for org in organizations if org.get("age_years", 0) < 2) return { "mature_orgs": mature_count, # > 5 years "established_orgs": established_count, # 2-5 years "new_orgs": new_count, # < 2 years - "maturity_ratio": mature_count / len(organizations) if organizations else 0 + "maturity_ratio": mature_count / len(organizations) if organizations else 0, } @@ -341,8 +348,8 @@ def _analyze_activity_patterns(organizations: List[Dict[str, Any]]) -> Dict[str, "activity_distribution": { "high": sum(1 for score in activity_scores if score > 75), "medium": sum(1 for score in activity_scores if 25 <= score <= 75), - "low": sum(1 for score in activity_scores if score < 25) - } + "low": sum(1 for score in activity_scores if score < 25), + }, } @@ -365,7 +372,7 @@ async def demonstrate_pre_auth_workflow(): "refresh_token": "github_oauth_refresh_token_here", "server_name": "github", "scopes": ["read:org", "public_repo"], - "authorization_server": "https://github.com/login/oauth/authorize" + "authorization_server": "https://github.com/login/oauth/authorize", } ] @@ -382,26 +389,30 @@ async def demonstrate_pre_auth_workflow(): result = await analyze_github_ecosystem( app_ctx=context, focus_areas=["AI/ML", "cloud", "security"], - include_details=True + include_details=True, ) print("\n3. Workflow Results:") print(f" - Focus areas analyzed: {result['focus_areas']}") print(f" - Queries executed: {len(result['queries_executed'])}") - print(f" - Organizations found: {result['results']['summary'].get('total_organizations', 0)}") + print( + f" - Organizations found: {result['results']['summary'].get('total_organizations', 0)}" + ) - if result['results']['errors']: + if result["results"]["errors"]: print(f" - Errors encountered: {len(result['results']['errors'])}") print("\n4. Ecosystem Insights:") - insights = result['insights'] - if 'geographic_distribution' in insights: - top_locations = insights['geographic_distribution'].get('top_locations', {}) + insights = result["insights"] + if "geographic_distribution" in insights: + top_locations = insights["geographic_distribution"].get( + "top_locations", {} + ) if top_locations: print(f" - Top locations: {list(top_locations.keys())[:3]}") - if 'maturity_analysis' in insights: - maturity = insights['maturity_analysis'] + if "maturity_analysis" in insights: + maturity = insights["maturity_analysis"] print(f" - Mature organizations: {maturity.get('mature_orgs', 0)}") print(f" - Maturity ratio: {maturity.get('maturity_ratio', 0):.2%}") @@ -423,4 +434,4 @@ async def main(): if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file + asyncio.run(main()) diff --git a/examples/oauth/workflow_pre_auth/client.py b/examples/oauth/workflow_pre_auth/client.py index cc8fd23bd..4d9ae1a7c 100644 --- a/examples/oauth/workflow_pre_auth/client.py +++ b/examples/oauth/workflow_pre_auth/client.py @@ -27,7 +27,7 @@ _BrokenResourceError = None # type: ignore # Get GitHub access token from environment or ask user -access_token = os.getenv('GITHUB_ACCESS_TOKEN') +access_token = os.getenv("GITHUB_ACCESS_TOKEN") if not access_token: print("\nGitHub access token not found in environment variable GITHUB_ACCESS_TOKEN") @@ -39,8 +39,10 @@ print("export GITHUB_ACCESS_TOKEN='your_token_here'") # Verify token format -if not access_token.startswith(('gho_', 'ghp_', 'github_pat_')): - print(f"Warning: Token doesn't look like a GitHub token (got: {access_token[:10]}...)") +if not access_token.startswith(("gho_", "ghp_", "github_pat_")): + print( + f"Warning: Token doesn't look like a GitHub token (got: {access_token[:10]}...)" + ) print("GitHub tokens usually start with 'gho_', 'ghp_', or 'github_pat_'") @@ -128,18 +130,22 @@ def make_session( if len(sys.argv) < 2 or sys.argv[1] != "--skip-pre-auth": print("Performing pre-auth") - await server.call_tool("workflows-pre-auth", - arguments={ - "workflow_name": "github_org_search", - "tokens": [ - { - "access_token": access_token, - "server_name": "github", - } - ] - }) - - print(await server.call_tool("github_org_search", {"query": "lastmileai"})) + await server.call_tool( + "workflows-pre-auth", + arguments={ + "workflow_name": "github_org_search", + "tokens": [ + { + "access_token": access_token, + "server_name": "github", + } + ], + }, + ) + + print( + await server.call_tool("github_org_search", {"query": "lastmileai"}) + ) except Exception as e: # Tolerate benign shutdown races from stdio client (BrokenResourceError within ExceptionGroup) if _ExceptionGroup is not None and isinstance(e, _ExceptionGroup): diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py index 415803ba0..8966a43dc 100644 --- a/examples/oauth/workflow_pre_auth/main.py +++ b/examples/oauth/workflow_pre_auth/main.py @@ -18,8 +18,14 @@ from mcp_agent.app import MCPApp from mcp_agent.server.app_server import create_mcp_server_for_app from mcp_agent.mcp.gen_client import gen_client -from mcp_agent.config import MCPServerSettings, Settings, LoggerSettings, MCPSettings, MCPServerAuthSettings, \ - MCPOAuthClientSettings +from mcp_agent.config import ( + MCPServerSettings, + Settings, + LoggerSettings, + MCPSettings, + MCPServerAuthSettings, + MCPOAuthClientSettings, +) # Note: This is purely optional: # if not provided, a default FastMCP server will be created by MCPApp using create_mcp_server_for_app() @@ -31,30 +37,32 @@ class MCPServerOAuthSettings: settings = Settings( - execution_engine="asyncio", - logger=LoggerSettings(level="info"), - mcp=MCPSettings( - servers={ - "github": MCPServerSettings( - name="github", - transport="streamable_http", - url="https://api.githubcopilot.com/mcp/", - auth=MCPServerAuthSettings( - oauth=MCPOAuthClientSettings( - enabled=True, - scopes= [ - "read:org", # Required for search_orgs tool - "public_repo", # Access to public repositories - "user:email" # User information access - ], - authorization_server=AnyHttpUrl("https://github.com/login/oauth"), - resource=AnyHttpUrl("https://api.githubcopilot.com/mcp") - ) + execution_engine="asyncio", + logger=LoggerSettings(level="info"), + mcp=MCPSettings( + servers={ + "github": MCPServerSettings( + name="github", + transport="streamable_http", + url="https://api.githubcopilot.com/mcp/", + auth=MCPServerAuthSettings( + oauth=MCPOAuthClientSettings( + enabled=True, + scopes=[ + "read:org", # Required for search_orgs tool + "public_repo", # Access to public repositories + "user:email", # User information access + ], + authorization_server=AnyHttpUrl( + "https://github.com/login/oauth" + ), + resource=AnyHttpUrl("https://api.githubcopilot.com/mcp"), ) - ) - } - ), - ) + ), + ) + } + ), +) # Define the MCPApp instance. The server created for this app will advertise the # MCP logging capability and forward structured logs upstream to connected clients. @@ -68,7 +76,6 @@ class MCPServerOAuthSettings: @app.tool(name="github_org_search") async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: - # Use the context's app if available for proper logging with upstream_session _app = app_ctx.app if app_ctx else app # Ensure the app's logger is bound to the current context with upstream_session @@ -77,28 +84,21 @@ async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> try: async with gen_client( - "github", - server_registry=app_ctx.server_registry, - context=app_ctx + "github", server_registry=app_ctx.server_registry, context=app_ctx ) as github_client: result = await github_client.call_tool( "search_orgs", - { - "query": query, - "perPage": 10, - "sort": "best-match", - "order": "desc" - } + {"query": query, "perPage": 10, "sort": "best-match", "order": "desc"}, ) organizations = [] if result.content: for content_item in result.content: - if hasattr(content_item, 'text'): + if hasattr(content_item, "text"): try: data = json.loads(content_item.text) - if isinstance(data, dict) and 'items' in data: - organizations.extend(data['items']) + if isinstance(data, dict) and "items" in data: + organizations.extend(data["items"]) elif isinstance(data, list): organizations.extend(data) except json.JSONDecodeError: @@ -107,8 +107,10 @@ async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> return str(organizations) except Exception: import traceback + return f"Error: {traceback.format_exc()}" + async def main(): async with app.run() as agent_app: # Log registered workflows and agent configurations @@ -124,7 +126,7 @@ async def main(): agent_app.logger.info(f"MCP Server settings: {mcp_server.settings}") # Run the server - #await mcp_server.run_stdio_async() + # await mcp_server.run_stdio_async() await mcp_server.run_sse_async() diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index a93dd69ea..021b9c6a7 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -85,14 +85,14 @@ async def authorize( scope_param = " ".join(scopes) params = { - "response_type":"code", - "client_id":client_id, - "redirect_uri":redirect_uri, - "scope":scope_param, - "state":state, - "code_challenge":code_challenge, - "code_challenge_method":"S256", - "resource":resource, + "response_type": "code", + "client_id": client_id, + "redirect_uri": redirect_uri, + "scope": scope_param, + "state": state, + "code_challenge": code_challenge, + "code_challenge_method": "S256", + "resource": resource, } # add extra params if any @@ -100,8 +100,11 @@ async def authorize( params.update(oauth_config.extra_authorize_params) import urllib.parse + authorize_url = httpx.URL( - str(auth_metadata.authorization_endpoint) +"?" + urllib.parse.urlencode(params) + str(auth_metadata.authorization_endpoint) + + "?" + + urllib.parse.urlencode(params) ) callback_future = None @@ -112,7 +115,7 @@ async def authorize( "url": str(authorize_url), "message": f"Authorization required for {server_name}", "redirect_uri_options": redirect_options, - "flow_id": flow_id + "flow_id": flow_id, } result = await _send_auth_request(context, request_payload) diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index 7dbcb12eb..5a5a14396 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -38,14 +38,21 @@ logger = get_logger(__name__) -def create_default_user_for_preconfigured_tokens(session_id: str | None = None) -> "OAuthUserIdentity": +def create_default_user_for_preconfigured_tokens( + session_id: str | None = None, +) -> "OAuthUserIdentity": """Create a synthetic user identity for pre-configured tokens.""" from mcp_agent.oauth.identity import OAuthUserIdentity return OAuthUserIdentity( provider="mcp-agent", - subject=f"preconfigured-tokens-{session_id}" if session_id else "preconfigured-tokens", - claims={"token_source": "preconfigured", "description": "Synthetic user for pre-configured OAuth tokens"} + subject=f"preconfigured-tokens-{session_id}" + if session_id + else "preconfigured-tokens", + claims={ + "token_source": "preconfigured", + "description": "Synthetic user for pre-configured OAuth tokens", + }, ) @@ -71,19 +78,25 @@ def __init__( self._auth_metadata_cache: Dict[str, tuple[float, object]] = {} async def store_preconfigured_token( - self, - server_name: str, - server_config, - synthetic_user: "OAuthUserIdentity" + self, server_name: str, server_config, synthetic_user: "OAuthUserIdentity" ) -> None: """Store a pre-configured token in the token store.""" oauth_config = server_config.auth.oauth # Create token record - resource_str = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) - auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server else None + resource_str = ( + str(oauth_config.resource) + if oauth_config.resource + else getattr(server_config, "url", None) + ) + auth_server_str = ( + str(oauth_config.authorization_server) + if oauth_config.authorization_server + else None + ) from datetime import datetime, timezone + record = TokenRecord( access_token=oauth_config.access_token, refresh_token=oauth_config.refresh_token, @@ -93,7 +106,7 @@ async def store_preconfigured_token( resource=resource_str, authorization_server=auth_server_str, obtained_at=datetime.now(tz=timezone.utc).timestamp(), - metadata={"server_name": server_name, "pre_configured": True} + metadata={"server_name": server_name, "pre_configured": True}, ) # Create storage key @@ -101,11 +114,13 @@ async def store_preconfigured_token( user_key=synthetic_user.cache_key, resource=resource_str or "", authorization_server=auth_server_str, - scope_fingerprint=scope_fingerprint(oauth_config.scopes or []) + scope_fingerprint=scope_fingerprint(oauth_config.scopes or []), ) # Store the token - logger.debug(f"Storing token with key: user_key={key.user_key}, resource={key.resource}, auth_server={key.authorization_server}, scope_fingerprint={key.scope_fingerprint}") + logger.debug( + f"Storing token with key: user_key={key.user_key}, resource={key.resource}, auth_server={key.authorization_server}, scope_fingerprint={key.scope_fingerprint}" + ) await self._token_store.set(key, record) async def ensure_access_token( @@ -127,16 +142,26 @@ async def ensure_access_token( user = context.current_user # Use the same key construction logic as store_preconfigured_token to ensure consistency - resource_str = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) - auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server else None - scope_list = list(scopes) if scopes is not None else list(oauth_config.scopes or []) + resource_str = ( + str(oauth_config.resource) + if oauth_config.resource + else getattr(server_config, "url", None) + ) + auth_server_str = ( + str(oauth_config.authorization_server) + if oauth_config.authorization_server + else None + ) + scope_list = ( + list(scopes) if scopes is not None else list(oauth_config.scopes or []) + ) # check for a globally configure token key = TokenStoreKey( user_key=create_default_user_for_preconfigured_tokens().cache_key, resource=resource_str, authorization_server=auth_server_str, - scope_fingerprint=scope_fingerprint(scope_list) + scope_fingerprint=scope_fingerprint(scope_list), ) lock = self._locks[key] @@ -151,7 +176,7 @@ async def ensure_access_token( user_key=user.cache_key, resource=resource_str, authorization_server=auth_server_str, - scope_fingerprint=scope_fingerprint(scope_list) + scope_fingerprint=scope_fingerprint(scope_list), ) lock = self._locks[key] @@ -168,13 +193,22 @@ async def ensure_access_token( # If token exists but expired, try to refresh it if record and record.refresh_token: # For refresh, we need OAuth metadata - resource_hint = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) + resource_hint = ( + str(oauth_config.resource) + if oauth_config.resource + else getattr(server_config, "url", None) + ) server_url = getattr(server_config, "url", None) resource = normalize_resource(resource_hint, server_url) # Get OAuth metadata for token refresh parsed_resource = URL(resource) - metadata_url = str(parsed_resource.copy_with(path="/.well-known/oauth-protected-resource" + parsed_resource.path)) + metadata_url = str( + parsed_resource.copy_with( + path="/.well-known/oauth-protected-resource" + + parsed_resource.path + ) + ) resource_metadata = await self._get_resource_metadata(metadata_url) auth_server_url = select_authorization_server( resource_metadata, str(oauth_config.authorization_server) @@ -199,13 +233,22 @@ async def ensure_access_token( # Need to run full authorization flow - only if no token found or refresh failed if not record: - resource_hint = str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) + resource_hint = ( + str(oauth_config.resource) + if oauth_config.resource + else getattr(server_config, "url", None) + ) server_url = getattr(server_config, "url", None) resource = normalize_resource(resource_hint, server_url) # Get OAuth metadata for full authorization flow parsed_resource = URL(resource) - metadata_url = str(parsed_resource.copy_with(path="/.well-known/oauth-protected-resource" + parsed_resource.path)) + metadata_url = str( + parsed_resource.copy_with( + path="/.well-known/oauth-protected-resource" + + parsed_resource.path + ) + ) resource_metadata = await self._get_resource_metadata(metadata_url) auth_server_url = select_authorization_server( resource_metadata, str(oauth_config.authorization_server) @@ -327,8 +370,13 @@ async def _get_authorization_metadata(self, url: str): # Construct OAuth authorization server metadata URL parsed_url = URL(url) metadata_url = str( - parsed_url.copy_with(path="/.well-known/oauth-authorization-server" + parsed_url.path)) - metadata = await fetch_authorization_server_metadata(self._http_client, metadata_url) + parsed_url.copy_with( + path="/.well-known/oauth-authorization-server" + parsed_url.path + ) + ) + metadata = await fetch_authorization_server_metadata( + self._http_client, metadata_url + ) self._auth_metadata_cache[url] = (time.time(), metadata) return metadata diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index 9cede9d45..3bbf6e59a 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -44,6 +44,7 @@ ) from mcp_agent.oauth.manager import create_default_user_for_preconfigured_tokens from mcp_agent.server.token_verifier import MCPAgentTokenVerifier + if TYPE_CHECKING: from mcp_agent.core.context import Context @@ -732,7 +733,9 @@ async def _handle_specific_request( elif method == "auth/request": # TODO: special handling of auth request, should be replaced by future URL elicitation class AuthToken(BaseModel): - confirmation: str = Field(description="Please press enter to confirm this message has been received") + confirmation: str = Field( + description="Please press enter to confirm this message has been received" + ) flow_id = params["flow_id"] callback_future = await callback_registry.create_handle(flow_id) @@ -1606,7 +1609,9 @@ async def workflow_pre_auth( ) continue - server_config = app_context.server_registry.get_server_config(server_name) + server_config = app_context.server_registry.get_server_config( + server_name + ) if not server_config: errors.append( f"Token {i}: server '{server_name}' not recognized" @@ -1629,10 +1634,16 @@ async def workflow_pre_auth( scope_fingerprint, ) - resource_str = str(oauth_config.resource) if oauth_config.resource \ + resource_str = ( + str(oauth_config.resource) + if oauth_config.resource else getattr(server_config, "url", None) - auth_server_str = str(oauth_config.authorization_server) if oauth_config.authorization_server \ + ) + auth_server_str = ( + str(oauth_config.authorization_server) + if oauth_config.authorization_server else None + ) scope_list = list(oauth_config.scopes or []) token_record = TokenRecord( @@ -1646,7 +1657,9 @@ async def workflow_pre_auth( metadata={"workflow_name": workflow_name}, ) - str(oauth_config.resource) if oauth_config.resource else getattr(server_config, "url", None) + str(oauth_config.resource) if oauth_config.resource else getattr( + server_config, "url", None + ) # Create storage key using current user store_key = TokenStoreKey( user_key=app_context.current_user.cache_key, diff --git a/tests/test_audience_validation.py b/tests/test_audience_validation.py index 058774fe1..392cf4e18 100644 --- a/tests/test_audience_validation.py +++ b/tests/test_audience_validation.py @@ -88,7 +88,11 @@ async def test_multiple_audiences_extraction(): } audiences = _extract_all_audiences(payload) - expected = {"https://api1.example.com", "https://api2.example.com", "https://api3.example.com"} + expected = { + "https://api1.example.com", + "https://api2.example.com", + "https://api3.example.com", + } assert set(audiences) == expected @@ -141,8 +145,6 @@ def test_configuration_validation(): assert "https://api.example.com" in settings.expected_audiences - - @pytest.mark.asyncio async def test_token_verifier_audience_validation_integration(): """Test full integration of audience validation in token verifier.""" @@ -196,8 +198,6 @@ async def test_token_verifier_audience_validation_integration(): assert token is None - - def test_audience_extraction_edge_cases(): """Test audience extraction handles edge cases properly.""" # Empty payload @@ -209,7 +209,7 @@ def test_audience_extraction_edge_cases(): # Mixed empty and valid values payload = { "aud": ["", "https://valid.com", None], - "resource": ["https://another.com", ""] + "resource": ["https://another.com", ""], } audiences = _extract_all_audiences(payload) expected = {"https://valid.com", "https://another.com"} @@ -218,7 +218,7 @@ def test_audience_extraction_edge_cases(): # Duplicate values should be removed payload = { "aud": ["https://api.com", "https://api.com"], - "resource": "https://api.com" + "resource": "https://api.com", } audiences = _extract_all_audiences(payload) assert audiences == ["https://api.com"] @@ -247,4 +247,4 @@ async def test_partial_audience_match(): token = MCPAccessToken.from_introspection("test_token", payload) # Should succeed because at least one audience matches - assert token.validate_audience(settings.expected_audiences) is True \ No newline at end of file + assert token.validate_audience(settings.expected_audiences) is True From 93fee78f147961e0faec5c1f0d14dbb88117370b Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Wed, 8 Oct 2025 18:03:30 -0400 Subject: [PATCH 13/25] rework oauth flow --- docs/oauth_support_design.md | 2 +- src/mcp_agent/core/context.py | 4 - .../executor/temporal/session_proxy.py | 27 +++ src/mcp_agent/mcp/mcp_server_registry.py | 10 + src/mcp_agent/oauth/http/auth.py | 35 +++- src/mcp_agent/oauth/identity.py | 18 +- src/mcp_agent/oauth/manager.py | 58 +++--- src/mcp_agent/server/app_server.py | 172 +++++++++++++++--- tests/test_token_manager.py | 11 +- uv.lock | 14 +- 10 files changed, 273 insertions(+), 78 deletions(-) diff --git a/docs/oauth_support_design.md b/docs/oauth_support_design.md index faeccce87..d9b0a7a10 100644 --- a/docs/oauth_support_design.md +++ b/docs/oauth_support_design.md @@ -59,7 +59,7 @@ src/mcp_agent/oauth/ Integration touchpoints: - `mcp_agent/config.py` – add OAuth settings models. -- `mcp_agent/core/context.py` – add `current_user`, `token_manager`, `token_store`, `oauth_config` fields. +- `mcp_agent/core/context.py` – add `token_manager`, `token_store`, `oauth_config` fields. - `mcp_agent/app.py` – initialize token store/manager based on settings. - `mcp_agent/server/app_server.py` – configure FastMCP auth settings, register callback route, surface user identity, extend relay to handle `auth/request`. - `mcp_agent/mcp/mcp_server_registry.py` & `mcp_agent/mcp/mcp_connection_manager.py` – wire `OAuthHttpxAuth` into HTTP transports and expose helper for manual token teardown. diff --git a/src/mcp_agent/core/context.py b/src/mcp_agent/core/context.py index 24d4071a6..b77c8254c 100644 --- a/src/mcp_agent/core/context.py +++ b/src/mcp_agent/core/context.py @@ -33,7 +33,6 @@ from mcp_agent.workflows.llm.llm_selector import ModelSelector from mcp_agent.logging.logger import get_logger from mcp_agent.tracing.token_counter import TokenCounter -from mcp_agent.oauth.identity import OAuthUserIdentity if TYPE_CHECKING: @@ -98,9 +97,6 @@ class Context(BaseModel): gateway_url: str | None = None gateway_token: str | None = None - # Current authenticated user (set when acting as an MCP server) - current_user: Optional[OAuthUserIdentity] = None - # OAuth helpers for downstream servers token_store: Optional[TokenStore] = None token_manager: Optional[TokenManager] = None diff --git a/src/mcp_agent/executor/temporal/session_proxy.py b/src/mcp_agent/executor/temporal/session_proxy.py index 6722176ac..dbd2f425c 100644 --- a/src/mcp_agent/executor/temporal/session_proxy.py +++ b/src/mcp_agent/executor/temporal/session_proxy.py @@ -18,6 +18,7 @@ from mcp_agent.core.context import Context from mcp_agent.executor.temporal.system_activities import SystemActivities from mcp_agent.executor.temporal.temporal_context import get_execution_id +from mcp_agent.oauth.identity import DEFAULT_PRECONFIGURED_IDENTITY class SessionProxy(ServerSession): @@ -72,6 +73,27 @@ def __init__(self, *, executor, context: Context) -> None: # Provide a low-level RPC facade similar to real ServerSession self.rpc = _RPC(self) + def _ensure_identity(self) -> None: + exec_id = get_execution_id() + identity = None + if exec_id: + try: + from mcp_agent.server import app_server + + identity = app_server._get_identity_for_execution(exec_id) + except Exception: + identity = None + + if identity is None: + identity = DEFAULT_PRECONFIGURED_IDENTITY + + try: + from mcp_agent.server import app_server + + app_server._set_current_identity(identity) + except Exception: + pass + # ---------------------- # Generic passthroughs # ---------------------- @@ -80,6 +102,7 @@ async def notify(self, method: str, params: Dict[str, Any] | None = None) -> boo Returns True on best-effort success. """ + self._ensure_identity() exec_id = get_execution_id() if not exec_id: return False @@ -111,6 +134,7 @@ async def request( """Send a server->client request and return the client's response. The result is a plain JSON-serializable dict. """ + self._ensure_identity() exec_id = get_execution_id() if not exec_id: return {"error": "missing_execution_id"} @@ -178,6 +202,7 @@ async def send_notification( if related_request_id is not None: params = dict(params or {}) params["related_request_id"] = related_request_id + self._ensure_identity() await self.notify(root.method, params) # type: ignore[attr-defined] async def send_request( @@ -196,6 +221,7 @@ async def send_request( except Exception: params = {} # Note: metadata (e.g., related_request_id) is handled server-side where applicable + self._ensure_identity() payload = await self.request(root.method, params) # type: ignore[attr-defined] # Attempt to validate into the requested result type try: @@ -211,6 +237,7 @@ async def send_log_message( related_request_id: types.RequestId | None = None, ) -> None: """Best-effort log forwarding to the client's UI.""" + self._ensure_identity() # Prefer activity-based forwarding inside workflow for determinism exec_id = get_execution_id() if _in_workflow_runtime() and exec_id: diff --git a/src/mcp_agent/mcp/mcp_server_registry.py b/src/mcp_agent/mcp/mcp_server_registry.py index 04a8cad08..7cd670445 100644 --- a/src/mcp_agent/mcp/mcp_server_registry.py +++ b/src/mcp_agent/mcp/mcp_server_registry.py @@ -39,6 +39,15 @@ logger = get_logger(__name__) + +def _resolve_identity_from_context(): + try: + from mcp_agent.server import app_server # local import to avoid circular dependency + + return app_server.get_current_identity() + except Exception: + return None + InitHookCallable = Callable[[ClientSession | None, MCPServerAuthSettings | None], bool] """ A type alias for an initialization hook function that is invoked after MCP server initialization. @@ -230,6 +239,7 @@ async def start_server( server_name=server_name, server_config=config, scopes=oauth_cfg.scopes, + identity_resolver=_resolve_identity_from_context, ) if auth_handler: kwargs["auth"] = auth_handler diff --git a/src/mcp_agent/oauth/http/auth.py b/src/mcp_agent/oauth/http/auth.py index 11f32ff29..0dffdaa5a 100644 --- a/src/mcp_agent/oauth/http/auth.py +++ b/src/mcp_agent/oauth/http/auth.py @@ -4,11 +4,12 @@ import httpx -from typing import TYPE_CHECKING +from typing import Callable, TYPE_CHECKING if TYPE_CHECKING: from mcp_agent.oauth.manager import TokenManager from mcp_agent.core.context import Context + from mcp_agent.oauth.identity import OAuthUserIdentity class OAuthHttpxAuth(httpx.Auth): @@ -22,20 +23,34 @@ def __init__( server_name: str, server_config, scopes=None, + identity_resolver: Callable[[], "OAuthUserIdentity | None"] | None = None, ) -> None: self._token_manager = token_manager self._context = context self._server_name = server_name self._server_config = server_config self._scopes = list(scopes) if scopes is not None else None + self._identity_resolver = identity_resolver async def async_auth_flow(self, request: httpx.Request): + identity = None + if self._identity_resolver is not None: + identity = self._identity_resolver() + else: + try: + from mcp_agent.server import app_server + + identity = app_server.get_current_identity() + except Exception: + identity = None + try: token_record = await self._token_manager.ensure_access_token( context=self._context, server_name=self._server_name, server_config=self._server_config, scopes=self._scopes, + identity=identity, ) except Exception: raise @@ -47,16 +62,25 @@ async def async_auth_flow(self, request: httpx.Request): if response.status_code != 401: return - user = self._context.current_user - if user is None: + if identity is None: + try: + from mcp_agent.server import app_server + + identity = app_server.get_current_identity() + except Exception: + identity = None + if identity is None: + from mcp_agent.oauth.identity import DEFAULT_PRECONFIGURED_IDENTITY + + identity = DEFAULT_PRECONFIGURED_IDENTITY + if identity is None: return await self._token_manager.invalidate( - user=user, + identity=identity, resource=token_record.resource or "", authorization_server=token_record.authorization_server, scopes=token_record.scopes, - session_id=self._context.session_id, ) refreshed_record = await self._token_manager.ensure_access_token( @@ -64,6 +88,7 @@ async def async_auth_flow(self, request: httpx.Request): server_name=self._server_name, server_config=self._server_config, scopes=self._scopes, + identity=identity, ) # Create a new request with the refreshed token. Using copy() preserves the original body. diff --git a/src/mcp_agent/oauth/identity.py b/src/mcp_agent/oauth/identity.py index 65eb22dd6..2774770f2 100644 --- a/src/mcp_agent/oauth/identity.py +++ b/src/mcp_agent/oauth/identity.py @@ -47,5 +47,21 @@ def _claim(token: MCPAccessToken, key: str) -> Any | None: DEFAULT_PRECONFIGURED_IDENTITY = OAuthUserIdentity( - provider="mcp-agent", subject="preconfigured-tokens" + provider="mcp-agent", + subject="preconfigured-tokens", + claims={ + "token_source": "synthetic", + "description": "Synthetic identity used when no user/session is available", + }, ) + + +def session_identity(session_id: str | None) -> OAuthUserIdentity | None: + """Build a deterministic identity for an unauthenticated MCP session.""" + if not session_id: + return None + return OAuthUserIdentity( + provider="mcp-session", + subject=str(session_id), + claims={"token_source": "session"}, + ) diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index 9c87d8a68..448f6e9ea 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -303,6 +303,7 @@ async def ensure_access_token( server_name: str, server_config, scopes: Iterable[str] | None = None, + identity: OAuthUserIdentity | None = None, ) -> TokenRecord: oauth_config: MCPOAuthClientSettings | None = None if server_config and server_config.auth: @@ -323,14 +324,21 @@ async def ensure_access_token( requested_scopes=requested_scopes, ) + context_identity = None + try: + from mcp_agent.server import app_server + + context_identity = app_server.get_current_identity() + except Exception: + context_identity = None session_identity = self._session_identity(context) - identities = _dedupe( - [ - context.current_user, - session_identity, - self._default_identity, - ] - ) + identity_candidates = [ + identity, + context_identity, + session_identity, + self._default_identity, + ] + identities = _dedupe(identity_candidates) if not identities: raise MissingUserIdentityError( "No authenticated user available for OAuth authorization" @@ -388,8 +396,15 @@ async def ensure_access_token( await self._token_store.delete(key) # Only authenticated users (non-default identity) can initiate new flows. - user_identity = context.current_user - if user_identity is None: + flow_identity = next( # type: ignore[arg-type] + ( + cand + for cand in identity_candidates + if cand is not None and cand != self._default_identity + ), + None, + ) + if flow_identity is None: if last_error: raise last_error raise MissingUserIdentityError( @@ -397,7 +412,7 @@ async def ensure_access_token( ) user_key = self._build_store_key( - user_identity, + flow_identity, resolved.resource, resolved.issuer, resolved.scopes, @@ -412,7 +427,7 @@ async def ensure_access_token( record = await self._flow.authorize( context=context, - user=user_identity, + user=flow_identity, server_name=server_name, oauth_config=oauth_config, resource=resolved.resource, @@ -433,11 +448,10 @@ async def ensure_access_token( async def invalidate( self, *, - user: OAuthUserIdentity, + identity: OAuthUserIdentity, resource: str, authorization_server: str | None, scopes: Iterable[str], - session_id: str | None = None, ) -> None: canonical_resource = normalize_resource(resource, resource) canonical_auth_server = ( @@ -446,13 +460,16 @@ async def invalidate( else authorization_server ) key = self._build_store_key( - user, + identity, canonical_resource, canonical_auth_server or "", tuple(scopes), ) await self._token_store.delete(key) - if user.cache_key != self._default_identity.cache_key and canonical_auth_server: + if ( + identity.cache_key != self._default_identity.cache_key + and canonical_auth_server + ): default_key = self._build_store_key( self._default_identity, canonical_resource, @@ -460,17 +477,6 @@ async def invalidate( tuple(scopes), ) await self._token_store.delete(default_key) - if session_id: - session_identity = OAuthUserIdentity( - provider="mcp-session", subject=str(session_id) - ) - session_key = self._build_store_key( - session_identity, - canonical_resource, - canonical_auth_server or "", - tuple(scopes), - ) - await self._token_store.delete(session_key) async def _refresh_token( self, diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index eb7bd3110..0b74a41ce 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -3,6 +3,8 @@ mcp-agent workflows and agents as MCP tools. """ +from __future__ import annotations + import json from collections.abc import AsyncIterator from contextlib import asynccontextmanager @@ -11,6 +13,7 @@ import secrets import asyncio from pydantic import BaseModel, Field +from contextvars import ContextVar from mcp.server.fastmcp import Context as MCPContext, FastMCP from mcp.server.fastmcp.server import AuthSettings @@ -36,7 +39,11 @@ from mcp_agent.logging.logger import get_logger from mcp_agent.logging.logger import LoggingConfig from mcp_agent.mcp.mcp_server_registry import ServerRegistry -from mcp_agent.oauth.identity import OAuthUserIdentity +from mcp_agent.oauth.identity import ( + OAuthUserIdentity, + DEFAULT_PRECONFIGURED_IDENTITY, + session_identity as _session_identity_from_value, +) from mcp_agent.oauth.callbacks import callback_registry from mcp_agent.oauth.errors import ( CallbackTimeoutError, @@ -51,17 +58,29 @@ # Allows external workers (e.g., Temporal) to relay logs/prompts through MCPApp. _RUN_SESSION_REGISTRY: Dict[str, Any] = {} _RUN_EXECUTION_ID_REGISTRY: Dict[str, str] = {} +_RUN_IDENTITY_REGISTRY: Dict[str, OAuthUserIdentity] = {} _RUN_SESSION_LOCK = asyncio.Lock() _PENDING_PROMPTS: Dict[str, Dict[str, Any]] = {} _PENDING_PROMPTS_LOCK = asyncio.Lock() _IDEMPOTENCY_KEYS_SEEN: Dict[str, Set[str]] = {} _IDEMPOTENCY_KEYS_LOCK = asyncio.Lock() +_CURRENT_IDENTITY: ContextVar[OAuthUserIdentity | None] = ContextVar( + "mcp_current_identity", default=None +) -async def _register_session(run_id: str, execution_id: str, session: Any) -> None: + +async def _register_session( + run_id: str, + execution_id: str, + session: Any, + identity: OAuthUserIdentity | None = None, +) -> None: async with _RUN_SESSION_LOCK: _RUN_SESSION_REGISTRY[execution_id] = session _RUN_EXECUTION_ID_REGISTRY[run_id] = execution_id + if identity is not None: + _RUN_IDENTITY_REGISTRY[execution_id] = identity try: logger.debug( f"Registered upstream session for run_id={run_id}, execution_id={execution_id}, session_id={id(session)}" @@ -75,6 +94,7 @@ async def _unregister_session(run_id: str) -> None: execution_id = _RUN_EXECUTION_ID_REGISTRY.pop(run_id, None) if execution_id: _RUN_SESSION_REGISTRY.pop(execution_id, None) + _RUN_IDENTITY_REGISTRY.pop(execution_id, None) try: logger.debug( f"Unregistered upstream session mapping for run_id={run_id}, execution_id={execution_id}" @@ -98,6 +118,41 @@ async def _get_session(execution_id: str) -> Any | None: return session +def _get_identity_for_execution(execution_id: str) -> OAuthUserIdentity | None: + return _RUN_IDENTITY_REGISTRY.get(execution_id) + + +def _set_current_identity(identity: OAuthUserIdentity | None) -> None: + _CURRENT_IDENTITY.set(identity) + + +def get_current_identity() -> OAuthUserIdentity | None: + return _CURRENT_IDENTITY.get() + + +def _resolve_identity_for_request( + ctx: MCPContext | None = None, + app_context: "Context" | None = None, + execution_id: str | None = None, +) -> OAuthUserIdentity: + identity = _CURRENT_IDENTITY.get() + if identity is None and execution_id: + identity = _get_identity_for_execution(execution_id) + if identity is None and ctx is not None: + session_id = _extract_session_id_from_context(ctx) + identity = _session_identity_from_value(session_id) + if identity is None and app_context is None and ctx is not None: + app = _get_attached_app(ctx.fastmcp) + if app is not None and getattr(app, "context", None) is not None: + app_context = app.context + if identity is None and app_context is not None: + session_id = getattr(app_context, "session_id", None) + identity = _session_identity_from_value(session_id) + if identity is None: + identity = DEFAULT_PRECONFIGURED_IDENTITY + return identity + + class ServerContext(ContextDependent): """Context object for the MCP App server.""" @@ -191,6 +246,7 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: pass # Capture authenticated user information if available + session_id = _extract_session_id_from_context(ctx) identity: OAuthUserIdentity | None = None try: auth_user = auth_context_var.get() @@ -212,16 +268,24 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: maybe_token = MCPAccessToken.model_validate( access_token.model_dump() ) - identity = OAuthUserIdentity.from_access_token(maybe_token) + identity = OAuthUserIdentity.from_access_token(maybe_token) except Exception: identity = None + if identity is None: + identity = _session_identity_from_value(session_id) + + if identity is None: + identity = DEFAULT_PRECONFIGURED_IDENTITY + + _set_current_identity(identity) + app: MCPApp | None = _get_attached_app(ctx.fastmcp) if app is not None and getattr(app, "context", None) is not None: if session is not None: app.context.upstream_session = session - # Always overwrite the current user to avoid leaking identities between requests. - app.context.current_user = identity + if session_id: + app.context.session_id = session_id def _resolve_workflows_and_context( @@ -260,6 +324,47 @@ def _resolve_workflows_and_context( return None, None +def _extract_session_id_from_context(ctx: MCPContext) -> str | None: + """Attempt to extract the caller's MCP session identifier from the request context.""" + # Request-level meta (top-level) + try: + meta = getattr(ctx.request_context, "meta", None) + if meta is not None: + extra = getattr(meta, "model_extra", {}) or {} + session_id = ( + getattr(meta, "sessionId", None) + or getattr(meta, "session_id", None) + or extra.get("sessionId") + or extra.get("session_id") + ) + if session_id: + return str(session_id) + except Exception: + pass + + # Parameters meta within the request payload + try: + req = getattr(ctx.request_context, "request", None) + if req is not None: + root = getattr(req, "root", None) + params = getattr(root, "params", None) + meta = getattr(params, "meta", None) + if meta is not None: + extra = getattr(meta, "model_extra", {}) or {} + session_id = ( + getattr(meta, "sessionId", None) + or getattr(meta, "session_id", None) + or extra.get("sessionId") + or extra.get("session_id") + ) + if session_id: + return str(session_id) + except Exception: + pass + + return None + + def _resolve_workflow_registry(ctx: MCPContext) -> WorkflowRegistry | None: """Resolve the workflow registry regardless of startup mode.""" lifespan_ctx = getattr(ctx.request_context, "lifespan_context", None) @@ -532,10 +637,12 @@ async def _relay_notify(request: Request): ) # Successful with latest → bind mapping for consistency try: + identity = _get_identity_for_execution(execution_id) await _register_session( run_id=execution_id, execution_id=execution_id, session=latest_session, + identity=identity, ) # logger.info( # f"[notify] rebound mapping to latest session_id={id(latest_session)} for execution_id={execution_id}" @@ -763,10 +870,12 @@ async def _try_session_request( if result is not None: if register_session: try: + identity = _get_identity_for_execution(execution_id) await _register_session( run_id=execution_id, execution_id=execution_id, session=session, + identity=identity, ) # logger.debug( # f"[{log_prefix}] rebound mapping to session_id={id(session)} for execution_id={execution_id}") @@ -780,10 +889,12 @@ async def _try_session_request( ) if register_session: try: + identity = _get_identity_for_execution(execution_id) await _register_session( run_id=execution_id, execution_id=execution_id, session=session, + identity=identity, ) # logger.debug( # f"[{log_prefix}] rebound mapping to session_id={id(session)} for execution_id={execution_id}") @@ -1028,10 +1139,12 @@ async def _internal_workflows_log(request: Request): f"[log] delivered via latest session_id={id(latest_session)} level={level} ns={namespace}" ) try: + identity = _get_identity_for_execution(execution_id) await _register_session( run_id=execution_id, execution_id=execution_id, session=latest_session, + identity=identity, ) logger.info( f"[log] rebound mapping to latest session_id={id(latest_session)} for execution_id={execution_id}" @@ -1118,10 +1231,17 @@ async def _internal_human_prompts(request: Request): logger="mcp_agent.human", ) try: + identity = _get_identity_for_execution(execution_id) + if identity is None: + identity = _session_identity_from_value( + metadata.get("session_id") + or metadata.get("sessionId") + ) await _register_session( run_id=execution_id, execution_id=execution_id, session=latest_session, + identity=identity, ) logger.info( f"[human] rebound mapping to latest session_id={id(latest_session)} for execution_id={execution_id}" @@ -1377,8 +1497,14 @@ async def get_workflow_status( sess = getattr(ctx, "session", None) if sess and run_id: exec_id = _RUN_EXECUTION_ID_REGISTRY.get(run_id, run_id) + app_obj = _get_attached_app(ctx.fastmcp) + app_ctx = getattr(app_obj, "context", None) if app_obj else None + identity = _resolve_identity_for_request(ctx, app_ctx, exec_id) await _register_session( - run_id=run_id, execution_id=exec_id, session=sess + run_id=run_id, + execution_id=exec_id, + session=sess, + identity=identity, ) except Exception: pass @@ -1421,8 +1547,14 @@ async def resume_workflow( sess = getattr(ctx, "session", None) if sess and run_id: exec_id = _RUN_EXECUTION_ID_REGISTRY.get(run_id, run_id) + app_obj = _get_attached_app(ctx.fastmcp) + app_ctx = getattr(app_obj, "context", None) if app_obj else None + identity = _resolve_identity_for_request(ctx, app_ctx, exec_id) await _register_session( - run_id=run_id, execution_id=exec_id, session=sess + run_id=run_id, + execution_id=exec_id, + session=sess, + identity=identity, ) except Exception: pass @@ -1486,8 +1618,14 @@ async def cancel_workflow( sess = getattr(ctx, "session", None) if sess and run_id: exec_id = _RUN_EXECUTION_ID_REGISTRY.get(run_id, run_id) + app_obj = _get_attached_app(ctx.fastmcp) + app_ctx = getattr(app_obj, "context", None) if app_obj else None + identity = _resolve_identity_for_request(ctx, app_ctx, exec_id) await _register_session( - run_id=run_id, execution_id=exec_id, session=sess + run_id=run_id, + execution_id=exec_id, + session=sess, + identity=identity, ) except Exception: pass @@ -1560,17 +1698,7 @@ async def workflow_pre_auth( if not app_context.token_manager: raise ToolError("OAuth token manager not available.") - current_user = app_context.current_user - if current_user is None: - session_id = getattr(app_context, "session_id", None) - if session_id: - current_user = OAuthUserIdentity( - provider="mcp-session", subject=str(session_id) - ) - else: - raise ToolError( - "Authenticated user required for workflow pre-authorization." - ) + identity = _resolve_identity_for_request(ctx, app_context) if not tokens: raise ToolError("At least one token must be provided.") @@ -1601,7 +1729,7 @@ async def workflow_pre_auth( ) continue - server_config = app_context.server_registry.get_server_config( + server_config = app_context.server_registry.registry.get( server_name ) if not server_config: @@ -1612,7 +1740,7 @@ async def workflow_pre_auth( await app_context.token_manager.store_user_token( context=app_context, - user=current_user, + user=identity, server_name=server_name, server_config=server_config, token_data=token_data, @@ -2241,10 +2369,12 @@ def _normalize_gateway_url(url: str | None) -> str | None: # Register upstream session for this run so external workers can proxy logs/prompts try: + identity = _resolve_identity_for_request(ctx, app_context, execution_id) await _register_session( run_id=execution.run_id, execution_id=execution_id, session=getattr(ctx, "session", None), + identity=identity, ) except Exception: pass diff --git a/tests/test_token_manager.py b/tests/test_token_manager.py index 422dc37aa..90a1c921a 100644 --- a/tests/test_token_manager.py +++ b/tests/test_token_manager.py @@ -25,11 +25,9 @@ class DummyContext: def __init__( self, session_id: str | None, - current_user: OAuthUserIdentity | None, config=None, ): self.session_id = session_id - self.current_user = current_user self.config = config @@ -62,12 +60,12 @@ async def test_preconfigured_token_lookup_and_invalidation(): manager._resolve_oauth_context = AsyncMock(return_value=resolved) # type: ignore[attr-defined] await manager.store_preconfigured_token( - context=DummyContext(session_id=None, current_user=None), + context=DummyContext(session_id=None), server_name="github", server_config=server_config, ) - context = DummyContext(session_id="session-1", current_user=None) + context = DummyContext(session_id="session-1") token = await manager.ensure_access_token( context=context, server_name="github", @@ -82,11 +80,10 @@ async def test_preconfigured_token_lookup_and_invalidation(): resolved.scopes, ) await manager.invalidate( - user=DEFAULT_PRECONFIGURED_IDENTITY, + identity=DEFAULT_PRECONFIGURED_IDENTITY, resource=resolved.resource, authorization_server=resolved.issuer, scopes=resolved.scopes, - session_id=context.session_id, ) assert await store.get(key) is None @@ -124,7 +121,7 @@ async def test_store_user_token_uses_workflow_and_session_metadata(): "expires_at": 0, } - context = DummyContext(session_id="session-xyz", current_user=user_identity) + context = DummyContext(session_id="session-xyz") await manager.store_user_token( context=context, user=user_identity, diff --git a/uv.lock b/uv.lock index 4638566fb..66da0d691 100644 --- a/uv.lock +++ b/uv.lock @@ -1588,18 +1588,6 @@ 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 = "hvac" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/48/a4/c0b698a7250b7a5c2956427406560701862215c646e079a7907846608f44/hvac-2.3.0.tar.gz", hash = "sha256:1b85e3320e8642dd82f234db63253cda169a817589e823713dc5fca83119b1e2", size = 332660, upload-time = "2024-06-18T14:46:09.748Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/34/56facf52e2ea14ce640f434ccf00311af6f3a1df0019d4682ba28ea09948/hvac-2.3.0-py3-none-any.whl", hash = "sha256:a3afc5710760b6ee9b3571769df87a0333da45da05a5f9f963e1d3925a84be7d", size = 155860, upload-time = "2024-06-18T14:46:05.399Z" }, -] - [[package]] name = "identify" version = "2.6.12" @@ -2234,7 +2222,7 @@ requires-dist = [ { name = "watchdog", specifier = ">=6.0.0" }, { name = "websockets", specifier = ">=12.0" }, ] -provides-extras = ["temporal", "anthropic", "anthropic-bedrock", "anthropic-vertex", "bedrock", "openai", "azure", "google", "cohere", "langchain", "redis", "crewai", "cli"] +provides-extras = ["temporal", "anthropic", "anthropic-bedrock", "anthropic-vertex", "bedrock", "openai", "azure", "google", "cohere", "langchain", "redis", "crewai"] [package.metadata.requires-dev] dev = [ From c4f6a44f0306f9b9ea8b1807381983883eccbd4e Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Wed, 8 Oct 2025 21:06:50 -0400 Subject: [PATCH 14/25] Update readme --- examples/oauth/README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/examples/oauth/README.md b/examples/oauth/README.md index 5b66b1caa..09976af7d 100644 --- a/examples/oauth/README.md +++ b/examples/oauth/README.md @@ -7,7 +7,9 @@ Two complementary scenarios demonstrate how OAuth integrates with MCP: Shows the full authorization code flow for a synchronous tool. When the client calls the tool, the server sends an `auth/request` message and the client walks the user through the browser-based login. Subsequent tool calls -reuse the stored token. +reuse the stored token—after the first run, re-run +`uv run examples/oauth/interactive_tool/client.py` (with the server still +running) and you should see the result immediately with no additional prompt. ## workflow_pre_auth @@ -15,3 +17,14 @@ Demonstrates seeding tokens via the `workflows-pre-auth` tool before running an asynchronous workflow. This is useful when workflows execute in the background (e.g., Temporal) and cannot perform interactive authentication on their own. + +## Using Redis for token storage + +If you want to exercise the Redis-backed token store instead of the default +in-memory store: + +1. Start a Redis server (for example: `docker run --rm -p 6379:6379 redis:7-alpine`). +2. Install the extra dependencies: `pip install -e .[redis]`. +3. Export `OAUTH_REDIS_URL`, e.g. `export OAUTH_REDIS_URL=redis://127.0.0.1:6379`. +4. Run the examples as usual (interactive tool or workflow). Tokens will be + cached in Redis and server restarts will reuse them. From f3f683de2f65093d23ecd978085cb5a6473b7287 Mon Sep 17 00:00:00 2001 From: Roman van der Krogt Date: Thu, 9 Oct 2025 18:59:17 +0100 Subject: [PATCH 15/25] Fix user conflation on temporal; start of moving cache to app side --- examples/oauth/workflow_pre_auth/main.py | 62 ++++++++--- src/mcp_agent/oauth/flow.py | 2 + src/mcp_agent/oauth/manager.py | 129 ++++++++++++++++++++++- src/mcp_agent/server/app_server.py | 77 ++++++++++++-- 4 files changed, 250 insertions(+), 20 deletions(-) diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py index 6f3a7376e..3dbac8d0d 100644 --- a/examples/oauth/workflow_pre_auth/main.py +++ b/examples/oauth/workflow_pre_auth/main.py @@ -16,7 +16,7 @@ MCPSettings, OAuthSettings, OAuthTokenStoreSettings, - Settings, + Settings, TemporalSettings, ) from mcp_agent.core.context import Context as AppContext from mcp_agent.mcp.gen_client import gen_client @@ -27,6 +27,23 @@ mcp = FastMCP(name="basic_agent_server", instructions="My basic agent server example.") +# Get client id and secret from environment variables +client_id = os.getenv("GITHUB_CLIENT_ID") +client_secret = os.getenv("GITHUB_CLIENT_SECRET") + +if not client_id or not client_secret: + print( + "\nGitHub client id and/or secret not found in GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET " + "environment variables." + ) + print("\nTo create these:") + print("1. Open your profile on github.com and navigate to 'Developer Settings'") + print("2. Create a new OAuth app and create a client secret for it.") + print("3. Create environment variables:") + print("export GITHUB_CLIENT_ID='your_client_id_here'") + print("export GITHUB_CLIENT_SECRET='your_client_secret_here'") + exit(1) + redis_url = os.getenv("OAUTH_REDIS_URL") if redis_url: token_store_settings = OAuthTokenStoreSettings( @@ -39,7 +56,13 @@ token_store_settings = OAuthTokenStoreSettings(refresh_leeway_seconds=60) settings = Settings( - execution_engine="asyncio", + execution_engine="temporal", + temporal=TemporalSettings( + host="localhost:7233", + namespace="default", + task_queue="mcp-agent", + max_concurrent_activities=10, + ), logger=LoggerSettings(level="info"), oauth=OAuthSettings( callback_base_url=AnyHttpUrl("http://localhost:8000"), @@ -54,6 +77,9 @@ url="https://api.githubcopilot.com/mcp/", auth=MCPServerAuthSettings( oauth=MCPOAuthClientSettings( + client_id=client_id, + client_secret=client_secret, + use_internal_callback=True, enabled=True, scopes=[ "read:org", # Required for search_orgs tool @@ -81,18 +107,16 @@ ) -@app.tool(name="github_org_search") -async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: - # Use the context's app if available for proper logging with upstream_session - _app = app_ctx.app if app_ctx else app - # Ensure the app's logger is bound to the current context with upstream_session - if _app._logger and hasattr(_app._logger, "_bound_context"): - _app._logger._bound_context = app_ctx +@app.workflow_task(name="github_org_search_activity") +async def github_org_search_activity(query: str) -> str: + from mcp_agent.mcp.gen_client import gen_client + print("running activity)") try: async with gen_client( - "github", server_registry=app_ctx.server_registry, context=app_ctx + "github", server_registry=app.context.server_registry, context=app.context ) as github_client: + print("got client") result = await github_client.call_tool( "search_orgs", {"query": query, "perPage": 10, "sort": "best-match", "order": "desc"}, @@ -111,11 +135,25 @@ async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> except json.JSONDecodeError: pass + print(f"Organizations: {organizations}") return str(organizations) - except Exception: + except Exception as e: import traceback - return f"Error: {traceback.format_exc()}" + traceback.print_exc() + return f"Error: {e}" + + + +@app.tool(name="github_org_search") +async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: + if app._logger and hasattr(app._logger, "_bound_context"): + app._logger._bound_context = app.context + + result = await app.executor.execute(github_org_search_activity, query) + print(f"Result: {result}") + + return result async def main(): diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index b2f0523b7..a1eb28c80 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -116,6 +116,8 @@ async def authorize( "message": f"Authorization required for {server_name}", "redirect_uri_options": redirect_options, "flow_id": flow_id, + "server_name": server_name, + "scopes": scope_param, } result = await _send_auth_request(context, request_payload) diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index 448f6e9ea..22f8f35dd 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -296,6 +296,105 @@ async def store_user_token( ) await self._token_store.set(key, record) + async def get_access_token_if_present( + self, + *, + context: "Context", + server_name: str, + server_config, + scopes: Iterable[str] | None = None, + identity: OAuthUserIdentity | None = None, + ) -> TokenRecord | None: + oauth_config: MCPOAuthClientSettings | None = None + if server_config and server_config.auth: + oauth_config = getattr(server_config.auth, "oauth", None) + if not oauth_config or not oauth_config.enabled: + raise OAuthFlowError( + f"Server '{server_name}' is not configured for OAuth authentication" + ) + + requested_scopes = ( + list(scopes) if scopes is not None else list(oauth_config.scopes or []) + ) + resolved = await self._resolve_oauth_context( + context=context, + server_name=server_name, + server_config=server_config, + oauth_config=oauth_config, + requested_scopes=requested_scopes, + ) + + context_identity = None + try: + from mcp_agent.server import app_server + + context_identity = app_server.get_current_identity() + except Exception: + context_identity = None + session_identity = self._session_identity(context) + + identity_candidates = [ + identity, + context_identity, + session_identity, + self._default_identity, + ] + identities = _dedupe(identity_candidates) + if not identities: + raise MissingUserIdentityError( + "No authenticated user available for OAuth authorization" + ) + + leeway = ( + self._settings.token_store.refresh_leeway_seconds + if self._settings.token_store + else 60 + ) + + for identity in identities: + key = self._build_store_key( + identity, + resolved.resource, + resolved.issuer, + resolved.scopes, + ) + lock = self._locks[key] + async with lock: + record = await self._token_store.get(key) + if record and not record.is_expired(leeway_seconds=leeway): + return record + + if record and record.refresh_token: + try: + refreshed = await self._refresh_token( + record, + oauth_config=oauth_config, + auth_metadata=resolved.authorization_metadata, + resource=resolved.resource, + scopes=resolved.scopes, + ) + except TokenRefreshError as exc: + logger.warning( + "Failed to refresh token for identity '%s': %s", + identity.cache_key, + exc, + ) + await self._token_store.delete(key) + continue + + if refreshed: + refreshed = refreshed.model_copy( + update={ + "resource": resolved.resource, + "authorization_server": resolved.issuer, + } + ) + await self._token_store.set(key, refreshed) + return refreshed + + await self._token_store.delete(key) + return None + async def ensure_access_token( self, *, @@ -332,6 +431,7 @@ async def ensure_access_token( except Exception: context_identity = None session_identity = self._session_identity(context) + identity_candidates = [ identity, context_identity, @@ -442,6 +542,7 @@ async def ensure_access_token( "authorization_server": resolved.issuer, } ) + await self._token_store.set(user_key, record) return record @@ -665,7 +766,33 @@ async def aclose(self) -> None: await close() def _session_identity(self, context: "Context") -> OAuthUserIdentity | None: - session_id = getattr(context, "session_id", None) + in_temporal = False + try: + from temporalio import workflow as _wf # type: ignore + from temporalio import activity as _a # type: ignore + + try: + in_temporal = bool(_wf.in_workflow()) or bool(_a.in_activity()) + except Exception: + in_temporal = False + except Exception: + in_temporal = False + + session_id = None + if in_temporal: + # Base the identity on the Temporal workflow execution ID + try: + from mcp_agent.executor.temporal.temporal_context import ( + get_execution_id as _get_exec_id, + ) + session_id = _get_exec_id() + except Exception: + pass + + if not session_id: + session_id = getattr(context, "session_id", None) + if not session_id: return None return OAuthUserIdentity(provider="mcp-session", subject=str(session_id)) + diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index 0b74a41ce..fd5b10f61 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -766,7 +766,8 @@ async def _handle_request_via_rpc( return None async def _handle_specific_request( - session, method: str, params: dict, log_prefix: str = "request" + session: Any, method: str, params: dict, identity: OAuthUserIdentity, + context: "Context", log_prefix: str = "request" ): """Handle specific request types with structured request/response.""" from mcp.types import ( @@ -819,6 +820,28 @@ async def _handle_specific_request( return result.model_dump(by_alias=True, mode="json", exclude_none=True) elif method == "auth/request": # TODO: special handling of auth request, should be replaced by future URL elicitation + + # first check to see if the token is in the cache already + try: + if context and hasattr(context, "token_manager"): + manager = context.token_manager + if manager: + server_name = params["server_name"] + server_config = context.server_registry.get_server_config(server_name) + scopes = params.get("scopes", []) + + token = await manager.get_access_token_if_present( + context=context, + server_name=server_name, + server_config=server_config, + scopes=scopes, + identity=identity) + if token: + return token + except Exception: + # elicitation fallback below + pass + class AuthToken(BaseModel): confirmation: str = Field( description="Please press enter to confirm this message has been received" @@ -849,6 +872,27 @@ class AuthToken(BaseModel): f"Timed out waiting for OAuth callback after {timeout} seconds" ) from exc + try: + if context and hasattr(context, "token_manager"): + manager = context.token_manager + if manager: + server_name = params["server_name"] + server_config = context.server_registry.get_server_config(server_name) + scopes = params.get("scopes", []) + + token_data={} + + await manager.store_user_token( + context=context, + user=identity, + server_name=server_name, + server_config=server_config, + token_data=token_data + ) + except Exception: + # Token is not stored, we have to auth again next time. + pass + return callback_data else: raise ValueError(f"unsupported method: {method}") @@ -858,10 +902,16 @@ async def _try_session_request( method: str, params: dict, execution_id: str, + context: "Context", log_prefix: str = "request", register_session: bool = False, ): """Try to handle a request via session, with optional registration.""" + try: + identity = _get_identity_for_execution(execution_id) + except Exception: + identity = None + try: # First try generic RPC passthrough result = await _handle_request_via_rpc( @@ -870,7 +920,6 @@ async def _try_session_request( if result is not None: if register_session: try: - identity = _get_identity_for_execution(execution_id) await _register_session( run_id=execution_id, execution_id=execution_id, @@ -885,11 +934,10 @@ async def _try_session_request( # Fallback to specific structured request handling result = await _handle_specific_request( - session, method, params, log_prefix + session, method, params, identity, context, log_prefix ) if register_session: try: - identity = _get_identity_for_execution(execution_id) await _register_session( run_id=execution_id, execution_id=execution_id, @@ -915,6 +963,12 @@ async def _try_session_request( include_in_schema=False, ) async def _relay_request(request: Request): + app = _get_attached_app(mcp_server) + if app and app.context: + app_context = app.context + else: + app_context = None + body = await request.json() execution_id = request.path_params.get("execution_id") method = body.get("method") @@ -934,6 +988,7 @@ async def _relay_request(request: Request): method, params, execution_id, + app_context, log_prefix="request", register_session=True, ) @@ -959,6 +1014,7 @@ async def _relay_request(request: Request): method, params, execution_id, + app_context, log_prefix="request", register_session=False, ) @@ -1013,6 +1069,12 @@ async def _async_relay_request(request: Request): # Create background task to handle the request and signal the workflow async def _handle_async_request_task(): + app = _get_attached_app(mcp_server) + if app and app.context: + app_context = app.context + else: + app_context = None + try: result = None @@ -1025,6 +1087,7 @@ async def _handle_async_request_task(): method, params, execution_id, + app_context, log_prefix="async-request", register_session=True, ) @@ -1043,6 +1106,7 @@ async def _handle_async_request_task(): method, params, execution_id, + app_context, log_prefix="async-request", register_session=False, ) @@ -1060,9 +1124,8 @@ async def _handle_async_request_task(): # Signal the workflow with the result using method-specific signal try: # Try to get Temporal client from the app context - app = _get_attached_app(mcp_server) - if app and app.context and hasattr(app.context, "executor"): - executor = app.context.executor + if app_context and hasattr(app_context, "executor"): + executor = app_context.executor if hasattr(executor, "client"): client = executor.client # Find the workflow using execution_id as both workflow_id and run_id From 5acbea59c8ef6159228a5daa4b41395c257ba0e0 Mon Sep 17 00:00:00 2001 From: Roman van der Krogt Date: Thu, 9 Oct 2025 23:02:09 +0100 Subject: [PATCH 16/25] cache tokens requested from temporal flow in app --- examples/oauth/workflow_pre_auth/main.py | 1 - src/mcp_agent/oauth/flow.py | 28 ++- src/mcp_agent/oauth/manager.py | 2 + src/mcp_agent/server/app_server.py | 249 ++++++++++++++++++----- 4 files changed, 221 insertions(+), 59 deletions(-) diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py index 3dbac8d0d..7eaabcb5b 100644 --- a/examples/oauth/workflow_pre_auth/main.py +++ b/examples/oauth/workflow_pre_auth/main.py @@ -109,7 +109,6 @@ @app.workflow_task(name="github_org_search_activity") async def github_org_search_activity(query: str) -> str: - from mcp_agent.mcp.gen_client import gen_client print("running activity)") try: diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index a1eb28c80..f7aca671c 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -3,13 +3,14 @@ from __future__ import annotations import asyncio -import time +import httpx import uuid +import time + from json import JSONDecodeError from typing import Any, Dict, Sequence from urllib.parse import parse_qs, urlparse -import httpx from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata from mcp.server.session import ServerSession @@ -19,9 +20,9 @@ from mcp_agent.oauth.callbacks import callback_registry from mcp_agent.oauth.errors import ( AuthorizationDeclined, - CallbackTimeoutError, MissingUserIdentityError, OAuthFlowError, + CallbackTimeoutError, ) from mcp_agent.oauth.identity import OAuthUserIdentity from mcp_agent.oauth.pkce import ( @@ -117,7 +118,19 @@ async def authorize( "redirect_uri_options": redirect_options, "flow_id": flow_id, "server_name": server_name, - "scopes": scope_param, + "scopes": scopes, + "flow_timeout_seconds": self._settings.flow_timeout_seconds, + "state": state, + "token_endpoint": str(auth_metadata.token_endpoint), + "redirect_uri": redirect_uri, + "client_id": client_id, + "code_verifier": code_verifier, + "resource": resource, + "scope_param": scope_param, + "extra_token_params": oauth_config.extra_token_params or {}, + "client_secret": oauth_config.client_secret, + "issuer_str": str(getattr(auth_metadata, "issuer", "") or ""), + "authorization_server_url": authorization_server_url, } result = await _send_auth_request(context, request_payload) @@ -131,6 +144,12 @@ async def authorize( callback_data = result if callback_future is not None: await callback_registry.discard(flow_id) + elif result and result.get("token_record"): + if callback_future is not None: + await callback_registry.discard(flow_id) + + tr_data = result["token_record"] + return TokenRecord.model_validate_json(tr_data) elif callback_future is not None: timeout = self._settings.flow_timeout_seconds or 300 try: @@ -223,6 +242,7 @@ async def authorize( ) + def _parse_callback_params(url: str) -> Dict[str, str]: parsed = urlparse(url) params = {} diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index 22f8f35dd..ab7e33cdf 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -294,6 +294,7 @@ async def store_user_token( resolved.issuer, record.scopes, ) + await self._token_store.set(key, record) async def get_access_token_if_present( @@ -316,6 +317,7 @@ async def get_access_token_if_present( requested_scopes = ( list(scopes) if scopes is not None else list(oauth_config.scopes or []) ) + resolved = await self._resolve_oauth_context( context=context, server_name=server_name, diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index fd5b10f61..e87b01eef 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -6,14 +6,19 @@ from __future__ import annotations import json -from collections.abc import AsyncIterator -from contextlib import asynccontextmanager -from typing import Any, Dict, List, Optional, Set, Tuple, Type, TYPE_CHECKING +import time +import httpx import os import secrets import asyncio + +from collections.abc import AsyncIterator +from contextlib import asynccontextmanager +from typing import Any, Dict, List, Optional, Set, Tuple, Type, TYPE_CHECKING from pydantic import BaseModel, Field from contextvars import ContextVar +from urllib.parse import parse_qs, urlparse +from json import JSONDecodeError from mcp.server.fastmcp import Context as MCPContext, FastMCP from mcp.server.fastmcp.server import AuthSettings @@ -21,11 +26,12 @@ AuthenticatedUser, auth_context_var, ) -from starlette.requests import Request -from starlette.responses import HTMLResponse, JSONResponse from mcp.server.fastmcp.exceptions import ToolError from mcp.server.fastmcp.tools import Tool as FastTool +from starlette.requests import Request +from starlette.responses import HTMLResponse, JSONResponse + from mcp_agent.app import MCPApp from mcp_agent.agents.agent import Agent from mcp_agent.core.context_dependent import ContextDependent @@ -35,7 +41,6 @@ WorkflowRegistry, WorkflowRunsPage, ) - from mcp_agent.logging.logger import get_logger from mcp_agent.logging.logger import LoggingConfig from mcp_agent.mcp.mcp_server_registry import ServerRegistry @@ -45,10 +50,14 @@ session_identity as _session_identity_from_value, ) from mcp_agent.oauth.callbacks import callback_registry +from mcp_agent.server.token_verifier import MCPAgentTokenVerifier from mcp_agent.oauth.errors import ( + AuthorizationDeclined, CallbackTimeoutError, + OAuthFlowError, ) -from mcp_agent.server.token_verifier import MCPAgentTokenVerifier +from mcp_agent.oauth.records import TokenRecord + if TYPE_CHECKING: from mcp_agent.core.context import Context @@ -359,6 +368,11 @@ def _extract_session_id_from_context(ctx: MCPContext) -> str | None: ) if session_id: return str(session_id) + + query_params = getattr(req, "query_params", None) + if query_params is not None: + if "session_id" in query_params: + return query_params.get("session_id") except Exception: pass @@ -791,10 +805,10 @@ async def _handle_specific_request( params=CreateMessageRequestParams(**params), ) ) - result = await session.send_request( + callback_data = await session.send_request( request=req, result_type=CreateMessageResult ) # type: ignore[attr-defined] - return result.model_dump(by_alias=True, mode="json", exclude_none=True) + return callback_data.model_dump(by_alias=True, mode="json", exclude_none=True) elif method == "elicitation/create": req = ServerRequest( ElicitRequest( @@ -802,33 +816,33 @@ async def _handle_specific_request( params=ElicitRequestParams(**params), ) ) - result = await session.send_request( + callback_data = await session.send_request( request=req, result_type=ElicitResult ) # type: ignore[attr-defined] - return result.model_dump(by_alias=True, mode="json", exclude_none=True) + return callback_data.model_dump(by_alias=True, mode="json", exclude_none=True) elif method == "roots/list": req = ServerRequest(ListRootsRequest(method="roots/list")) - result = await session.send_request( + callback_data = await session.send_request( request=req, result_type=ListRootsResult ) # type: ignore[attr-defined] - return result.model_dump(by_alias=True, mode="json", exclude_none=True) + return callback_data.model_dump(by_alias=True, mode="json", exclude_none=True) elif method == "ping": req = ServerRequest(PingRequest(method="ping")) - result = await session.send_request( + callback_data = await session.send_request( request=req, result_type=EmptyResult ) # type: ignore[attr-defined] - return result.model_dump(by_alias=True, mode="json", exclude_none=True) + return callback_data.model_dump(by_alias=True, mode="json", exclude_none=True) elif method == "auth/request": # TODO: special handling of auth request, should be replaced by future URL elicitation # first check to see if the token is in the cache already + server_name = params["server_name"] + scopes = params.get("scopes", []) try: if context and hasattr(context, "token_manager"): manager = context.token_manager if manager: - server_name = params["server_name"] server_config = context.server_registry.get_server_config(server_name) - scopes = params.get("scopes", []) token = await manager.get_access_token_if_present( context=context, @@ -842,61 +856,180 @@ async def _handle_specific_request( # elicitation fallback below pass - class AuthToken(BaseModel): - confirmation: str = Field( - description="Please press enter to confirm this message has been received" - ) - - flow_id = params["flow_id"] - callback_future = await callback_registry.create_handle(flow_id) - - req = ElicitRequest( - method="elicitation/create", - params=ElicitRequestParams( - message=params["message"] + "\n\n" + params["url"], - requestedSchema=AuthToken.model_json_schema(), - ), - ) - - result = await session.send_request( - request=req, result_type=ElicitResult - ) # type: ignore[attr-defined] - - timeout = 300 - try: - callback_data = await asyncio.wait_for( - callback_future, timeout=timeout - ) - except asyncio.TimeoutError as exc: - raise CallbackTimeoutError( - f"Timed out waiting for OAuth callback after {timeout} seconds" - ) from exc + # token is not present in the cache, perform the auth flow + record = await _perform_auth_flow(context, params, scopes, session) + # save in the token manager for next time try: if context and hasattr(context, "token_manager"): manager = context.token_manager if manager: - server_name = params["server_name"] server_config = context.server_registry.get_server_config(server_name) - scopes = params.get("scopes", []) - token_data={} + token_data = { + "access_token": record.access_token, + "refresh_token": record.refresh_token, + "scopes": record.scopes, + "authorization_server": record.authorization_server, + "expires_at": record.expires_at, + "token_type": "Bearer", + } await manager.store_user_token( context=context, user=identity, server_name=server_name, - server_config=server_config, - token_data=token_data - ) + server_config = server_config, + token_data = token_data) except Exception: - # Token is not stored, we have to auth again next time. pass - return callback_data + return {"token_record": record.model_dump_json()} else: raise ValueError(f"unsupported method: {method}") + async def _perform_auth_flow(context, params, scopes, session): + from mcp.types import ( + ElicitRequest, + ElicitRequestParams, + ElicitResult, + ) + + class AuthToken(BaseModel): + confirmation: str = Field( + description="Please press enter to confirm this message has been received" + ) + + flow_id = params["flow_id"] + flow_timeout_seconds = params.get("flow_timeout_seconds") + state = params["state"] + token_endpoint = params["token_endpoint"] + redirect_uri = params["redirect_uri"] + client_id = params["client_id"] + code_verifier = params["code_verifier"] + resource = params.get("resource") + scope_param = params.get("scope_param") + extra_token_params = params.get("extra_token_params", {}) + client_secret = params.get("client_secret") + issuer_str = params.get("issuer_str") + authorization_server_url = params.get("authorization_server_url") + callback_future = await callback_registry.create_handle(flow_id) + req = ElicitRequest( + method="elicitation/create", + params=ElicitRequestParams( + message=params["message"] + "\n\n" + params["url"], + requestedSchema=AuthToken.model_json_schema(), + ), + ) + await session.send_request( + request=req, result_type=ElicitResult + ) # type: ignore[attr-defined] + timeout = 300 + try: + callback_data = await asyncio.wait_for( + callback_future, timeout=timeout + ) + except asyncio.TimeoutError as exc: + raise CallbackTimeoutError( + f"Timed out waiting for OAuth callback after {timeout} seconds" + ) from exc + try: + if callback_data and callback_data.get("url"): + callback_data = _parse_callback_params(callback_data["url"]) + if callback_future is not None: + await callback_registry.discard(flow_id) + elif callback_data and callback_data.get("code"): + callback_data = callback_data + if callback_future is not None: + await callback_registry.discard(flow_id) + elif callback_future is not None: + timeout = flow_timeout_seconds or 300 + try: + callback_data = await asyncio.wait_for( + callback_future, timeout=timeout + ) + except asyncio.TimeoutError as exc: + raise CallbackTimeoutError( + f"Timed out waiting for OAuth callback after {timeout} seconds" + ) from exc + else: + raise AuthorizationDeclined( + "Authorization request was declined by the user" + ) + finally: + if callback_future is not None: + await callback_registry.discard(flow_id) + error = callback_data.get("error") + if error: + description = callback_data.get("error_description") or error + raise OAuthFlowError(f"Authorization server returned error: {description}") + returned_state = callback_data.get("state") + if returned_state != state: + raise OAuthFlowError("State mismatch detected in OAuth callback") + authorization_code = callback_data.get("code") + if not authorization_code: + raise OAuthFlowError("Authorization callback did not include code") + token_endpoint = str(token_endpoint) + data: Dict[str, Any] = { + "grant_type": "authorization_code", + "code": authorization_code, + "redirect_uri": redirect_uri, + "client_id": client_id, + "code_verifier": code_verifier, + "resource": resource, + } + if scope_param: + data["scope"] = scope_param + if extra_token_params: + data.update(extra_token_params) + auth = None + if client_secret: + data["client_secret"] = client_secret + try: + if context and hasattr(context, "token_manager"): + manager = context.token_manager + if manager: + http_client = manager._http_client + except Exception: + http_client = None + if not http_client: + http_client = httpx.AsyncClient(timeout=30.0) + token_response = await http_client.post( + token_endpoint, data=data, auth=auth, headers={"Accept": "application/json"} + ) + token_response.raise_for_status() + try: + callback_data = token_response.json() + except JSONDecodeError: + callback_data = _parse_callback_params("?" + token_response.text) + access_token = callback_data.get("access_token") + if not access_token: + raise OAuthFlowError("Token endpoint response missing access_token") + refresh_token = callback_data.get("refresh_token") + expires_in = callback_data.get("expires_in") + expires_at = None + if isinstance(expires_in, (int, float)): + expires_at = time.time() + float(expires_in) + scope_from_payload = callback_data.get("scope") + if isinstance(scope_from_payload, str) and scope_from_payload.strip(): + effective_scopes = tuple(scope_from_payload.split()) + else: + effective_scopes = tuple(scopes) + record = TokenRecord( + access_token=access_token, + refresh_token=refresh_token, + expires_at=expires_at, + scopes=effective_scopes, + token_type=str(callback_data.get("token_type", "Bearer")), + resource=resource, + authorization_server=issuer_str, + metadata={ + "raw": token_response.text, + "authorization_server_url": authorization_server_url, + }, + ) + return record + async def _try_session_request( session, method: str, @@ -2496,3 +2629,11 @@ async def _workflow_status( # endregion + +def _parse_callback_params(url: str) -> Dict[str, str]: + parsed = urlparse(url) + params = {} + params.update({k: v[-1] for k, v in parse_qs(parsed.query).items()}) + if parsed.fragment: + params.update({k: v[-1] for k, v in parse_qs(parsed.fragment).items()}) + return params \ No newline at end of file From c90c17b54f960de2e45301e1ef50cc2dc68d54f1 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Thu, 9 Oct 2025 17:23:32 -0400 Subject: [PATCH 17/25] Implement local loopback OAuth callback server for MCPApp client-only runs --- src/mcp_agent/oauth/callbacks.py | 27 +++++ src/mcp_agent/oauth/flow.py | 168 ++++++++++++++++++++++++++++++- 2 files changed, 193 insertions(+), 2 deletions(-) diff --git a/src/mcp_agent/oauth/callbacks.py b/src/mcp_agent/oauth/callbacks.py index 8bfa99957..a827f0fa8 100644 --- a/src/mcp_agent/oauth/callbacks.py +++ b/src/mcp_agent/oauth/callbacks.py @@ -12,6 +12,9 @@ class OAuthCallbackRegistry: def __init__(self) -> None: self._pending: Dict[str, asyncio.Future[Dict[str, Any]]] = {} self._lock = asyncio.Lock() + # Map OAuth state -> flow_id to support loopback callbacks that + # only receive the state param (no flow id in the redirect path). + self._state_to_flow: Dict[str, str] = {} async def create_handle(self, flow_id: str) -> asyncio.Future[Dict[str, Any]]: """Create (or reuse) a future associated with a flow identifier.""" @@ -34,6 +37,26 @@ async def deliver(self, flow_id: str, payload: Dict[str, Any]) -> bool: future.set_result(payload) return True + async def register_state(self, flow_id: str, state: str) -> None: + """Associate an OAuth state value with a flow id for loopback delivery.""" + if not state: + return + async with self._lock: + self._state_to_flow[state] = flow_id + + async def deliver_by_state(self, state: str, payload: Dict[str, Any]) -> bool: + """Deliver a callback payload by resolving the flow id from state. + + Returns False if the state is unknown. + """ + if not state: + return False + async with self._lock: + flow_id = self._state_to_flow.get(state) + if not flow_id: + return False + return await self.deliver(flow_id, payload) + async def fail(self, flow_id: str, exc: Exception) -> bool: async with self._lock: future = self._pending.get(flow_id) @@ -48,6 +71,10 @@ async def discard(self, flow_id: str) -> None: future = self._pending.pop(flow_id, None) if future and not future.done(): future.cancel() + # Best-effort cleanup of any state entries pointing to this flow + for s, f in list(self._state_to_flow.items()): + if f == flow_id: + self._state_to_flow.pop(s, None) # Global registry used by server + flow coordinator diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index f7aca671c..eb6d7c9dd 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -8,7 +8,7 @@ import time from json import JSONDecodeError -from typing import Any, Dict, Sequence +from typing import Any, Dict, Sequence, Iterable, Tuple from urllib.parse import parse_qs, urlparse from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata @@ -31,6 +31,7 @@ generate_state, ) from mcp_agent.oauth.records import TokenRecord +from mcp_agent.oauth.errors import OAuthFlowError logger = get_logger(__name__) @@ -73,6 +74,26 @@ async def authorize( internal_redirect = f"{str(self._settings.callback_base_url).rstrip('/')}/internal/oauth/callback/{flow_id}" redirect_options.insert(0, internal_redirect) + # If there is no upstream session to handle auth/request, we will use a + # local loopback callback listener on 127.0.0.1 with a configurable fixed + # set of ports. Build candidate redirect URIs here but only start the + # listener if we detect there is no upstream session. + loopback_candidates: list[Tuple[str, int]] = [] + try: + # Expect a list of ports on settings under 'loopback_ports'; if not + # present, use a small default set that mirrors common tooling. + ports: Iterable[int] = getattr( + self._settings, "loopback_ports", (33418, 33419, 33420) + ) + for p in ports: + loopback_candidates.append((f"http://127.0.0.1:{p}/callback", p)) + loopback_candidates.append((f"http://localhost:{p}/callback", p)) + except Exception: + pass + for url, _ in loopback_candidates: + if url not in redirect_options: + redirect_options.append(url) + if not redirect_options: raise OAuthFlowError( "No redirect URI options configured for OAuth authorization flow" @@ -133,7 +154,18 @@ async def authorize( "authorization_server_url": authorization_server_url, } - result = await _send_auth_request(context, request_payload) + # Try to send an auth/request upstream if available. If not available, + # fall back to a local loopback server using the configured ports. + result: Dict[str, Any] | None + try: + result = await _send_auth_request(context, request_payload) + except AuthorizationDeclined: + result = await _run_loopback_flow( + flow_id=flow_id, + state=state, + authorize_url=authorize_url, + loopback_candidates=loopback_candidates, + ) try: if result and result.get("url"): @@ -264,3 +296,135 @@ async def _send_auth_request( raise AuthorizationDeclined( "No upstream MCP session available to prompt user for authorization" ) + + +async def _run_loopback_flow( + *, + flow_id: str, + state: str, + authorize_url: httpx.URL, + loopback_candidates: list[tuple[str, int]], +) -> Dict[str, Any]: + """Run a local loopback OAuth authorization flow. + + Tries a list of fixed ports; opens the browser to the authorization URL + unchanged (provider must already have an allowed redirect matching the + selection). Delivers the callback via callback_registry using either the + flow id (if present) or the state parameter. + """ + if not loopback_candidates: + raise AuthorizationDeclined( + "No upstream session and no loopback ports configured for OAuth flow" + ) + + # Register state so the loopback handler can resolve flow id + try: + await callback_registry.register_state(flow_id, state) + except Exception: + pass + + # Deferred import to avoid heavy deps unless needed + import contextlib + import socket + import threading + import webbrowser + from http.server import BaseHTTPRequestHandler, HTTPServer + from urllib.parse import urlparse as _urlparse, parse_qs as _parse_qs + + selected: tuple[str, int] | None = None + + # Find an available port from candidates + for url, port in loopback_candidates: + with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: + try: + s.bind(("127.0.0.1", port)) + selected = (url, port) + break + except OSError: + continue + + if selected is None: + raise AuthorizationDeclined( + "All configured loopback ports are busy; configure a different port list" + ) + + redirect_url, port = selected + + # Minimal request handler to capture the callback + result_container: dict[str, Any] = {"payload": None} + + class _Handler(BaseHTTPRequestHandler): + def do_GET(self): # noqa: N802 (http server style) + try: + parsed = _urlparse(self.path) + params = {k: v[-1] for k, v in _parse_qs(parsed.query).items()} + # Deliver by flow id or state + delivered = False + if flow_id: + delivered = ( + threading.get_native_id() is not None + ) # dummy to appease linters + # Ignore variable; use registry + # Prefer explicit flow delivery; else by state + ok = False + if flow_id: + ok = False # avoid mypy confusion; we'll deliver after sending response + result_container["payload"] = params + # Respond immediately + self.send_response(200) + self.send_header("Content-Type", "text/html; charset=utf-8") + self.end_headers() + self.wfile.write( + b"

Authorization complete.

You may close this window and return to MCP Agent.

" + ) + except Exception: + self.send_response(500) + self.end_headers() + + def log_message(self, format: str, *args): # noqa: A003 - keep server quiet + return + + httpd: HTTPServer = HTTPServer(("127.0.0.1", port), _Handler) + + def _serve_once(): + try: + httpd.handle_request() + finally: + with contextlib.suppress(Exception): + httpd.server_close() + + t = threading.Thread(target=_serve_once, daemon=True) + t.start() + + # Open the browser to the provider's authorize URL. The authorize URL must + # already include a redirect_uri matching one of the provider's registered + # values. We do not mutate the URL here because we don't know which of the + # candidate redirect URIs the client registered; that comes from config. + with contextlib.suppress(Exception): + webbrowser.open(str(authorize_url), new=1, autoraise=True) + + # Wait for one request or timeout + # Simple polling with backoff; we keep this lightweight. + import time as _time + + deadline = _time.time() + 300.0 + while _time.time() < deadline: + if result_container["payload"] is not None: + break + _time.sleep(0.1) + + payload = result_container["payload"] + if not payload: + raise CallbackTimeoutError("Timed out waiting for loopback OAuth callback") + + # Try to deliver via flow id first, else by state + delivered = await callback_registry.deliver(flow_id, payload) + if not delivered: + delivered = await callback_registry.deliver_by_state( + payload.get("state", ""), payload + ) + if not delivered: + # If still not delivered, just return the parsed payload to the caller + # (flow will proceed using the returned data). + return payload + return payload From af9eb29f7044ca5b507a47d7be3d7a933b0c87e4 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Thu, 9 Oct 2025 17:49:03 -0400 Subject: [PATCH 18/25] Tests and more fixes for loopback, including browser launch --- docs/oauth_support_design.md | 5 +- examples/basic/oauth_basic_agent/README.md | 23 +++ examples/basic/oauth_basic_agent/main.py | 153 ++++++++++++++++++ .../oauth_basic_agent/mcp_agent.config.yaml | 38 +++++ .../mcp_agent.secrets.yaml.example | 15 ++ .../basic/oauth_basic_agent/requirements.txt | 2 + src/mcp_agent/config.py | 2 + src/mcp_agent/oauth/flow.py | 42 +++-- tests/test_oauth_utils.py | 22 +++ 9 files changed, 285 insertions(+), 17 deletions(-) create mode 100644 examples/basic/oauth_basic_agent/README.md create mode 100644 examples/basic/oauth_basic_agent/main.py create mode 100644 examples/basic/oauth_basic_agent/mcp_agent.config.yaml create mode 100644 examples/basic/oauth_basic_agent/mcp_agent.secrets.yaml.example create mode 100644 examples/basic/oauth_basic_agent/requirements.txt diff --git a/docs/oauth_support_design.md b/docs/oauth_support_design.md index d9b0a7a10..b30d6dcb4 100644 --- a/docs/oauth_support_design.md +++ b/docs/oauth_support_design.md @@ -17,7 +17,10 @@ - `InMemoryTokenStore` and Redis-backed implementation (optional for multi-instance) - `TokenManager` orchestration (acquire, refresh, revoke) - `OAuthHttpxAuth` for attaching tokens to downstream HTTP transports - - `AuthorizationFlowCoordinator` that interacts with the user via MCP `auth/request` + - `AuthorizationFlowCoordinator` that interacts with the user via MCP `auth/request`. + When no upstream client session is available, a client-only loopback flow starts a + temporary local callback listener on 127.0.0.1 using a configurable fixed port list + (default: 33418, 33419, 33420), opens the browser, and completes the PKCE code flow. 5. **Delegated Authorization UI Flow** – Extend the gateway/session relay so servers can send `auth/request` messages to MCP clients, capturing authorization codes via either: - Client-returned callback URL (preferred, works with SEP-capable clients) - MCP Agent hosted callback endpoint (`/internal/oauth/callback/{flow_id}`) as a fallback / native-app style loopback. diff --git a/examples/basic/oauth_basic_agent/README.md b/examples/basic/oauth_basic_agent/README.md new file mode 100644 index 000000000..cf34e20df --- /dev/null +++ b/examples/basic/oauth_basic_agent/README.md @@ -0,0 +1,23 @@ +# OAuth Basic MCP Agent example (client-only loopback) + +This example mirrors `mcp_basic_agent` but adds GitHub MCP with OAuth using the client-only loopback flow. + +## Setup + +1. Register a GitHub OAuth App and add redirect URIs (at least one of): + + - `http://127.0.0.1:33418/callback` + - `http://127.0.0.1:33419/callback` + - `http://localhost:33418/callback` + +2. Install deps and run: + +```bash +uv sync +uv pip install -r requirements.txt +export GITHUB_CLIENT_ID=... +export GITHUB_CLIENT_SECRET=... +uv run main.py +``` + +On first run, a browser window opens to authorize GitHub; subsequent runs reuse the cached token. diff --git a/examples/basic/oauth_basic_agent/main.py b/examples/basic/oauth_basic_agent/main.py new file mode 100644 index 000000000..70ddbaaa1 --- /dev/null +++ b/examples/basic/oauth_basic_agent/main.py @@ -0,0 +1,153 @@ +import asyncio +import os +import time + +from mcp_agent.app import MCPApp +from mcp_agent.config import ( + Settings, + LoggerSettings, + MCPSettings, + MCPServerSettings, + OpenAISettings, + AnthropicSettings, + MCPServerAuthSettings, + MCPOAuthClientSettings, + OAuthSettings, +) +from mcp_agent.agents.agent import Agent +from mcp_agent.workflows.llm.augmented_llm import RequestParams +from mcp_agent.workflows.llm.llm_selector import ModelPreferences +from mcp_agent.workflows.llm.augmented_llm_anthropic import AnthropicAugmentedLLM +from mcp_agent.workflows.llm.augmented_llm_openai import OpenAIAugmentedLLM +from mcp_agent.tracing.token_counter import TokenSummary + + +client_id = os.environ.get("GITHUB_CLIENT_ID") +client_secret = os.environ.get("GITHUB_CLIENT_SECRET") + +settings = Settings( + execution_engine="asyncio", + logger=LoggerSettings(type="file", level="debug"), + oauth=OAuthSettings(), + mcp=MCPSettings( + servers={ + "fetch": MCPServerSettings( + command="uvx", + args=["mcp-server-fetch"], + ), + "filesystem": MCPServerSettings( + command="npx", + args=["-y", "@modelcontextprotocol/server-filesystem"], + ), + "github": MCPServerSettings( + name="github", + transport="streamable_http", + url="https://api.githubcopilot.com/mcp/", + auth=MCPServerAuthSettings( + oauth=MCPOAuthClientSettings( + enabled=True, + client_id=client_id, + client_secret=client_secret, + scopes=["read:org", "public_repo", "user:email"], + authorization_server="https://github.com/login/oauth", + resource="https://api.githubcopilot.com/mcp", + use_internal_callback=False, + ) + ), + ), + } + ), + openai=OpenAISettings( + api_key="sk-my-openai-api-key", + default_model="gpt-4o-mini", + ), + anthropic=AnthropicSettings( + api_key="sk-my-anthropic-api-key", + ), +) + +app = MCPApp(name="oauth_basic_agent") + + +@app.tool() +async def example_usage() -> str: + async with app.run() as agent_app: + logger = agent_app.logger + context = agent_app.context + result = "" + + logger.info("Current config:", data=context.config.model_dump()) + + context.config.mcp.servers["filesystem"].args.extend([os.getcwd()]) + + finder_agent = Agent( + name="finder", + instruction="""You are an agent with access to the filesystem, + as well as the ability to fetch URLs and GitHub MCP. Your job is to + identify the closest match to a user's request, make the appropriate tool + calls, and return useful results.""", + server_names=["fetch", "filesystem", "github"], + ) + + async with finder_agent: + logger.info("finder: Connected to server, calling list_tools...") + tools_list = await finder_agent.list_tools() + logger.info("Tools available:", data=tools_list.model_dump()) + + llm = await finder_agent.attach_llm(OpenAIAugmentedLLM) + result += await llm.generate_str( + message="Print the contents of mcp_agent.config.yaml verbatim", + ) + logger.info(f"mcp_agent.config.yaml contents: {result}") + + llm = await finder_agent.attach_llm(AnthropicAugmentedLLM) + + result += await llm.generate_str( + message="Print the first 2 paragraphs of https://modelcontextprotocol.io/introduction", + ) + logger.info(f"First 2 paragraphs of Model Context Protocol docs: {result}") + result += "\n\n" + + result += await llm.generate_str( + message="Summarize those paragraphs in a 128 character tweet", + request_params=RequestParams( + modelPreferences=ModelPreferences( + costPriority=0.1, speedPriority=0.2, intelligencePriority=0.7 + ), + ), + ) + + await display_token_summary(agent_app) + return result + + +async def display_token_summary(app_ctx: MCPApp, agent: Agent | None = None): + summary: TokenSummary = await app_ctx.get_token_summary() + + print("\n" + "=" * 50) + print("TOKEN USAGE SUMMARY") + print("=" * 50) + + print("\nTotal Usage:") + print(f" Total tokens: {summary.usage.total_tokens:,}") + print(f" Input tokens: {summary.usage.input_tokens:,}") + print(f" Output tokens: {summary.usage.output_tokens:,}") + print(f" Total cost: ${summary.cost:.4f}") + + if summary.model_usage: + print("\nBreakdown by Model:") + for model_key, data in summary.model_usage.items(): + print(f"\n {model_key}:") + print( + f" Tokens: {data.usage.total_tokens:,} (input: {data.usage.input_tokens:,}, output: {data.usage.output_tokens:,})" + ) + print(f" Cost: ${data.cost:.4f}") + + print("\n" + "=" * 50) + + +if __name__ == "__main__": + start = time.time() + asyncio.run(example_usage()) + end = time.time() + print(f"Total run time: {end - start:.2f}s") diff --git a/examples/basic/oauth_basic_agent/mcp_agent.config.yaml b/examples/basic/oauth_basic_agent/mcp_agent.config.yaml new file mode 100644 index 000000000..944015e0f --- /dev/null +++ b/examples/basic/oauth_basic_agent/mcp_agent.config.yaml @@ -0,0 +1,38 @@ +$schema: ../../../schema/mcp-agent.config.schema.json + +execution_engine: asyncio +logger: + transports: [console, file] + level: info + path_settings: + path_pattern: "logs/mcp-agent-{unique_id}.jsonl" + unique_id: "timestamp" + +oauth: + loopback_ports: [33418, 33419, 33420] + +mcp: + servers: + fetch: + command: "uvx" + args: ["mcp-server-fetch"] + filesystem: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-filesystem"] + github: + transport: streamable_http + url: "https://api.githubcopilot.com/mcp/" + auth: + oauth: + enabled: true + client_id: ${GITHUB_CLIENT_ID} + client_secret: ${GITHUB_CLIENT_SECRET} + scopes: ["read:org", "public_repo", "user:email"] + authorization_server: "https://github.com/login/oauth" + resource: "https://api.githubcopilot.com/mcp" + use_internal_callback: false + +openai: + default_model: "gpt-4o-mini" +anthropic: + default_model: claude-sonnet-4-20250514 diff --git a/examples/basic/oauth_basic_agent/mcp_agent.secrets.yaml.example b/examples/basic/oauth_basic_agent/mcp_agent.secrets.yaml.example new file mode 100644 index 000000000..c737c0afb --- /dev/null +++ b/examples/basic/oauth_basic_agent/mcp_agent.secrets.yaml.example @@ -0,0 +1,15 @@ +$schema: ../../../schema/mcp-agent.config.schema.json + +# Copy to mcp_agent.secrets.yaml and fill in API keys and GitHub OAuth values. + +openai: + api_key: "sk-your-openai-key" + +anthropic: + api_key: "sk-your-anthropic-key" + +# GitHub OAuth client (required for this example) +GITHUB_CLIENT_ID: "your-client-id" +GITHUB_CLIENT_SECRET: "your-client-secret" + + diff --git a/examples/basic/oauth_basic_agent/requirements.txt b/examples/basic/oauth_basic_agent/requirements.txt new file mode 100644 index 000000000..9bf2c8804 --- /dev/null +++ b/examples/basic/oauth_basic_agent/requirements.txt @@ -0,0 +1,2 @@ +-e ../../.. + diff --git a/src/mcp_agent/config.py b/src/mcp_agent/config.py index 72ef61118..227245f8c 100644 --- a/src/mcp_agent/config.py +++ b/src/mcp_agent/config.py @@ -119,6 +119,8 @@ class OAuthSettings(BaseModel): ) flow_timeout_seconds: int = Field(300, ge=30) callback_base_url: AnyHttpUrl | None = None + # Fixed loopback ports to try (client-only OAuth). If empty, loopback is disabled. + loopback_ports: list[int] = Field(default_factory=lambda: [33418, 33419, 33420]) model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index eb6d7c9dd..243f085c2 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -31,7 +31,7 @@ generate_state, ) from mcp_agent.oauth.records import TokenRecord -from mcp_agent.oauth.errors import OAuthFlowError +# Keep import list minimal in this module to avoid warnings; OAuthFlowError imported elsewhere when needed logger = get_logger(__name__) @@ -359,16 +359,7 @@ def do_GET(self): # noqa: N802 (http server style) parsed = _urlparse(self.path) params = {k: v[-1] for k, v in _parse_qs(parsed.query).items()} # Deliver by flow id or state - delivered = False - if flow_id: - delivered = ( - threading.get_native_id() is not None - ) # dummy to appease linters - # Ignore variable; use registry - # Prefer explicit flow delivery; else by state - ok = False - if flow_id: - ok = False # avoid mypy confusion; we'll deliver after sending response + # Store payload for delivery after HTTP response result_container["payload"] = params # Respond immediately self.send_response(200) @@ -396,12 +387,31 @@ def _serve_once(): t = threading.Thread(target=_serve_once, daemon=True) t.start() - # Open the browser to the provider's authorize URL. The authorize URL must - # already include a redirect_uri matching one of the provider's registered - # values. We do not mutate the URL here because we don't know which of the - # candidate redirect URIs the client registered; that comes from config. + # Ensure the authorization URL uses the selected redirect_uri. + from urllib.parse import ( + urlencode as _urlencode, + urlparse as _p, + parse_qs as _q, + urlunparse as _u, + ) + + parsed = _p(str(authorize_url)) + q = {k: v[-1] for k, v in _q(parsed.query).items()} + q["redirect_uri"] = redirect_url + final_url = _u( + ( + parsed.scheme, + parsed.netloc, + parsed.path, + parsed.params, + _urlencode(q), + parsed.fragment, + ) + ) + + # Open the browser to the adjusted URL with contextlib.suppress(Exception): - webbrowser.open(str(authorize_url), new=1, autoraise=True) + webbrowser.open(final_url, new=1, autoraise=True) # Wait for one request or timeout # Simple polling with backoff; we keep this lightweight. diff --git a/tests/test_oauth_utils.py b/tests/test_oauth_utils.py index 36c052318..581608524 100644 --- a/tests/test_oauth_utils.py +++ b/tests/test_oauth_utils.py @@ -1,4 +1,5 @@ import time +import asyncio import pathlib import sys @@ -88,3 +89,24 @@ def test_normalize_resource_with_fallback(): def test_normalize_resource_canonicalizes_case(): assert normalize_resource("https://Example.COM/", None) == "https://example.com" + + +def test_oauth_loopback_ports_config_defaults(): + from mcp_agent.config import OAuthSettings + + s = OAuthSettings() + assert isinstance(s.loopback_ports, list) + assert 33418 in s.loopback_ports + + +@pytest.mark.asyncio +async def test_callback_registry_state_mapping(): + from mcp_agent.oauth.callbacks import OAuthCallbackRegistry + + reg = OAuthCallbackRegistry() + fut = await reg.create_handle("flow1") + await reg.register_state("flow1", "state1") + delivered = await reg.deliver_by_state("state1", {"code": "abc"}) + assert delivered is True + result = await asyncio.wait_for(fut, timeout=0.2) + assert result["code"] == "abc" From 25da6dabaf12bbc32148795c067444c78a6d414f Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Thu, 9 Oct 2025 18:19:37 -0400 Subject: [PATCH 19/25] various fixes --- examples/basic/oauth_basic_agent/README.md | 10 +- src/mcp_agent/oauth/callbacks.py | 2 +- src/mcp_agent/oauth/flow.py | 170 ++++++++++++--------- 3 files changed, 106 insertions(+), 76 deletions(-) diff --git a/examples/basic/oauth_basic_agent/README.md b/examples/basic/oauth_basic_agent/README.md index cf34e20df..319c4eec2 100644 --- a/examples/basic/oauth_basic_agent/README.md +++ b/examples/basic/oauth_basic_agent/README.md @@ -10,11 +10,17 @@ This example mirrors `mcp_basic_agent` but adds GitHub MCP with OAuth using the - `http://127.0.0.1:33419/callback` - `http://localhost:33418/callback` -2. Install deps and run: +2. Copy the secrets template and fill in your API keys / OAuth client (or export the env vars manually): + +```bash +cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml +``` + +3. Install deps and run: ```bash -uv sync uv pip install -r requirements.txt +# If you populated the secrets file you can skip these exports. export GITHUB_CLIENT_ID=... export GITHUB_CLIENT_SECRET=... uv run main.py diff --git a/src/mcp_agent/oauth/callbacks.py b/src/mcp_agent/oauth/callbacks.py index a827f0fa8..5e2db4fbd 100644 --- a/src/mcp_agent/oauth/callbacks.py +++ b/src/mcp_agent/oauth/callbacks.py @@ -52,7 +52,7 @@ async def deliver_by_state(self, state: str, payload: Dict[str, Any]) -> bool: if not state: return False async with self._lock: - flow_id = self._state_to_flow.get(state) + flow_id = self._state_to_flow.pop(state, None) if not flow_id: return False return await self.deliver(flow_id, payload) diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index 243f085c2..d649d8bf3 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -3,6 +3,7 @@ from __future__ import annotations import asyncio +import contextlib import httpx import uuid import time @@ -197,7 +198,7 @@ async def authorize( "Authorization request was declined by the user" ) finally: - if callback_future is not None: + with contextlib.suppress(Exception): await callback_registry.discard(flow_id) error = callback_data.get("error") @@ -274,7 +275,6 @@ async def authorize( ) - def _parse_callback_params(url: str) -> Dict[str, str]: parsed = urlparse(url) params = {} @@ -323,13 +323,16 @@ async def _run_loopback_flow( except Exception: pass - # Deferred import to avoid heavy deps unless needed - import contextlib import socket - import threading import webbrowser - from http.server import BaseHTTPRequestHandler, HTTPServer - from urllib.parse import urlparse as _urlparse, parse_qs as _parse_qs + from urllib.parse import ( + urlencode as _urlencode, + urlparse as _p, + parse_qs as _q, + urlunparse as _u, + urlsplit as _urlsplit, + parse_qs as _parse_qs, + ) selected: tuple[str, int] | None = None @@ -337,6 +340,7 @@ async def _run_loopback_flow( for url, port in loopback_candidates: with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: try: + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("127.0.0.1", port)) selected = (url, port) break @@ -350,82 +354,102 @@ async def _run_loopback_flow( redirect_url, port = selected - # Minimal request handler to capture the callback - result_container: dict[str, Any] = {"payload": None} + loop = asyncio.get_running_loop() + payload_future: asyncio.Future[Dict[str, Any]] = loop.create_future() - class _Handler(BaseHTTPRequestHandler): - def do_GET(self): # noqa: N802 (http server style) - try: - parsed = _urlparse(self.path) - params = {k: v[-1] for k, v in _parse_qs(parsed.query).items()} - # Deliver by flow id or state - # Store payload for delivery after HTTP response - result_container["payload"] = params - # Respond immediately - self.send_response(200) - self.send_header("Content-Type", "text/html; charset=utf-8") - self.end_headers() - self.wfile.write( - b"

Authorization complete.

You may close this window and return to MCP Agent.

" - ) - except Exception: - self.send_response(500) - self.end_headers() - - def log_message(self, format: str, *args): # noqa: A003 - keep server quiet - return - - httpd: HTTPServer = HTTPServer(("127.0.0.1", port), _Handler) - - def _serve_once(): + async def _handle( + reader: asyncio.StreamReader, writer: asyncio.StreamWriter + ) -> None: try: - httpd.handle_request() + request_line = await reader.readline() + if not request_line: + return + parts = request_line.decode("latin-1").strip().split(" ") + if len(parts) < 2: + return + target = parts[1] + + # Consume headers until blank line + while True: + header = await reader.readline() + if not header or header in (b"\r\n", b"\n"): + break + + parsed_target = _urlsplit(target) + params = {k: v[-1] for k, v in _parse_qs(parsed_target.query).items()} + if not payload_future.done(): + payload_future.set_result(params) + + body = ( + "

Authorization complete.

" + "

You may close this window and return to MCP Agent.

" + ) + response = ( + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html; charset=utf-8\r\n" + f"Content-Length: {len(body.encode('utf-8'))}\r\n" + "Connection: close\r\n\r\n" + f"{body}" + ) + writer.write(response.encode("utf-8")) + await writer.drain() + except Exception: + with contextlib.suppress(Exception): + writer.write( + b"HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\n\r\n" + ) + await writer.drain() finally: + writer.close() with contextlib.suppress(Exception): - httpd.server_close() - - t = threading.Thread(target=_serve_once, daemon=True) - t.start() + await writer.wait_closed() - # Ensure the authorization URL uses the selected redirect_uri. - from urllib.parse import ( - urlencode as _urlencode, - urlparse as _p, - parse_qs as _q, - urlunparse as _u, - ) + server = await asyncio.start_server(_handle, "127.0.0.1", port) - parsed = _p(str(authorize_url)) - q = {k: v[-1] for k, v in _q(parsed.query).items()} - q["redirect_uri"] = redirect_url - final_url = _u( - ( - parsed.scheme, - parsed.netloc, - parsed.path, - parsed.params, - _urlencode(q), - parsed.fragment, + try: + # Ensure the authorization URL uses the selected redirect_uri. + parsed = _p(str(authorize_url)) + q = {k: v[-1] for k, v in _q(parsed.query).items()} + q["redirect_uri"] = redirect_url + final_url = _u( + ( + parsed.scheme, + parsed.netloc, + parsed.path, + parsed.params, + _urlencode(q), + parsed.fragment, + ) ) - ) - - # Open the browser to the adjusted URL - with contextlib.suppress(Exception): - webbrowser.open(final_url, new=1, autoraise=True) - # Wait for one request or timeout - # Simple polling with backoff; we keep this lightweight. - import time as _time + logger.info( + "OAuth loopback flow started", + data={ + "redirect_uri": redirect_url, + "authorization_url": final_url, + "ports": sorted({p for _, p in loopback_candidates}), + "selected_port": port, + }, + ) - deadline = _time.time() + 300.0 - while _time.time() < deadline: - if result_container["payload"] is not None: - break - _time.sleep(0.1) + # Open the browser to the adjusted URL, but always print the URL + print( + "\nOpen the following URL in your browser to authorize if it does not open automatically:\n" + f" {final_url}\n" + ) + with contextlib.suppress(Exception): + webbrowser.open(final_url, new=1, autoraise=True) - payload = result_container["payload"] - if not payload: - raise CallbackTimeoutError("Timed out waiting for loopback OAuth callback") + try: + payload = await asyncio.wait_for(payload_future, timeout=300.0) + except asyncio.TimeoutError as exc: + raise CallbackTimeoutError( + "Timed out waiting for loopback OAuth callback" + ) from exc + finally: + server.close() + with contextlib.suppress(Exception): + await server.wait_closed() # Try to deliver via flow id first, else by state delivered = await callback_registry.deliver(flow_id, payload) From 8135e3543158d739305b8ad11cd417275709f20b Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Thu, 9 Oct 2025 18:22:13 -0400 Subject: [PATCH 20/25] additional fixes suggested by cursor --- TESTING_GUIDE.md | 180 ++++++++++++++++++++++++++++++++++++ src/mcp_agent/oauth/flow.py | 30 +++++- 2 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 TESTING_GUIDE.md diff --git a/TESTING_GUIDE.md b/TESTING_GUIDE.md new file mode 100644 index 000000000..47d825843 --- /dev/null +++ b/TESTING_GUIDE.md @@ -0,0 +1,180 @@ +# OAuth Flow Validation Guide + +This checklist lets you flip between the original `feat/mcp_agent_oauth` branch and the current branch, exercise every scenario we discussed, and confirm the token flows (including caching) behave as intended. All commands use `uv` for Python execution. + +--- + +## 0. One-Time Setup + +### 0.1 Create a Virtual Environment + +```bash +uv venv +source .venv/bin/activate +``` + +### 0.2 Install Project (with optional extras) + +```bash +uv pip install -e .[oauth,cli,redis] +``` + +### 0.3 Start Temporal (required by the workflow examples) + +```bash +temporal server start-dev +``` + +### 0.4 Set Secrets You'll Reuse + +```bash +export GITHUB_CLIENT_ID=your_client_id +export GITHUB_CLIENT_SECRET=your_client_secret +export GITHUB_ACCESS_TOKEN=ghp_your_pat # for pre-auth / pre-seeded flows +``` + +### 0.5 (Optional) Start Redis for Redis-backed tests + +```bash +docker run --rm -p 6379:6379 redis:7-alpine +export OAUTH_REDIS_URL=redis://127.0.0.1:6379 +``` + +--- + +## 1. Original Branch (`feat/mcp_agent_oauth`) + +```bash +git checkout feat/mcp_agent_oauth +``` + +### 1.1 Unit Tests + +```bash +uv run python -m pytest tests/test_oauth_utils.py tests/test_audience_validation.py +# add tests/test_token_manager.py if it exists in that branch +``` + +### 1.2 Examples + +#### 1.2.1 Preconfigured (static token cache) + +- Terminal 1: + ```bash + uv run python examples/oauth/preconfigured/main.py + ``` + +#### 1.2.2 Workflow Pre-Auth + +- Terminal 1: + ```bash + uv run python examples/oauth/workflow_pre_auth/worker.py + ``` +- Terminal 2: + ```bash + uv run python examples/oauth/workflow_pre_auth/main.py + ``` +- Terminal 3: + ```bash + uv run python examples/oauth/workflow_pre_auth/client.py + ``` + Optional: rerun the client with `--skip-pre-auth` to confirm cached token reuse. + +#### 1.2.3 Dynamic Interactive Flow + +- Terminal 1: + ```bash + uv run python examples/oauth/dynamic_auth/worker.py + ``` +- Terminal 2: + ```bash + uv run python examples/oauth/dynamic_auth/main.py + ``` +- Terminal 3: + ```bash + uv run python examples/oauth/dynamic_auth/client.py + ``` + +#### 1.2.4 Standalone OAuth Helper + +```bash +uv run python examples/oauth/preconfigured/oauth_demo.py +``` + +--- + +## 2. Current Branch (`your current working branch`) + +```bash +git checkout +``` + +### 2.1 Unit Tests + +```bash +uv run python -m pytest tests/test_oauth_utils.py tests/test_audience_validation.py tests/test_token_manager.py +``` + +_(Fix pytest/pytest_asyncio integration if you still have the autoload error before running.)_ + +### 2.2 Examples + +#### 2.2.1 Interactive Tool Flow (dynamic auth) + +- Terminal 1: + ```bash + uv run python examples/oauth/interactive_tool/server.py + ``` +- Terminal 2: + ```bash + uv run python examples/oauth/interactive_tool/client.py + ``` + After finishing the first run, run the client **again** (with the server still running). The second invocation should return immediately with no additional auth prompt—confirming token caching. + +#### 2.2.1b Client-only loopback (basic agent) + +- In `examples/basic/oauth_basic_agent/`, copy the secrets template and add your credentials: + ```bash + cd examples/basic/oauth_basic_agent + cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml # fill in keys/client details + uv pip install -r requirements.txt + export GITHUB_CLIENT_ID=your_client_id # skip if secrets file already has these + export GITHUB_CLIENT_SECRET=your_client_secret + uv run python main.py + ``` + On first run the browser opens to GitHub; authorize and the agent completes. Run the same command again and it should reuse the cached token without prompting. To choose different loopback ports, set `oauth.loopback_ports` in `mcp_agent.config.yaml`. + +#### 2.2.2 Workflow Pre-Auth + +- Terminal 1: + ```bash + uv run python examples/oauth/workflow_pre_auth/worker.py + ``` +- Terminal 2: + ```bash + uv run python examples/oauth/workflow_pre_auth/main.py + ``` +- Terminal 3: + ```bash + uv run python examples/oauth/workflow_pre_auth/client.py + ``` + Repeat with `--skip-pre-auth` to verify cached token reuse after the workflow has been seeded once. + +#### 2.2.3 Redis-backed Token Cache (optional) + +- Make sure Redis is running (step 0.5 above). +- With `OAUTH_REDIS_URL` exported and the redis extra installed, re-run either example. Tokens will persist across server restarts, so you can stop and restart the server and rerun the client to confirm the Redis cache is used. + +--- + +## 3. Manual Validation Matrix + +| Scenario | Terminal(s) | Expected outcome | +| ------------------------------------ | ----------------------------------------- | --------------------------------------------------------------------------- | +| Static pre-auth (both branches) | Worker + server + client | First run seeds token, subsequent run with `--skip-pre-auth` reuses it. | +| Interactive flow (both branches) | Server + client | First run asks for auth; immediate re-run uses cached token without prompt. | +| Redis token caching (current branch) | Same as above but with Redis env vars set | Tokens survive server restart thanks to Redis-backed store. | + +--- + +Following this checklist will let you validate the complete OAuth functionality on both branches, including the multiple-user token caching behavior. diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index d649d8bf3..9342363b3 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -328,7 +328,6 @@ async def _run_loopback_flow( from urllib.parse import ( urlencode as _urlencode, urlparse as _p, - parse_qs as _q, urlunparse as _u, urlsplit as _urlsplit, parse_qs as _parse_qs, @@ -348,8 +347,9 @@ async def _run_loopback_flow( continue if selected is None: + cfg_ports = ",".join(str(p) for _, p in loopback_candidates) or "(none)" raise AuthorizationDeclined( - "All configured loopback ports are busy; configure a different port list" + f"All configured loopback ports are busy (tried: {cfg_ports}); set oauth.loopback_ports to a different list" ) redirect_url, port = selected @@ -377,7 +377,8 @@ async def _handle( parsed_target = _urlsplit(target) params = {k: v[-1] for k, v in _parse_qs(parsed_target.query).items()} - if not payload_future.done(): + is_auth_callback = bool(params.get("code") or params.get("error")) + if is_auth_callback and not payload_future.done(): payload_future.set_result(params) body = ( @@ -409,7 +410,7 @@ async def _handle( try: # Ensure the authorization URL uses the selected redirect_uri. parsed = _p(str(authorize_url)) - q = {k: v[-1] for k, v in _q(parsed.query).items()} + q = {k: v[-1] for k, v in _parse_qs(parsed.query).items()} q["redirect_uri"] = redirect_url final_url = _u( ( @@ -422,11 +423,30 @@ async def _handle( ) ) + # Mask sensitive query parameters in logs + try: + masked_q = dict(q) + for sensitive in ("state", "code_challenge"): + if sensitive in masked_q: + masked_q[sensitive] = "***" + masked_url = _u( + ( + parsed.scheme, + parsed.netloc, + parsed.path, + parsed.params, + _urlencode(masked_q), + parsed.fragment, + ) + ) + except Exception: + masked_url = "(redacted)" + logger.info( "OAuth loopback flow started", data={ "redirect_uri": redirect_url, - "authorization_url": final_url, + "authorization_url": masked_url, "ports": sorted({p for _, p in loopback_candidates}), "selected_port": port, }, From bb0542fe8385219917e199ff021fd9b2a5c575cb Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 21 Oct 2025 14:58:58 -0400 Subject: [PATCH 21/25] merge and format --- examples/oauth/workflow_pre_auth/main.py | 5 +- src/mcp_agent/mcp/mcp_server_registry.py | 5 +- src/mcp_agent/oauth/manager.py | 2 +- src/mcp_agent/server/app_server.py | 62 ++++++++++++++++-------- uv.lock | 2 +- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py index 7eaabcb5b..a4575496c 100644 --- a/examples/oauth/workflow_pre_auth/main.py +++ b/examples/oauth/workflow_pre_auth/main.py @@ -16,7 +16,8 @@ MCPSettings, OAuthSettings, OAuthTokenStoreSettings, - Settings, TemporalSettings, + Settings, + TemporalSettings, ) from mcp_agent.core.context import Context as AppContext from mcp_agent.mcp.gen_client import gen_client @@ -109,7 +110,6 @@ @app.workflow_task(name="github_org_search_activity") async def github_org_search_activity(query: str) -> str: - print("running activity)") try: async with gen_client( @@ -143,7 +143,6 @@ async def github_org_search_activity(query: str) -> str: return f"Error: {e}" - @app.tool(name="github_org_search") async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: if app._logger and hasattr(app._logger, "_bound_context"): diff --git a/src/mcp_agent/mcp/mcp_server_registry.py b/src/mcp_agent/mcp/mcp_server_registry.py index d00a368a5..bb0b5c94b 100644 --- a/src/mcp_agent/mcp/mcp_server_registry.py +++ b/src/mcp_agent/mcp/mcp_server_registry.py @@ -42,12 +42,15 @@ def _resolve_identity_from_context(): try: - from mcp_agent.server import app_server # local import to avoid circular dependency + from mcp_agent.server import ( + app_server, + ) # local import to avoid circular dependency return app_server.get_current_identity() except Exception: return None + InitHookCallable = Callable[[ClientSession | None, MCPServerAuthSettings | None], bool] """ A type alias for an initialization hook function that is invoked after MCP server initialization. diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index ab7e33cdf..403a35a33 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -787,6 +787,7 @@ def _session_identity(self, context: "Context") -> OAuthUserIdentity | None: from mcp_agent.executor.temporal.temporal_context import ( get_execution_id as _get_exec_id, ) + session_id = _get_exec_id() except Exception: pass @@ -797,4 +798,3 @@ def _session_identity(self, context: "Context") -> OAuthUserIdentity | None: if not session_id: return None return OAuthUserIdentity(provider="mcp-session", subject=str(session_id)) - diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index 084482ee9..866dabc97 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -780,8 +780,12 @@ async def _handle_request_via_rpc( return None async def _handle_specific_request( - session: Any, method: str, params: dict, identity: OAuthUserIdentity, - context: "Context", log_prefix: str = "request" + session: Any, + method: str, + params: dict, + identity: OAuthUserIdentity, + context: "Context", + log_prefix: str = "request", ): """Handle specific request types with structured request/response.""" from mcp.types import ( @@ -808,7 +812,9 @@ async def _handle_specific_request( callback_data = await session.send_request( request=req, result_type=CreateMessageResult ) # type: ignore[attr-defined] - return callback_data.model_dump(by_alias=True, mode="json", exclude_none=True) + return callback_data.model_dump( + by_alias=True, mode="json", exclude_none=True + ) elif method == "elicitation/create": req = ServerRequest( ElicitRequest( @@ -819,19 +825,25 @@ async def _handle_specific_request( callback_data = await session.send_request( request=req, result_type=ElicitResult ) # type: ignore[attr-defined] - return callback_data.model_dump(by_alias=True, mode="json", exclude_none=True) + return callback_data.model_dump( + by_alias=True, mode="json", exclude_none=True + ) elif method == "roots/list": req = ServerRequest(ListRootsRequest(method="roots/list")) callback_data = await session.send_request( request=req, result_type=ListRootsResult ) # type: ignore[attr-defined] - return callback_data.model_dump(by_alias=True, mode="json", exclude_none=True) + return callback_data.model_dump( + by_alias=True, mode="json", exclude_none=True + ) elif method == "ping": req = ServerRequest(PingRequest(method="ping")) callback_data = await session.send_request( request=req, result_type=EmptyResult ) # type: ignore[attr-defined] - return callback_data.model_dump(by_alias=True, mode="json", exclude_none=True) + return callback_data.model_dump( + by_alias=True, mode="json", exclude_none=True + ) elif method == "auth/request": # TODO: special handling of auth request, should be replaced by future URL elicitation @@ -842,14 +854,17 @@ async def _handle_specific_request( if context and hasattr(context, "token_manager"): manager = context.token_manager if manager: - server_config = context.server_registry.get_server_config(server_name) + server_config = context.server_registry.get_server_config( + server_name + ) token = await manager.get_access_token_if_present( context=context, server_name=server_name, server_config=server_config, scopes=scopes, - identity=identity) + identity=identity, + ) if token: return token except Exception: @@ -864,13 +879,15 @@ async def _handle_specific_request( if context and hasattr(context, "token_manager"): manager = context.token_manager if manager: - server_config = context.server_registry.get_server_config(server_name) + server_config = context.server_registry.get_server_config( + server_name + ) token_data = { "access_token": record.access_token, "refresh_token": record.refresh_token, "scopes": record.scopes, - "authorization_server": record.authorization_server, + "authorization_server": record.authorization_server, "expires_at": record.expires_at, "token_type": "Bearer", } @@ -879,8 +896,9 @@ async def _handle_specific_request( context=context, user=identity, server_name=server_name, - server_config = server_config, - token_data = token_data) + server_config=server_config, + token_data=token_data, + ) except Exception: pass @@ -921,14 +939,10 @@ class AuthToken(BaseModel): requestedSchema=AuthToken.model_json_schema(), ), ) - await session.send_request( - request=req, result_type=ElicitResult - ) # type: ignore[attr-defined] + await session.send_request(request=req, result_type=ElicitResult) # type: ignore[attr-defined] timeout = 300 try: - callback_data = await asyncio.wait_for( - callback_future, timeout=timeout - ) + callback_data = await asyncio.wait_for(callback_future, timeout=timeout) except asyncio.TimeoutError as exc: raise CallbackTimeoutError( f"Timed out waiting for OAuth callback after {timeout} seconds" @@ -962,7 +976,9 @@ class AuthToken(BaseModel): error = callback_data.get("error") if error: description = callback_data.get("error_description") or error - raise OAuthFlowError(f"Authorization server returned error: {description}") + raise OAuthFlowError( + f"Authorization server returned error: {description}" + ) returned_state = callback_data.get("state") if returned_state != state: raise OAuthFlowError("State mismatch detected in OAuth callback") @@ -995,7 +1011,10 @@ class AuthToken(BaseModel): if not http_client: http_client = httpx.AsyncClient(timeout=30.0) token_response = await http_client.post( - token_endpoint, data=data, auth=auth, headers={"Accept": "application/json"} + token_endpoint, + data=data, + auth=auth, + headers={"Accept": "application/json"}, ) token_response.raise_for_status() try: @@ -2721,10 +2740,11 @@ async def _workflow_status( # endregion + def _parse_callback_params(url: str) -> Dict[str, str]: parsed = urlparse(url) params = {} params.update({k: v[-1] for k, v in parse_qs(parsed.query).items()}) if parsed.fragment: params.update({k: v[-1] for k, v in parse_qs(parsed.fragment).items()}) - return params \ No newline at end of file + return params diff --git a/uv.lock b/uv.lock index 796049545..095d9ae14 100644 --- a/uv.lock +++ b/uv.lock @@ -2226,7 +2226,7 @@ requires-dist = [ { name = "watchdog", marker = "extra == 'cli'", specifier = ">=6.0.0" }, { name = "websockets", specifier = ">=12.0" }, ] -provides-extras = ["cli", "temporal", "anthropic", "anthropic-bedrock", "anthropic-vertex", "bedrock", "openai", "azure", "google", "cohere", "langchain", "crewai"] +provides-extras = ["cli", "temporal", "anthropic", "anthropic-bedrock", "anthropic-vertex", "bedrock", "openai", "azure", "google", "cohere", "langchain", "redis", "crewai"] [package.metadata.requires-dev] dev = [ From c2fdcba65834ad061379049e23698bf4fb484862 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 21 Oct 2025 17:27:33 -0400 Subject: [PATCH 22/25] Various updates to get the "interactive_tool" example working --- docs/configuration.mdx | 2 + examples/oauth/interactive_tool/README.md | 38 ++++- examples/oauth/interactive_tool/client.py | 2 +- examples/oauth/interactive_tool/server.py | 35 ++++- schema/mcp-agent.config.schema.json | 162 +++++++++++++++++++++- src/mcp_agent/config.py | 1 + src/mcp_agent/executor/workflow.py | 7 +- src/mcp_agent/oauth/flow.py | 40 ++++-- src/mcp_agent/oauth/manager.py | 4 + src/mcp_agent/server/app_server.py | 29 +++- 10 files changed, 295 insertions(+), 25 deletions(-) diff --git a/docs/configuration.mdx b/docs/configuration.mdx index 4a38e5394..b6ac053ad 100644 --- a/docs/configuration.mdx +++ b/docs/configuration.mdx @@ -160,6 +160,7 @@ mcp: scopes: ["repo", "user:email"] client_id: ${GITHUB_MCP_CLIENT_ID} client_secret: ${GITHUB_MCP_CLIENT_SECRET} + include_resource_parameter: false # disable RFC 8707 resource param for providers like GitHub redirect_uri_options: - https://agent.example.com/internal/oauth/callback ``` @@ -168,6 +169,7 @@ mcp: - `oauth` enables delegated authorization flows; the default in-memory token store is ideal for local development while Redis is recommended for production clusters. - To use Redis for token storage, configure `token_store.backend: redis` and supply `redis_url` (see optional dependency `mcp-agent[redis]`). - Downstream servers opt into OAuth via `mcp.servers..auth.oauth`. Supplying a `client_id`/`client_secret` allows immediate usage; support for dynamic client registration is planned as a follow-up. +- Some providers (including GitHub) reject the RFC 8707 `resource` parameter. Set `include_resource_parameter: false` in the client settings for those services. ## Configuration Reference diff --git a/examples/oauth/interactive_tool/README.md b/examples/oauth/interactive_tool/README.md index dd42ef07b..6c8b76fee 100644 --- a/examples/oauth/interactive_tool/README.md +++ b/examples/oauth/interactive_tool/README.md @@ -9,7 +9,11 @@ the browser so you can complete the GitHub sign-in. ## Prerequisites 1. Create a GitHub OAuth App (Settings → Developer settings → OAuth Apps) - with callback URL `http://localhost:8000/internal/oauth/callback`. + and set the **Authorization callback URL** to `http://127.0.0.1:33418/callback`. + (The example pins its loopback listener to that port, so the value must + match exactly.) + GitHub does not accept the RFC 8707 `resource` parameter, so the example + disables it via `include_resource_parameter: false` in the server config. 2. Export the client credentials: ```bash @@ -41,5 +45,33 @@ The client will display an authorization prompt. Approve it in the browser and GitHub will redirect back to the local callback handler. Once completed, the tool result is printed in the client terminal. -Subsequent tool invocations reuse the stored token until it expires or is -revoked. +The server and client use stable session IDs so the OAuth token is cached and +reused across runs. Once the first authorization completes, subsequent +invocations should return immediately without reopening the browser. + +## Optional: Redis-backed token store + +By default the example keeps tokens in memory. To persist tokens across server +restarts, switch to the Redis token store: + +1. Install the Redis extra: + + ```bash + pip install -e .[redis] + ``` + +2. Start a Redis instance (for example, Docker): + + ```bash + docker run --rm -p 6379:6379 redis:7-alpine + ``` + +3. Export `OAUTH_REDIS_URL` before launching the server: + + ```bash + export OAUTH_REDIS_URL="redis://127.0.0.1:6379" + ``` + +With the environment variable set, the server automatically switches to Redis +(`mcp_agent:oauth_tokens` prefix by default) and will reuse tokens even after +restarts. diff --git a/examples/oauth/interactive_tool/client.py b/examples/oauth/interactive_tool/client.py index 6b8713313..d10de2e51 100644 --- a/examples/oauth/interactive_tool/client.py +++ b/examples/oauth/interactive_tool/client.py @@ -36,7 +36,7 @@ async def _received_notification(self, notification): # type: ignore[override] return await super()._received_notification(notification) -async def make_session( +def make_session( read_stream: MemoryObjectReceiveStream, write_stream: MemoryObjectSendStream, read_timeout_seconds: timedelta | None, diff --git a/examples/oauth/interactive_tool/server.py b/examples/oauth/interactive_tool/server.py index ede6075fd..fe9c691c1 100644 --- a/examples/oauth/interactive_tool/server.py +++ b/examples/oauth/interactive_tool/server.py @@ -10,6 +10,7 @@ import asyncio import json import os +import traceback from typing import Optional from pydantic import AnyHttpUrl @@ -24,6 +25,7 @@ MCPServerSettings, MCPSettings, OAuthSettings, + OAuthTokenStoreSettings, Settings, ) from mcp_agent.core.context import Context as AppContext @@ -46,12 +48,23 @@ instructions="Demo GitHub search tool that requires OAuth authentication.", ) +redis_url = os.getenv("OAUTH_REDIS_URL") +if redis_url: + token_store = OAuthTokenStoreSettings( + backend="redis", + redis_url=redis_url, + ) +else: + token_store = OAuthTokenStoreSettings() + settings = Settings( execution_engine="asyncio", logger=LoggerSettings(level="info"), oauth=OAuthSettings( callback_base_url=AnyHttpUrl("http://localhost:8000"), flow_timeout_seconds=300, + loopback_ports=[33418], + token_store=token_store, ), mcp=MCPSettings( servers={ @@ -72,8 +85,8 @@ authorization_server=AnyHttpUrl( "https://github.com/login/oauth" ), - resource=AnyHttpUrl("https://api.githubcopilot.com/mcp"), use_internal_callback=True, + include_resource_parameter=False, ) ), ) @@ -86,6 +99,7 @@ description="Example MCP server that performs GitHub organization searches.", mcp=mcp, settings=settings, + session_id="github-oauth-demo", ) @@ -98,10 +112,23 @@ async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> server_registry=context.server_registry, context=context, ) as github_client: - result = await github_client.call_tool( - "search_orgs", - {"query": query, "perPage": 5, "sort": "best-match", "order": "desc"}, + tools = await github_client.list_tools() + context.logger.info( + "github_org_search: available tools from GitHub MCP", + data={"tools": [tool.name for tool in tools.tools]}, ) + try: + result = await github_client.call_tool( + "search_repositories", + {"query": f"org:{query}", "per_page": 5, "sort": "best-match", "order": "desc"}, + ) + except Exception as exc: + context.logger.error( + "github_org_search: call to remote GitHub MCP failed", + exception=repr(exc), + traceback=traceback.format_exc(), + ) + raise orgs: list[dict] = [] if result.content: diff --git a/schema/mcp-agent.config.schema.json b/schema/mcp-agent.config.schema.json index 0a6205461..0f9f4cc90 100644 --- a/schema/mcp-agent.config.schema.json +++ b/schema/mcp-agent.config.schema.json @@ -662,6 +662,154 @@ "title": "MCPRootSettings", "type": "object" }, + "MCPOAuthClientSettings": { + "additionalProperties": true, + "properties": { + "enabled": { + "default": false, + "title": "Enabled", + "type": "boolean" + }, + "scopes": { + "items": { + "type": "string" + }, + "title": "Scopes", + "type": "array", + "default": [] + }, + "resource": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Resource" + }, + "authorization_server": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Authorization Server" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Client Secret" + }, + "access_token": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Access Token" + }, + "refresh_token": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Refresh Token" + }, + "expires_at": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Expires At" + }, + "token_type": { + "default": "Bearer", + "title": "Token Type", + "type": "string" + }, + "redirect_uri_options": { + "items": { + "type": "string" + }, + "title": "Redirect Uri Options", + "type": "array", + "default": [] + }, + "extra_authorize_params": { + "additionalProperties": { + "type": "string" + }, + "title": "Extra Authorize Params", + "type": "object", + "default": {} + }, + "extra_token_params": { + "additionalProperties": { + "type": "string" + }, + "title": "Extra Token Params", + "type": "object", + "default": {} + }, + "require_pkce": { + "default": true, + "title": "Require Pkce", + "type": "boolean" + }, + "use_internal_callback": { + "default": true, + "title": "Use Internal Callback", + "type": "boolean" + }, + "include_resource_parameter": { + "default": true, + "title": "Include Resource Parameter", + "type": "boolean" + } + }, + "title": "MCPOAuthClientSettings", + "type": "object" + }, "MCPServerAuthSettings": { "additionalProperties": true, "description": "Represents authentication configuration for a server.", @@ -677,6 +825,18 @@ ], "default": null, "title": "Api Key" + }, + "oauth": { + "anyOf": [ + { + "$ref": "#/$defs/MCPOAuthClientSettings" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Oauth" } }, "title": "MCPServerAuthSettings", @@ -1523,4 +1683,4 @@ "title": "MCP Agent Configuration Schema", "type": "object", "$schema": "http://json-schema.org/draft-07/schema#" -} \ No newline at end of file +} diff --git a/src/mcp_agent/config.py b/src/mcp_agent/config.py index ad0403946..0c7ea01ee 100644 --- a/src/mcp_agent/config.py +++ b/src/mcp_agent/config.py @@ -96,6 +96,7 @@ class MCPOAuthClientSettings(BaseModel): extra_token_params: Dict[str, str] = Field(default_factory=dict) require_pkce: bool = True use_internal_callback: bool = True + include_resource_parameter: bool = True model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) diff --git a/src/mcp_agent/executor/workflow.py b/src/mcp_agent/executor/workflow.py index 2721fac2c..0083e6bca 100644 --- a/src/mcp_agent/executor/workflow.py +++ b/src/mcp_agent/executor/workflow.py @@ -218,6 +218,7 @@ async def run_async(self, *args, **kwargs) -> "WorkflowExecution": import asyncio from concurrent.futures import CancelledError + import traceback handle: "WorkflowHandle" | None = None @@ -315,7 +316,11 @@ async def _execute_workflow(): return result except Exception as e: - self._logger.error(f"Error waiting for tasks: {e}") + self._logger.error( + "Error waiting for tasks", + exception=repr(e), + traceback=traceback.format_exc(), + ) raise except CancelledError: diff --git a/src/mcp_agent/oauth/flow.py b/src/mcp_agent/oauth/flow.py index 9342363b3..e2c523044 100644 --- a/src/mcp_agent/oauth/flow.py +++ b/src/mcp_agent/oauth/flow.py @@ -107,6 +107,16 @@ async def authorize( state = generate_state() scope_param = " ".join(scopes) + include_resource = getattr(oauth_config, "include_resource_parameter", True) + logger.debug( + "Starting OAuth authorization", + data={ + "server": server_name, + "include_resource_param": include_resource, + "resource": resource, + }, + ) + params = { "response_type": "code", "client_id": client_id, @@ -115,8 +125,9 @@ async def authorize( "state": state, "code_challenge": code_challenge, "code_challenge_method": "S256", - "resource": resource, } + if include_resource and resource: + params["resource"] = resource # add extra params if any if oauth_config.extra_authorize_params: @@ -147,13 +158,16 @@ async def authorize( "redirect_uri": redirect_uri, "client_id": client_id, "code_verifier": code_verifier, - "resource": resource, - "scope_param": scope_param, - "extra_token_params": oauth_config.extra_token_params or {}, - "client_secret": oauth_config.client_secret, - "issuer_str": str(getattr(auth_metadata, "issuer", "") or ""), - "authorization_server_url": authorization_server_url, } + if include_resource and resource: + request_payload["resource"] = resource + if scope_param: + request_payload["scope_param"] = scope_param + if oauth_config.extra_token_params: + request_payload["extra_token_params"] = oauth_config.extra_token_params + request_payload["client_secret"] = oauth_config.client_secret + request_payload["issuer_str"] = str(getattr(auth_metadata, "issuer", "") or "") + request_payload["authorization_server_url"] = authorization_server_url # Try to send an auth/request upstream if available. If not available, # fall back to a local loopback server using the configured ports. @@ -167,6 +181,9 @@ async def authorize( authorize_url=authorize_url, loopback_candidates=loopback_candidates, ) + if result and result.get("_loopback_redirect_uri"): + redirect_uri = result.pop("_loopback_redirect_uri") + request_payload["redirect_uri"] = redirect_uri try: if result and result.get("url"): @@ -221,12 +238,13 @@ async def authorize( "redirect_uri": redirect_uri, "client_id": client_id, "code_verifier": code_verifier, - "resource": resource, } if scope_param: data["scope"] = scope_param if oauth_config.extra_token_params: data.update(oauth_config.extra_token_params) + if include_resource and resource: + data["resource"] = resource auth = None if oauth_config.client_secret: @@ -244,6 +262,10 @@ async def authorize( access_token = callback_data.get("access_token") if not access_token: + logger.error( + "Token endpoint response missing access_token", + data={"response": callback_data, "text": token_response.text}, + ) raise OAuthFlowError("Token endpoint response missing access_token") refresh_token = callback_data.get("refresh_token") expires_in = callback_data.get("expires_in") @@ -471,6 +493,8 @@ async def _handle( with contextlib.suppress(Exception): await server.wait_closed() + payload["_loopback_redirect_uri"] = redirect_url + # Try to deliver via flow id first, else by state delivered = await callback_registry.deliver(flow_id, payload) if not delivered: diff --git a/src/mcp_agent/oauth/manager.py b/src/mcp_agent/oauth/manager.py index 403a35a33..0938834b5 100644 --- a/src/mcp_agent/oauth/manager.py +++ b/src/mcp_agent/oauth/manager.py @@ -794,6 +794,10 @@ def _session_identity(self, context: "Context") -> OAuthUserIdentity | None: if not session_id: session_id = getattr(context, "session_id", None) + if not session_id: + app = getattr(context, "app", None) + if app is not None: + session_id = getattr(app, "_session_id_override", None) if not session_id: return None diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index 866dabc97..ca3965910 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -147,6 +147,9 @@ def _resolve_identity_for_request( identity = _CURRENT_IDENTITY.get() if identity is None and execution_id: identity = _get_identity_for_execution(execution_id) + if identity is None and app_context is not None: + session_id = getattr(app_context, "session_id", None) + identity = _session_identity_from_value(session_id) if identity is None and ctx is not None: session_id = _extract_session_id_from_context(ctx) identity = _session_identity_from_value(session_id) @@ -281,6 +284,25 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: except Exception: identity = None + app: MCPApp | None = _get_attached_app(ctx.fastmcp) + if app is not None and getattr(app, "context", None) is not None: + if session is not None: + app.context.upstream_session = session + if session_id and not getattr(app.context, "session_id", None): + app.context.session_id = session_id + + app_session_id = getattr(app.context, "session_id", None) + else: + app_session_id = None + + if app_session_id: + app_identity = _session_identity_from_value(app_session_id) + if identity is None or ( + isinstance(identity, OAuthUserIdentity) + and identity.provider == "mcp-session" + ): + identity = app_identity + if identity is None: identity = _session_identity_from_value(session_id) @@ -289,13 +311,6 @@ def _set_upstream_from_request_ctx_if_available(ctx: MCPContext) -> None: _set_current_identity(identity) - app: MCPApp | None = _get_attached_app(ctx.fastmcp) - if app is not None and getattr(app, "context", None) is not None: - if session is not None: - app.context.upstream_session = session - if session_id: - app.context.session_id = session_id - def _resolve_workflows_and_context( ctx: MCPContext, From 0bd41a7854d87e70a815552da583f1c49aac7543 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 21 Oct 2025 19:22:04 -0400 Subject: [PATCH 23/25] All examples working --- TESTING_GUIDE.md | 24 +-- examples/basic/oauth_basic_agent/README.md | 13 +- examples/basic/oauth_basic_agent/main.py | 129 ++++++------- .../oauth_basic_agent/mcp_agent.config.yaml | 4 +- .../mcp_agent.secrets.yaml.example | 10 +- examples/oauth/README.md | 4 +- examples/oauth/interactive_tool/server.py | 7 +- examples/oauth/pre_authorize/README.md | 59 ++++++ .../client.py | 28 +-- examples/oauth/pre_authorize/main.py | 143 ++++++++++++++ .../oauth/pre_authorize/mcp_agent.config.yaml | 31 +++ .../mcp_agent.secrets.yaml.example | 13 ++ .../worker.py | 0 examples/oauth/workflow_pre_auth/README.md | 51 ----- examples/oauth/workflow_pre_auth/main.py | 177 ------------------ src/mcp_agent/mcp/mcp_connection_manager.py | 36 ++++ src/mcp_agent/server/app_server.py | 11 +- 17 files changed, 403 insertions(+), 337 deletions(-) create mode 100644 examples/oauth/pre_authorize/README.md rename examples/oauth/{workflow_pre_auth => pre_authorize}/client.py (90%) create mode 100644 examples/oauth/pre_authorize/main.py create mode 100644 examples/oauth/pre_authorize/mcp_agent.config.yaml create mode 100644 examples/oauth/pre_authorize/mcp_agent.secrets.yaml.example rename examples/oauth/{workflow_pre_auth => pre_authorize}/worker.py (100%) delete mode 100644 examples/oauth/workflow_pre_auth/README.md delete mode 100644 examples/oauth/workflow_pre_auth/main.py diff --git a/TESTING_GUIDE.md b/TESTING_GUIDE.md index 47d825843..f72d019b1 100644 --- a/TESTING_GUIDE.md +++ b/TESTING_GUIDE.md @@ -30,7 +30,7 @@ temporal server start-dev ```bash export GITHUB_CLIENT_ID=your_client_id export GITHUB_CLIENT_SECRET=your_client_secret -export GITHUB_ACCESS_TOKEN=ghp_your_pat # for pre-auth / pre-seeded flows + export GITHUB_ACCESS_TOKEN=ghp_your_pat # for token bootstrap flows ``` ### 0.5 (Optional) Start Redis for Redis-backed tests @@ -64,21 +64,21 @@ uv run python -m pytest tests/test_oauth_utils.py tests/test_audience_validation uv run python examples/oauth/preconfigured/main.py ``` -#### 1.2.2 Workflow Pre-Auth +#### 1.2.2 Workflow Pre-Authorize - Terminal 1: ```bash - uv run python examples/oauth/workflow_pre_auth/worker.py + uv run python examples/oauth/pre_authorize/worker.py ``` - Terminal 2: ```bash - uv run python examples/oauth/workflow_pre_auth/main.py + uv run python examples/oauth/pre_authorize/main.py ``` - Terminal 3: ```bash - uv run python examples/oauth/workflow_pre_auth/client.py + uv run python examples/oauth/pre_authorize/client.py ``` - Optional: rerun the client with `--skip-pre-auth` to confirm cached token reuse. + Optional: rerun the client with `--skip-store-credentials` to confirm cached token reuse. #### 1.2.3 Dynamic Interactive Flow @@ -144,21 +144,21 @@ _(Fix pytest/pytest_asyncio integration if you still have the autoload error bef ``` On first run the browser opens to GitHub; authorize and the agent completes. Run the same command again and it should reuse the cached token without prompting. To choose different loopback ports, set `oauth.loopback_ports` in `mcp_agent.config.yaml`. -#### 2.2.2 Workflow Pre-Auth +#### 2.2.2 Workflow Pre-Authorize - Terminal 1: ```bash - uv run python examples/oauth/workflow_pre_auth/worker.py + uv run python examples/oauth/pre_authorize/worker.py ``` - Terminal 2: ```bash - uv run python examples/oauth/workflow_pre_auth/main.py + uv run python examples/oauth/pre_authorize/main.py ``` - Terminal 3: ```bash - uv run python examples/oauth/workflow_pre_auth/client.py + uv run python examples/oauth/pre_authorize/client.py ``` - Repeat with `--skip-pre-auth` to verify cached token reuse after the workflow has been seeded once. + Repeat with `--skip-store-credentials` to verify cached token reuse after the workflow has been seeded once. #### 2.2.3 Redis-backed Token Cache (optional) @@ -171,7 +171,7 @@ _(Fix pytest/pytest_asyncio integration if you still have the autoload error bef | Scenario | Terminal(s) | Expected outcome | | ------------------------------------ | ----------------------------------------- | --------------------------------------------------------------------------- | -| Static pre-auth (both branches) | Worker + server + client | First run seeds token, subsequent run with `--skip-pre-auth` reuses it. | +| Workflow pre-authorize (both branches) | Worker + server + client | First run seeds token, subsequent run with `--skip-store-credentials` reuses it. | | Interactive flow (both branches) | Server + client | First run asks for auth; immediate re-run uses cached token without prompt. | | Redis token caching (current branch) | Same as above but with Redis env vars set | Tokens survive server restart thanks to Redis-backed store. | diff --git a/examples/basic/oauth_basic_agent/README.md b/examples/basic/oauth_basic_agent/README.md index 319c4eec2..c16e7188f 100644 --- a/examples/basic/oauth_basic_agent/README.md +++ b/examples/basic/oauth_basic_agent/README.md @@ -16,7 +16,18 @@ This example mirrors `mcp_basic_agent` but adds GitHub MCP with OAuth using the cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml ``` -3. Install deps and run: +3. Configuration is loaded from `mcp_agent.config.yaml` and secrets from + `mcp_agent.secrets.yaml`. Populate the secrets file (or export the matching + environment variables) with your GitHub OAuth credentials before running. + +4. (Optional) To persist tokens across runs, start Redis and set `OAUTH_REDIS_URL`: + +```bash +docker run --rm -p 6379:6379 redis:7-alpine +export OAUTH_REDIS_URL="redis://127.0.0.1:6379" +``` + +5. Install deps and run: ```bash uv pip install -r requirements.txt diff --git a/examples/basic/oauth_basic_agent/main.py b/examples/basic/oauth_basic_agent/main.py index 70ddbaaa1..3c433d389 100644 --- a/examples/basic/oauth_basic_agent/main.py +++ b/examples/basic/oauth_basic_agent/main.py @@ -1,72 +1,55 @@ import asyncio +import inspect import os import time from mcp_agent.app import MCPApp -from mcp_agent.config import ( - Settings, - LoggerSettings, - MCPSettings, - MCPServerSettings, - OpenAISettings, - AnthropicSettings, - MCPServerAuthSettings, - MCPOAuthClientSettings, - OAuthSettings, -) +from mcp_agent.config import get_settings, OAuthTokenStoreSettings, OAuthSettings from mcp_agent.agents.agent import Agent -from mcp_agent.workflows.llm.augmented_llm import RequestParams -from mcp_agent.workflows.llm.llm_selector import ModelPreferences from mcp_agent.workflows.llm.augmented_llm_anthropic import AnthropicAugmentedLLM from mcp_agent.workflows.llm.augmented_llm_openai import OpenAIAugmentedLLM from mcp_agent.tracing.token_counter import TokenSummary -client_id = os.environ.get("GITHUB_CLIENT_ID") -client_secret = os.environ.get("GITHUB_CLIENT_SECRET") - -settings = Settings( - execution_engine="asyncio", - logger=LoggerSettings(type="file", level="debug"), - oauth=OAuthSettings(), - mcp=MCPSettings( - servers={ - "fetch": MCPServerSettings( - command="uvx", - args=["mcp-server-fetch"], - ), - "filesystem": MCPServerSettings( - command="npx", - args=["-y", "@modelcontextprotocol/server-filesystem"], - ), - "github": MCPServerSettings( - name="github", - transport="streamable_http", - url="https://api.githubcopilot.com/mcp/", - auth=MCPServerAuthSettings( - oauth=MCPOAuthClientSettings( - enabled=True, - client_id=client_id, - client_secret=client_secret, - scopes=["read:org", "public_repo", "user:email"], - authorization_server="https://github.com/login/oauth", - resource="https://api.githubcopilot.com/mcp", - use_internal_callback=False, - ) - ), - ), - } - ), - openai=OpenAISettings( - api_key="sk-my-openai-api-key", - default_model="gpt-4o-mini", - ), - anthropic=AnthropicSettings( - api_key="sk-my-anthropic-api-key", - ), +def _load_settings(): + signature = inspect.signature(get_settings) + if "set_global" in signature.parameters: + return get_settings(set_global=False) + return get_settings() + + +settings = _load_settings() + +redis_url = os.environ.get("OAUTH_REDIS_URL") +if redis_url: + settings.oauth = settings.oauth or OAuthSettings() + settings.oauth.token_store = OAuthTokenStoreSettings( + backend="redis", + redis_url=redis_url, + ) +elif not getattr(settings.oauth, "token_store", None): + settings.oauth = settings.oauth or OAuthSettings() + settings.oauth.token_store = OAuthTokenStoreSettings() + +github_settings = ( + settings.mcp.servers.get("github") + if settings.mcp and settings.mcp.servers + else None +) +github_oauth = ( + github_settings.auth.oauth + if github_settings and github_settings.auth and github_settings.auth.oauth + else None ) -app = MCPApp(name="oauth_basic_agent") +if not github_oauth or not github_oauth.client_id or not github_oauth.client_secret: + raise SystemExit( + "GitHub OAuth client_id/client_secret must be provided via mcp_agent.config.yaml or mcp_agent.secrets.yaml." + ) + +app = MCPApp( + name="oauth_basic_agent", settings=settings, session_id="oauth-basic-agent" +) @app.tool() @@ -95,27 +78,35 @@ async def example_usage() -> str: logger.info("Tools available:", data=tools_list.model_dump()) llm = await finder_agent.attach_llm(OpenAIAugmentedLLM) - result += await llm.generate_str( + + # GitHub MCP server use + github_repos = await llm.generate_str( + message="Use the GitHub MCP server to find the top 3 public repositories for the GitHub organization lastmile-ai and list their names.", + ) + logger.info( + f"Top 3 public repositories for the GitHub organization lastmile-ai: {github_repos}" + ) + + result += f"\n\nTop 3 public repositories for the GitHub organization lastmile-ai: {github_repos}" + + # Filesystem MCP server use + config_contents = await llm.generate_str( message="Print the contents of mcp_agent.config.yaml verbatim", ) - logger.info(f"mcp_agent.config.yaml contents: {result}") + logger.info(f"mcp_agent.config.yaml contents: {config_contents}") + result += f"\n\nContents of mcp_agent.config.yaml: {config_contents}" + # Switch to Anthropic LLM llm = await finder_agent.attach_llm(AnthropicAugmentedLLM) - result += await llm.generate_str( + # fetch MCP server use + mcp_introduction = await llm.generate_str( message="Print the first 2 paragraphs of https://modelcontextprotocol.io/introduction", ) - logger.info(f"First 2 paragraphs of Model Context Protocol docs: {result}") - result += "\n\n" - - result += await llm.generate_str( - message="Summarize those paragraphs in a 128 character tweet", - request_params=RequestParams( - modelPreferences=ModelPreferences( - costPriority=0.1, speedPriority=0.2, intelligencePriority=0.7 - ), - ), + logger.info( + f"First 2 paragraphs of Model Context Protocol docs: {mcp_introduction}" ) + result += f"\n\nFirst 2 paragraphs of Model Context Protocol docs: {mcp_introduction}" await display_token_summary(agent_app) return result diff --git a/examples/basic/oauth_basic_agent/mcp_agent.config.yaml b/examples/basic/oauth_basic_agent/mcp_agent.config.yaml index 944015e0f..f02be527e 100644 --- a/examples/basic/oauth_basic_agent/mcp_agent.config.yaml +++ b/examples/basic/oauth_basic_agent/mcp_agent.config.yaml @@ -25,12 +25,10 @@ mcp: auth: oauth: enabled: true - client_id: ${GITHUB_CLIENT_ID} - client_secret: ${GITHUB_CLIENT_SECRET} scopes: ["read:org", "public_repo", "user:email"] authorization_server: "https://github.com/login/oauth" - resource: "https://api.githubcopilot.com/mcp" use_internal_callback: false + include_resource_parameter: false openai: default_model: "gpt-4o-mini" diff --git a/examples/basic/oauth_basic_agent/mcp_agent.secrets.yaml.example b/examples/basic/oauth_basic_agent/mcp_agent.secrets.yaml.example index c737c0afb..7c21dd56c 100644 --- a/examples/basic/oauth_basic_agent/mcp_agent.secrets.yaml.example +++ b/examples/basic/oauth_basic_agent/mcp_agent.secrets.yaml.example @@ -8,8 +8,12 @@ openai: anthropic: api_key: "sk-your-anthropic-key" -# GitHub OAuth client (required for this example) -GITHUB_CLIENT_ID: "your-client-id" -GITHUB_CLIENT_SECRET: "your-client-secret" +mcp: + servers: + github: + auth: + oauth: + client_id: "github-client-id" + client_secret: "your-client-secret" diff --git a/examples/oauth/README.md b/examples/oauth/README.md index 09976af7d..8348ee895 100644 --- a/examples/oauth/README.md +++ b/examples/oauth/README.md @@ -11,9 +11,9 @@ reuse the stored token—after the first run, re-run `uv run examples/oauth/interactive_tool/client.py` (with the server still running) and you should see the result immediately with no additional prompt. -## workflow_pre_auth +## pre_authorize -Demonstrates seeding tokens via the `workflows-pre-auth` tool before running +Demonstrates seeding tokens via the `workflows-store-credentials` tool before running an asynchronous workflow. This is useful when workflows execute in the background (e.g., Temporal) and cannot perform interactive authentication on their own. diff --git a/examples/oauth/interactive_tool/server.py b/examples/oauth/interactive_tool/server.py index fe9c691c1..f83d8663d 100644 --- a/examples/oauth/interactive_tool/server.py +++ b/examples/oauth/interactive_tool/server.py @@ -120,7 +120,12 @@ async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> try: result = await github_client.call_tool( "search_repositories", - {"query": f"org:{query}", "per_page": 5, "sort": "best-match", "order": "desc"}, + { + "query": f"org:{query}", + "per_page": 5, + "sort": "best-match", + "order": "desc", + }, ) except Exception as exc: context.logger.error( diff --git a/examples/oauth/pre_authorize/README.md b/examples/oauth/pre_authorize/README.md new file mode 100644 index 000000000..19dbbea0d --- /dev/null +++ b/examples/oauth/pre_authorize/README.md @@ -0,0 +1,59 @@ +# Workflow Pre-Authorize Example + +This example shows how to seed OAuth credentials for asynchronous workflows. +The client calls the `workflows-store-credentials` tool to cache a token for a +specific workflow before the workflow runs. Once the token is saved, the +workflow can access the downstream MCP server without further user interaction. + +## Prerequisites + +1. Copy the secrets template and provide your GitHub OAuth client credentials: + + ```bash + cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml + ``` + + Edit the copied file (or export matching environment variables) so the GitHub + entry contains your OAuth app's client id and client secret. + +2. Obtain a GitHub access token (e.g., via the interactive example) and + export it before running the client: + + ```bash + export GITHUB_ACCESS_TOKEN="github_pat_xxx" + ``` + +3. Install dependencies: + + ```bash + pip install -e . + # optional redis support + # pip install -e .[redis] + ``` + +4. (Optional) To persist tokens in Redis instead of memory, start a Redis + instance and set `OAUTH_REDIS_URL`, for example: + + ```bash + docker run --rm -p 6379:6379 redis:7-alpine + export OAUTH_REDIS_URL="redis://127.0.0.1:6379" + ``` + +## Running + +1. Start the workflow server: + + ```bash + python examples/oauth/pre_authorize/main.py + ``` + +2. In another terminal, run the client to seed the token and execute the + workflow: + + ```bash + python examples/oauth/pre_authorize/client.py + ``` + +The client first invokes `workflows-store-credentials` with the provided token and +then calls the `github_org_search` workflow, which uses the cached token to +query the GitHub MCP server. diff --git a/examples/oauth/workflow_pre_auth/client.py b/examples/oauth/pre_authorize/client.py similarity index 90% rename from examples/oauth/workflow_pre_auth/client.py rename to examples/oauth/pre_authorize/client.py index 4d9ae1a7c..b089d7625 100644 --- a/examples/oauth/workflow_pre_auth/client.py +++ b/examples/oauth/pre_authorize/client.py @@ -1,7 +1,8 @@ import asyncio -import time +import json import os import sys +import time from datetime import timedelta from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream @@ -61,9 +62,9 @@ async def main(): logger.info("Connecting to workflow server...") # Override the server configuration to point to our local script - context.server_registry.registry["basic_agent_server"] = MCPServerSettings( - name="basic_agent_server", - description="Local workflow server running the basic agent example", + context.server_registry.registry["pre_authorize_server"] = MCPServerSettings( + name="pre_authorize_server", + description="Local workflow server running the pre-authorize example", transport="sse", url="http://127.0.0.1:8000/sse", # command="uv", @@ -111,7 +112,7 @@ def make_session( try: async with gen_client( - "basic_agent_server", + "pre_authorize_server", context.server_registry, client_session_factory=make_session, ) as server: @@ -128,10 +129,10 @@ def make_session( data={"tools": [tool.name for tool in tools_result.tools]}, ) - if len(sys.argv) < 2 or sys.argv[1] != "--skip-pre-auth": - print("Performing pre-auth") + if len(sys.argv) < 2 or sys.argv[1] != "--skip-store-credentials": + print("Storing workflow credentials") await server.call_tool( - "workflows-pre-auth", + "workflows-store-credentials", arguments={ "workflow_name": "github_org_search", "tokens": [ @@ -143,9 +144,14 @@ def make_session( }, ) - print( - await server.call_tool("github_org_search", {"query": "lastmileai"}) + tool_result = await server.call_tool( + "github_org_search", {"query": "lastmile-ai"} ) + parsed = _tool_result_to_json(tool_result) + if parsed is not None: + print(json.dumps(parsed, indent=2)) + else: + print(tool_result) except Exception as e: # Tolerate benign shutdown races from stdio client (BrokenResourceError within ExceptionGroup) if _ExceptionGroup is not None and isinstance(e, _ExceptionGroup): @@ -187,8 +193,6 @@ def _tool_result_to_json(tool_result: CallToolResult): text = tool_result.content[0].text try: # Try to parse the response as JSON if it's a string - import json - return json.loads(text) except (json.JSONDecodeError, TypeError): # If it's not valid JSON, just use the text diff --git a/examples/oauth/pre_authorize/main.py b/examples/oauth/pre_authorize/main.py new file mode 100644 index 000000000..96914c423 --- /dev/null +++ b/examples/oauth/pre_authorize/main.py @@ -0,0 +1,143 @@ +import asyncio +import inspect +import json +import os +from pathlib import Path +from typing import Optional + +from mcp.server.fastmcp import FastMCP + +from mcp_agent.app import MCPApp +from mcp_agent.config import get_settings, OAuthTokenStoreSettings, OAuthSettings +from mcp_agent.core.context import Context as AppContext +from mcp_agent.mcp.gen_client import gen_client +from mcp_agent.server.app_server import create_mcp_server_for_app + + +mcp = FastMCP( + name="pre_authorize_server", + instructions="Pre-authorize workflow example server.", +) + + +def _load_settings(): + signature = inspect.signature(get_settings) + kwargs = {} + config_path = Path(__file__).with_name("mcp_agent.config.yaml") + if "config_path" in signature.parameters: + kwargs["config_path"] = str(config_path) + if "set_global" in signature.parameters: + kwargs["set_global"] = False + return get_settings(**kwargs) + + +settings = _load_settings() + +redis_url = os.getenv("OAUTH_REDIS_URL") +if redis_url: + settings.oauth = settings.oauth or OAuthSettings() + settings.oauth.token_store = OAuthTokenStoreSettings( + backend="redis", + redis_url=redis_url, + ) +elif not getattr(settings.oauth, "token_store", None): + settings.oauth = settings.oauth or OAuthSettings() + settings.oauth.token_store = OAuthTokenStoreSettings() + +github_settings = ( + settings.mcp.servers.get("github") + if settings.mcp and settings.mcp.servers + else None +) +github_oauth = ( + github_settings.auth.oauth + if github_settings and github_settings.auth and github_settings.auth.oauth + else None +) + +if not github_oauth or not github_oauth.client_id or not github_oauth.client_secret: + raise SystemExit( + "GitHub OAuth client_id/client_secret must be provided via mcp_agent.config.yaml or mcp_agent.secrets.yaml." + ) + +app = MCPApp( + name="pre_authorize_server", + description="Pre-authorize workflow example", + mcp=mcp, + settings=settings, + session_id="workflow-pre-authorize", +) + + +@app.workflow_task(name="github_org_search_activity") +async def github_org_search_activity(query: str) -> str: + app.logger.info("github_org_search_activity started") + try: + async with gen_client( + "github", server_registry=app.context.server_registry, context=app.context + ) as github_client: + app.logger.info("Obtained GitHub MCP client") + result = await github_client.call_tool( + "search_repositories", + { + "query": f"org:{query}", + "per_page": 5, + "sort": "best-match", + "order": "desc", + }, + ) + + repositories = [] + if result.content: + for content_item in result.content: + if hasattr(content_item, "text"): + try: + data = json.loads(content_item.text) + if isinstance(data, dict) and "items" in data: + repositories.extend(data["items"]) + elif isinstance(data, list): + repositories.extend(data) + except json.JSONDecodeError: + pass + + app.logger.info("Repositories fetched", data={"count": len(repositories)}) + return json.dumps(repositories, indent=2) + except Exception as e: + import traceback + + traceback.print_exc() + return f"Error: {e}" + + +@app.tool(name="github_org_search") +async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: + if app._logger and hasattr(app._logger, "_bound_context"): + app._logger._bound_context = app.context + + result = await app.executor.execute(github_org_search_activity, query) + app.logger.info("Workflow result", data={"result": result}) + + return result + + +async def main(): + async with app.run() as agent_app: + # Log registered workflows and agent configurations + agent_app.logger.info(f"Creating MCP server for {agent_app.name}") + + agent_app.logger.info("Registered workflows:") + for workflow_id in agent_app.workflows: + agent_app.logger.info(f" - {workflow_id}") + + # Create the MCP server that exposes both workflows and agent configurations, + # optionally using custom FastMCP settings + mcp_server = create_mcp_server_for_app(agent_app) + agent_app.logger.info(f"MCP Server settings: {mcp_server.settings}") + + # Run the server + # await mcp_server.run_stdio_async() + await mcp_server.run_sse_async() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/oauth/pre_authorize/mcp_agent.config.yaml b/examples/oauth/pre_authorize/mcp_agent.config.yaml new file mode 100644 index 000000000..7a6a065f7 --- /dev/null +++ b/examples/oauth/pre_authorize/mcp_agent.config.yaml @@ -0,0 +1,31 @@ +$schema: ../../../schema/mcp-agent.config.schema.json + +execution_engine: temporal +temporal: + host: localhost:7233 + namespace: default + task_queue: mcp-agent + max_concurrent_activities: 10 + +logger: + transports: [console, file] + level: info + path_settings: + path_pattern: "logs/mcp-agent-{unique_id}.jsonl" + unique_id: "timestamp" + +oauth: + loopback_ports: [33418, 33419, 33420] + +mcp: + servers: + github: + transport: streamable_http + url: "https://api.githubcopilot.com/mcp/" + auth: + oauth: + enabled: true + scopes: ["read:org", "public_repo", "user:email"] + authorization_server: "https://github.com/login/oauth" + use_internal_callback: false + include_resource_parameter: false diff --git a/examples/oauth/pre_authorize/mcp_agent.secrets.yaml.example b/examples/oauth/pre_authorize/mcp_agent.secrets.yaml.example new file mode 100644 index 000000000..95509475c --- /dev/null +++ b/examples/oauth/pre_authorize/mcp_agent.secrets.yaml.example @@ -0,0 +1,13 @@ +$schema: ../../../schema/mcp-agent.config.schema.json + +# Copy this file to mcp_agent.secrets.yaml and fill in your credentials. + +mcp: + servers: + github: + auth: + oauth: + client_id: "your-github-client-id" + client_secret: "your-github-client-secret" + access_token: "your-github-access-token" + diff --git a/examples/oauth/workflow_pre_auth/worker.py b/examples/oauth/pre_authorize/worker.py similarity index 100% rename from examples/oauth/workflow_pre_auth/worker.py rename to examples/oauth/pre_authorize/worker.py diff --git a/examples/oauth/workflow_pre_auth/README.md b/examples/oauth/workflow_pre_auth/README.md deleted file mode 100644 index d52b4fee4..000000000 --- a/examples/oauth/workflow_pre_auth/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Workflow Pre-Authorization Example - -This example shows how to preload OAuth tokens for asynchronous workflows. -The client calls the `workflows-pre-auth` tool to store a token for a -specific workflow before the workflow runs. Once the token is saved, the -workflow can access the downstream MCP server without further user -interaction. - -## Prerequisites - -1. Obtain a GitHub access token (e.g., via the interactive example) and - export it before running the client: - - ```bash - export GITHUB_ACCESS_TOKEN="github_pat_xxx" - ``` - -2. Install dependencies: - - ```bash - pip install -e . - # optional redis support - # pip install -e .[redis] - ``` - -3. (Optional) To persist tokens in Redis instead of memory, start a Redis - instance and set `OAUTH_REDIS_URL`, for example: - - ```bash - docker run --rm -p 6379:6379 redis:7-alpine - export OAUTH_REDIS_URL="redis://127.0.0.1:6379" - ``` - -## Running - -1. Start the workflow server: - - ```bash - python examples/oauth/workflow_pre_auth/main.py - ``` - -2. In another terminal, run the client to seed the token and execute the - workflow: - - ```bash - python examples/oauth/workflow_pre_auth/client.py - ``` - -The client first invokes `workflows-pre-auth` with the provided token and -then calls the `github_org_search` workflow, which uses the cached token to -query the GitHub MCP server. diff --git a/examples/oauth/workflow_pre_auth/main.py b/examples/oauth/workflow_pre_auth/main.py deleted file mode 100644 index a4575496c..000000000 --- a/examples/oauth/workflow_pre_auth/main.py +++ /dev/null @@ -1,177 +0,0 @@ -import asyncio -import json -import os -from typing import Optional - -from pydantic import AnyHttpUrl - -from mcp.server.fastmcp import FastMCP - -from mcp_agent.app import MCPApp -from mcp_agent.config import ( - LoggerSettings, - MCPOAuthClientSettings, - MCPServerAuthSettings, - MCPServerSettings, - MCPSettings, - OAuthSettings, - OAuthTokenStoreSettings, - Settings, - TemporalSettings, -) -from mcp_agent.core.context import Context as AppContext -from mcp_agent.mcp.gen_client import gen_client -from mcp_agent.server.app_server import create_mcp_server_for_app - -# Note: This is purely optional: -# if not provided, a default FastMCP server will be created by MCPApp using create_mcp_server_for_app() -mcp = FastMCP(name="basic_agent_server", instructions="My basic agent server example.") - - -# Get client id and secret from environment variables -client_id = os.getenv("GITHUB_CLIENT_ID") -client_secret = os.getenv("GITHUB_CLIENT_SECRET") - -if not client_id or not client_secret: - print( - "\nGitHub client id and/or secret not found in GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET " - "environment variables." - ) - print("\nTo create these:") - print("1. Open your profile on github.com and navigate to 'Developer Settings'") - print("2. Create a new OAuth app and create a client secret for it.") - print("3. Create environment variables:") - print("export GITHUB_CLIENT_ID='your_client_id_here'") - print("export GITHUB_CLIENT_SECRET='your_client_secret_here'") - exit(1) - -redis_url = os.getenv("OAUTH_REDIS_URL") -if redis_url: - token_store_settings = OAuthTokenStoreSettings( - backend="redis", - redis_url=redis_url, - redis_prefix="mcp_agent:oauth_tokens", - refresh_leeway_seconds=60, - ) -else: - token_store_settings = OAuthTokenStoreSettings(refresh_leeway_seconds=60) - -settings = Settings( - execution_engine="temporal", - temporal=TemporalSettings( - host="localhost:7233", - namespace="default", - task_queue="mcp-agent", - max_concurrent_activities=10, - ), - logger=LoggerSettings(level="info"), - oauth=OAuthSettings( - callback_base_url=AnyHttpUrl("http://localhost:8000"), - flow_timeout_seconds=300, - token_store=token_store_settings, - ), - mcp=MCPSettings( - servers={ - "github": MCPServerSettings( - name="github", - transport="streamable_http", - url="https://api.githubcopilot.com/mcp/", - auth=MCPServerAuthSettings( - oauth=MCPOAuthClientSettings( - client_id=client_id, - client_secret=client_secret, - use_internal_callback=True, - enabled=True, - scopes=[ - "read:org", # Required for search_orgs tool - "public_repo", # Access to public repositories - "user:email", # User information access - ], - authorization_server=AnyHttpUrl( - "https://github.com/login/oauth" - ), - resource=AnyHttpUrl("https://api.githubcopilot.com/mcp"), - ) - ), - ) - } - ), -) - -# Define the MCPApp instance. The server created for this app will advertise the -# MCP logging capability and forward structured logs upstream to connected clients. -app = MCPApp( - name="basic_agent_server", - description="Basic agent server example", - mcp=mcp, - settings=settings, -) - - -@app.workflow_task(name="github_org_search_activity") -async def github_org_search_activity(query: str) -> str: - print("running activity)") - try: - async with gen_client( - "github", server_registry=app.context.server_registry, context=app.context - ) as github_client: - print("got client") - result = await github_client.call_tool( - "search_orgs", - {"query": query, "perPage": 10, "sort": "best-match", "order": "desc"}, - ) - - organizations = [] - if result.content: - for content_item in result.content: - if hasattr(content_item, "text"): - try: - data = json.loads(content_item.text) - if isinstance(data, dict) and "items" in data: - organizations.extend(data["items"]) - elif isinstance(data, list): - organizations.extend(data) - except json.JSONDecodeError: - pass - - print(f"Organizations: {organizations}") - return str(organizations) - except Exception as e: - import traceback - - traceback.print_exc() - return f"Error: {e}" - - -@app.tool(name="github_org_search") -async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: - if app._logger and hasattr(app._logger, "_bound_context"): - app._logger._bound_context = app.context - - result = await app.executor.execute(github_org_search_activity, query) - print(f"Result: {result}") - - return result - - -async def main(): - async with app.run() as agent_app: - # Log registered workflows and agent configurations - agent_app.logger.info(f"Creating MCP server for {agent_app.name}") - - agent_app.logger.info("Registered workflows:") - for workflow_id in agent_app.workflows: - agent_app.logger.info(f" - {workflow_id}") - - # Create the MCP server that exposes both workflows and agent configurations, - # optionally using custom FastMCP settings - mcp_server = create_mcp_server_for_app(agent_app) - agent_app.logger.info(f"MCP Server settings: {mcp_server.settings}") - - # Run the server - # await mcp_server.run_stdio_async() - await mcp_server.run_sse_async() - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/src/mcp_agent/mcp/mcp_connection_manager.py b/src/mcp_agent/mcp/mcp_connection_manager.py index 27a76f632..96cd11b1a 100644 --- a/src/mcp_agent/mcp/mcp_connection_manager.py +++ b/src/mcp_agent/mcp/mcp_connection_manager.py @@ -35,6 +35,7 @@ from mcp_agent.logging.event_progress import ProgressAction from mcp_agent.logging.logger import get_logger from mcp_agent.mcp.mcp_agent_client_session import MCPAgentClientSession +from mcp_agent.oauth.http import OAuthHttpxAuth if TYPE_CHECKING: from mcp_agent.mcp.mcp_server_registry import InitHookCallable, ServerRegistry @@ -43,6 +44,16 @@ logger = get_logger(__name__) +def _resolve_identity_from_context(): + try: + from mcp_agent.server import app_server # type: ignore + + identity = app_server.get_current_identity() + return identity + except Exception: + return None + + class ServerConnection: """ Represents a long-lived MCP server connection, including: @@ -477,6 +488,31 @@ def transport_context_factory(): if sse_read_timeout is not None: kwargs["sse_read_timeout"] = sse_read_timeout + auth_handler = None + oauth_cfg = config.auth.oauth if config.auth else None + ctx = None + try: + ctx = self.context + except Exception: + ctx = None + if oauth_cfg and oauth_cfg.enabled: + token_manager = getattr(ctx, "token_manager", None) if ctx else None + if token_manager is None: + logger.warning( + f"{server_name}: OAuth configured but token manager not available; skipping auth" + ) + else: + auth_handler = OAuthHttpxAuth( + token_manager=token_manager, + context=ctx, + server_name=server_name, + server_config=config, + scopes=oauth_cfg.scopes, + identity_resolver=_resolve_identity_from_context, + ) + if auth_handler: + kwargs["auth"] = auth_handler + return streamablehttp_client( **kwargs, ) diff --git a/src/mcp_agent/server/app_server.py b/src/mcp_agent/server/app_server.py index ca3965910..aea520c70 100644 --- a/src/mcp_agent/server/app_server.py +++ b/src/mcp_agent/server/app_server.py @@ -1888,16 +1888,15 @@ async def cancel_workflow( return result - @mcp.tool(name="workflows-pre-auth") - async def workflow_pre_auth( + @mcp.tool(name="workflows-store-credentials") + async def workflow_store_credentials( ctx: MCPContext, workflow_name: str, tokens: List[Dict[str, Any]] ) -> Dict[str, Any]: """ - Pre-authorize OAuth tokens for a workflow to use with MCP servers. + Store OAuth tokens for a workflow to use with MCP servers. - Stores OAuth tokens that the workflow can use when connecting to various MCP servers. - This allows workflows to authenticate with external services without requiring - interactive OAuth flows during execution. + Persisting tokens ahead of time lets workflows authenticate with external services + without needing an interactive OAuth flow at execution time. Args: workflow_name: The name of the workflow that will use these tokens. From ade29709f8e345dce571dcf29605caaad478a8af Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 21 Oct 2025 19:28:28 -0400 Subject: [PATCH 24/25] Regenerate schema and add docstrings --- schema/mcp-agent.config.schema.json | 331 +++++++++++++++++++++++++--- src/mcp_agent/config.py | 82 ++++++- 2 files changed, 369 insertions(+), 44 deletions(-) diff --git a/schema/mcp-agent.config.schema.json b/schema/mcp-agent.config.schema.json index 0f9f4cc90..2c3d362d7 100644 --- a/schema/mcp-agent.config.schema.json +++ b/schema/mcp-agent.config.schema.json @@ -620,18 +620,21 @@ "title": "LoggerSettings", "type": "object" }, - "MCPRootSettings": { + "MCPAuthorizationServerSettings": { "additionalProperties": true, - "description": "Represents a root directory configuration for an MCP server.", + "description": "Configuration for exposing the MCP Agent server as an OAuth protected resource.", "properties": { - "uri": { - "title": "Uri", - "type": "string", - "description": "The URI identifying the root. Must start with file://" + "enabled": { + "default": false, + "title": "Enabled", + "type": "boolean", + "description": "Whether to expose this MCP app as an OAuth-protected resource server." }, - "name": { + "issuer_url": { "anyOf": [ { + "format": "uri", + "minLength": 1, "type": "string" }, { @@ -639,12 +642,14 @@ } ], "default": null, - "title": "Name", - "description": "Optional name for the root." + "title": "Issuer Url", + "description": "Issuer URL advertised to clients (must resolve to provider metadata)." }, - "server_uri_alias": { + "resource_server_url": { "anyOf": [ { + "format": "uri", + "minLength": 1, "type": "string" }, { @@ -652,23 +657,115 @@ } ], "default": null, - "title": "Server Uri Alias", - "description": "Optional URI alias for presentation to the server" + "title": "Resource Server Url", + "description": "Base URL of the protected resource (used for discovery and validation)." + }, + "service_documentation_url": { + "anyOf": [ + { + "format": "uri", + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Service Documentation Url", + "description": "Optional URL pointing to resource server documentation for clients." + }, + "required_scopes": { + "items": { + "type": "string" + }, + "title": "Required Scopes", + "type": "array", + "description": "Scopes that clients must present when accessing this resource." + }, + "jwks_uri": { + "anyOf": [ + { + "format": "uri", + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Jwks Uri", + "description": "Optional JWKS endpoint for validating JWT access tokens." + }, + "introspection_endpoint": { + "anyOf": [ + { + "format": "uri", + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Introspection Endpoint", + "description": "Optional OAuth introspection endpoint for opaque tokens." + }, + "introspection_client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Introspection Client Id", + "description": "Client id to use when calling the introspection endpoint." + }, + "introspection_client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Introspection Client Secret", + "description": "Client secret to use when calling the introspection endpoint." + }, + "token_cache_ttl_seconds": { + "default": 300, + "minimum": 0, + "title": "Token Cache Ttl Seconds", + "type": "integer", + "description": "How long (in seconds) to cache positive introspection/JWT validation results." + }, + "expected_audiences": { + "items": { + "type": "string" + }, + "title": "Expected Audiences", + "type": "array" } }, - "required": [ - "uri" - ], - "title": "MCPRootSettings", + "title": "MCPAuthorizationServerSettings", "type": "object" }, "MCPOAuthClientSettings": { "additionalProperties": true, + "description": "Configuration for authenticating to downstream OAuth-protected MCP servers.", "properties": { "enabled": { "default": false, "title": "Enabled", - "type": "boolean" + "type": "boolean", + "description": "Whether OAuth auth is enabled for this downstream server." }, "scopes": { "items": { @@ -676,11 +773,13 @@ }, "title": "Scopes", "type": "array", - "default": [] + "description": "OAuth scopes to request when authorizing." }, "resource": { "anyOf": [ { + "format": "uri", + "minLength": 1, "type": "string" }, { @@ -688,11 +787,14 @@ } ], "default": null, - "title": "Resource" + "title": "Resource", + "description": "Protected resource identifier to include in token/authorize requests (RFC 8707)." }, "authorization_server": { "anyOf": [ { + "format": "uri", + "minLength": 1, "type": "string" }, { @@ -700,7 +802,8 @@ } ], "default": null, - "title": "Authorization Server" + "title": "Authorization Server", + "description": "Authorization server base URL (provider metadata is discovered from this root)." }, "client_id": { "anyOf": [ @@ -712,7 +815,8 @@ } ], "default": null, - "title": "Client Id" + "title": "Client Id", + "description": "OAuth client identifier registered with the authorization server." }, "client_secret": { "anyOf": [ @@ -724,7 +828,8 @@ } ], "default": null, - "title": "Client Secret" + "title": "Client Secret", + "description": "OAuth client secret for confidential clients." }, "access_token": { "anyOf": [ @@ -736,7 +841,8 @@ } ], "default": null, - "title": "Access Token" + "title": "Access Token", + "description": "Optional pre-seeded access token that bypasses the interactive flow." }, "refresh_token": { "anyOf": [ @@ -748,7 +854,8 @@ } ], "default": null, - "title": "Refresh Token" + "title": "Refresh Token", + "description": "Optional refresh token stored alongside a pre-seeded access token." }, "expires_at": { "anyOf": [ @@ -760,12 +867,14 @@ } ], "default": null, - "title": "Expires At" + "title": "Expires At", + "description": "Epoch timestamp (seconds) when the pre-seeded token expires." }, "token_type": { "default": "Bearer", "title": "Token Type", - "type": "string" + "type": "string", + "description": "Token type returned by the provider; defaults to Bearer." }, "redirect_uri_options": { "items": { @@ -773,7 +882,7 @@ }, "title": "Redirect Uri Options", "type": "array", - "default": [] + "description": "Allowed redirect URI values; the flow selects from this list." }, "extra_authorize_params": { "additionalProperties": { @@ -781,7 +890,7 @@ }, "title": "Extra Authorize Params", "type": "object", - "default": {} + "description": "Additional query parameters to append to the authorize request." }, "extra_token_params": { "additionalProperties": { @@ -789,27 +898,72 @@ }, "title": "Extra Token Params", "type": "object", - "default": {} + "description": "Additional form parameters to append to the token request." }, "require_pkce": { "default": true, "title": "Require Pkce", - "type": "boolean" + "type": "boolean", + "description": "Whether to enforce PKCE when initiating the authorization code flow." }, "use_internal_callback": { "default": true, "title": "Use Internal Callback", - "type": "boolean" + "type": "boolean", + "description": "When true, attempt to use the app's internal callback URL before loopback." }, "include_resource_parameter": { "default": true, "title": "Include Resource Parameter", - "type": "boolean" + "type": "boolean", + "description": "Whether to include the RFC 8707 `resource` parameter in authorize/token requests." } }, "title": "MCPOAuthClientSettings", "type": "object" }, + "MCPRootSettings": { + "additionalProperties": true, + "description": "Represents a root directory configuration for an MCP server.", + "properties": { + "uri": { + "title": "Uri", + "type": "string", + "description": "The URI identifying the root. Must start with file://" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name", + "description": "Optional name for the root." + }, + "server_uri_alias": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Server Uri Alias", + "description": "Optional URI alias for presentation to the server" + } + }, + "required": [ + "uri" + ], + "title": "MCPRootSettings", + "type": "object" + }, "MCPServerAuthSettings": { "additionalProperties": true, "description": "Represents authentication configuration for a server.", @@ -835,8 +989,7 @@ "type": "null" } ], - "default": null, - "title": "Oauth" + "default": null } }, "title": "MCPServerAuthSettings", @@ -1055,6 +1208,91 @@ "title": "MCPSettings", "type": "object" }, + "OAuthSettings": { + "additionalProperties": true, + "description": "Global OAuth-related settings for MCP Agent.", + "properties": { + "token_store": { + "$ref": "#/$defs/OAuthTokenStoreSettings" + }, + "flow_timeout_seconds": { + "default": 300, + "minimum": 30, + "title": "Flow Timeout Seconds", + "type": "integer", + "description": "Maximum number of seconds to wait for an authorization callback before timing out." + }, + "callback_base_url": { + "anyOf": [ + { + "format": "uri", + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Callback Base Url", + "description": "Base URL for internal callbacks (used when `use_internal_callback` is true)." + }, + "loopback_ports": { + "items": { + "type": "integer" + }, + "title": "Loopback Ports", + "type": "array", + "description": "Ports to use for local loopback callbacks when internal callbacks are unavailable." + } + }, + "title": "OAuthSettings", + "type": "object" + }, + "OAuthTokenStoreSettings": { + "additionalProperties": true, + "description": "Settings for OAuth token persistence.", + "properties": { + "backend": { + "default": "memory", + "enum": [ + "memory", + "redis" + ], + "title": "Backend", + "type": "string", + "description": "Persistence backend to use for storing tokens." + }, + "redis_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Redis Url", + "description": "Connection URL for Redis when using the redis backend." + }, + "redis_prefix": { + "default": "mcp_agent:oauth_tokens", + "title": "Redis Prefix", + "type": "string", + "description": "Key prefix used when writing tokens to Redis." + }, + "refresh_leeway_seconds": { + "default": 60, + "minimum": 0, + "title": "Refresh Leeway Seconds", + "type": "integer", + "description": "Seconds before expiry when tokens should be refreshed." + } + }, + "title": "OAuthTokenStoreSettings", + "type": "object" + }, "OTLPExporterSettings": { "additionalProperties": true, "properties": { @@ -1678,9 +1916,32 @@ "definitions": [] }, "description": "Settings for defining and loading subagents for the MCP Agent application" + }, + "authorization": { + "anyOf": [ + { + "$ref": "#/$defs/MCPAuthorizationServerSettings" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Settings for exposing this MCP application as an OAuth protected resource" + }, + "oauth": { + "anyOf": [ + { + "$ref": "#/$defs/OAuthSettings" + }, + { + "type": "null" + } + ], + "description": "Global OAuth client configuration (token store, delegated auth defaults)" } }, "title": "MCP Agent Configuration Schema", "type": "object", "$schema": "http://json-schema.org/draft-07/schema#" -} +} \ No newline at end of file diff --git a/src/mcp_agent/config.py b/src/mcp_agent/config.py index 0c7ea01ee..a6e5255a3 100644 --- a/src/mcp_agent/config.py +++ b/src/mcp_agent/config.py @@ -26,28 +26,38 @@ from mcp_agent.agents.agent_spec import AgentSpec -class MCPServerAuthSettings(BaseModel): - """Represents authentication configuration for a server.""" - - api_key: str | None = None - oauth: Optional["MCPOAuthClientSettings"] = None - - model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) - - class MCPAuthorizationServerSettings(BaseModel): """Configuration for exposing the MCP Agent server as an OAuth protected resource.""" enabled: bool = False + """Whether to expose this MCP app as an OAuth-protected resource server.""" + issuer_url: AnyHttpUrl | None = None + """Issuer URL advertised to clients (must resolve to provider metadata).""" + resource_server_url: AnyHttpUrl | None = None + """Base URL of the protected resource (used for discovery and validation).""" + service_documentation_url: AnyHttpUrl | None = None + """Optional URL pointing to resource server documentation for clients.""" + required_scopes: List[str] = Field(default_factory=list) + """Scopes that clients must present when accessing this resource.""" + jwks_uri: AnyHttpUrl | None = None + """Optional JWKS endpoint for validating JWT access tokens.""" + introspection_endpoint: AnyHttpUrl | None = None + """Optional OAuth introspection endpoint for opaque tokens.""" + introspection_client_id: str | None = None + """Client id to use when calling the introspection endpoint.""" + introspection_client_secret: str | None = None + """Client secret to use when calling the introspection endpoint.""" + token_cache_ttl_seconds: int = Field(300, ge=0) + """How long (in seconds) to cache positive introspection/JWT validation results.""" # RFC 9068 audience validation settings # TODO: this should really depend on the app_id, or config_id so that we can enforce unique values. @@ -81,22 +91,53 @@ class MCPOAuthClientSettings(BaseModel): """Configuration for authenticating to downstream OAuth-protected MCP servers.""" enabled: bool = False + """Whether OAuth auth is enabled for this downstream server.""" + scopes: List[str] = Field(default_factory=list) + """OAuth scopes to request when authorizing.""" + resource: AnyHttpUrl | None = None + """Protected resource identifier to include in token/authorize requests (RFC 8707).""" + authorization_server: AnyHttpUrl | None = None + """Authorization server base URL (provider metadata is discovered from this root).""" + client_id: str | None = None + """OAuth client identifier registered with the authorization server.""" + client_secret: str | None = None + """OAuth client secret for confidential clients.""" + # Support for pre-configured access tokens (bypasses OAuth flow) access_token: str | None = None + """Optional pre-seeded access token that bypasses the interactive flow.""" + refresh_token: str | None = None + """Optional refresh token stored alongside a pre-seeded access token.""" + expires_at: float | None = None + """Epoch timestamp (seconds) when the pre-seeded token expires.""" + token_type: str = "Bearer" + """Token type returned by the provider; defaults to Bearer.""" + redirect_uri_options: List[str] = Field(default_factory=list) + """Allowed redirect URI values; the flow selects from this list.""" + extra_authorize_params: Dict[str, str] = Field(default_factory=dict) + """Additional query parameters to append to the authorize request.""" + extra_token_params: Dict[str, str] = Field(default_factory=dict) + """Additional form parameters to append to the token request.""" + require_pkce: bool = True + """Whether to enforce PKCE when initiating the authorization code flow.""" + use_internal_callback: bool = True + """When true, attempt to use the app's internal callback URL before loopback.""" + include_resource_parameter: bool = True + """Whether to include the RFC 8707 `resource` parameter in authorize/token requests.""" model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) @@ -105,9 +146,16 @@ class OAuthTokenStoreSettings(BaseModel): """Settings for OAuth token persistence.""" backend: Literal["memory", "redis"] = "memory" + """Persistence backend to use for storing tokens.""" + redis_url: str | None = None + """Connection URL for Redis when using the redis backend.""" + redis_prefix: str = "mcp_agent:oauth_tokens" + """Key prefix used when writing tokens to Redis.""" + refresh_leeway_seconds: int = Field(60, ge=0) + """Seconds before expiry when tokens should be refreshed.""" model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) @@ -118,10 +166,26 @@ class OAuthSettings(BaseModel): token_store: OAuthTokenStoreSettings = Field( default_factory=OAuthTokenStoreSettings ) + """Token storage configuration shared across downstream servers.""" + flow_timeout_seconds: int = Field(300, ge=30) + """Maximum number of seconds to wait for an authorization callback before timing out.""" + callback_base_url: AnyHttpUrl | None = None + """Base URL for internal callbacks (used when `use_internal_callback` is true).""" + # Fixed loopback ports to try (client-only OAuth). If empty, loopback is disabled. loopback_ports: list[int] = Field(default_factory=lambda: [33418, 33419, 33420]) + """Ports to use for local loopback callbacks when internal callbacks are unavailable.""" + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + +class MCPServerAuthSettings(BaseModel): + """Represents authentication configuration for a server.""" + + api_key: str | None = None + oauth: MCPOAuthClientSettings | None = None model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) From 7ddcf4614eca088ca8fa17de139b17053d9bd9f1 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Tue, 21 Oct 2025 19:33:45 -0400 Subject: [PATCH 25/25] Remove TESTING_GUIDE.md --- TESTING_GUIDE.md | 180 ----------------------------------------------- 1 file changed, 180 deletions(-) delete mode 100644 TESTING_GUIDE.md diff --git a/TESTING_GUIDE.md b/TESTING_GUIDE.md deleted file mode 100644 index f72d019b1..000000000 --- a/TESTING_GUIDE.md +++ /dev/null @@ -1,180 +0,0 @@ -# OAuth Flow Validation Guide - -This checklist lets you flip between the original `feat/mcp_agent_oauth` branch and the current branch, exercise every scenario we discussed, and confirm the token flows (including caching) behave as intended. All commands use `uv` for Python execution. - ---- - -## 0. One-Time Setup - -### 0.1 Create a Virtual Environment - -```bash -uv venv -source .venv/bin/activate -``` - -### 0.2 Install Project (with optional extras) - -```bash -uv pip install -e .[oauth,cli,redis] -``` - -### 0.3 Start Temporal (required by the workflow examples) - -```bash -temporal server start-dev -``` - -### 0.4 Set Secrets You'll Reuse - -```bash -export GITHUB_CLIENT_ID=your_client_id -export GITHUB_CLIENT_SECRET=your_client_secret - export GITHUB_ACCESS_TOKEN=ghp_your_pat # for token bootstrap flows -``` - -### 0.5 (Optional) Start Redis for Redis-backed tests - -```bash -docker run --rm -p 6379:6379 redis:7-alpine -export OAUTH_REDIS_URL=redis://127.0.0.1:6379 -``` - ---- - -## 1. Original Branch (`feat/mcp_agent_oauth`) - -```bash -git checkout feat/mcp_agent_oauth -``` - -### 1.1 Unit Tests - -```bash -uv run python -m pytest tests/test_oauth_utils.py tests/test_audience_validation.py -# add tests/test_token_manager.py if it exists in that branch -``` - -### 1.2 Examples - -#### 1.2.1 Preconfigured (static token cache) - -- Terminal 1: - ```bash - uv run python examples/oauth/preconfigured/main.py - ``` - -#### 1.2.2 Workflow Pre-Authorize - -- Terminal 1: - ```bash - uv run python examples/oauth/pre_authorize/worker.py - ``` -- Terminal 2: - ```bash - uv run python examples/oauth/pre_authorize/main.py - ``` -- Terminal 3: - ```bash - uv run python examples/oauth/pre_authorize/client.py - ``` - Optional: rerun the client with `--skip-store-credentials` to confirm cached token reuse. - -#### 1.2.3 Dynamic Interactive Flow - -- Terminal 1: - ```bash - uv run python examples/oauth/dynamic_auth/worker.py - ``` -- Terminal 2: - ```bash - uv run python examples/oauth/dynamic_auth/main.py - ``` -- Terminal 3: - ```bash - uv run python examples/oauth/dynamic_auth/client.py - ``` - -#### 1.2.4 Standalone OAuth Helper - -```bash -uv run python examples/oauth/preconfigured/oauth_demo.py -``` - ---- - -## 2. Current Branch (`your current working branch`) - -```bash -git checkout -``` - -### 2.1 Unit Tests - -```bash -uv run python -m pytest tests/test_oauth_utils.py tests/test_audience_validation.py tests/test_token_manager.py -``` - -_(Fix pytest/pytest_asyncio integration if you still have the autoload error before running.)_ - -### 2.2 Examples - -#### 2.2.1 Interactive Tool Flow (dynamic auth) - -- Terminal 1: - ```bash - uv run python examples/oauth/interactive_tool/server.py - ``` -- Terminal 2: - ```bash - uv run python examples/oauth/interactive_tool/client.py - ``` - After finishing the first run, run the client **again** (with the server still running). The second invocation should return immediately with no additional auth prompt—confirming token caching. - -#### 2.2.1b Client-only loopback (basic agent) - -- In `examples/basic/oauth_basic_agent/`, copy the secrets template and add your credentials: - ```bash - cd examples/basic/oauth_basic_agent - cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml # fill in keys/client details - uv pip install -r requirements.txt - export GITHUB_CLIENT_ID=your_client_id # skip if secrets file already has these - export GITHUB_CLIENT_SECRET=your_client_secret - uv run python main.py - ``` - On first run the browser opens to GitHub; authorize and the agent completes. Run the same command again and it should reuse the cached token without prompting. To choose different loopback ports, set `oauth.loopback_ports` in `mcp_agent.config.yaml`. - -#### 2.2.2 Workflow Pre-Authorize - -- Terminal 1: - ```bash - uv run python examples/oauth/pre_authorize/worker.py - ``` -- Terminal 2: - ```bash - uv run python examples/oauth/pre_authorize/main.py - ``` -- Terminal 3: - ```bash - uv run python examples/oauth/pre_authorize/client.py - ``` - Repeat with `--skip-store-credentials` to verify cached token reuse after the workflow has been seeded once. - -#### 2.2.3 Redis-backed Token Cache (optional) - -- Make sure Redis is running (step 0.5 above). -- With `OAUTH_REDIS_URL` exported and the redis extra installed, re-run either example. Tokens will persist across server restarts, so you can stop and restart the server and rerun the client to confirm the Redis cache is used. - ---- - -## 3. Manual Validation Matrix - -| Scenario | Terminal(s) | Expected outcome | -| ------------------------------------ | ----------------------------------------- | --------------------------------------------------------------------------- | -| Workflow pre-authorize (both branches) | Worker + server + client | First run seeds token, subsequent run with `--skip-store-credentials` reuses it. | -| Interactive flow (both branches) | Server + client | First run asks for auth; immediate re-run uses cached token without prompt. | -| Redis token caching (current branch) | Same as above but with Redis env vars set | Tokens survive server restart thanks to Redis-backed store. | - ---- - -Following this checklist will let you validate the complete OAuth functionality on both branches, including the multiple-user token caching behavior.