From e9d3cd37d339f7b9c65da33c48065ba3e5d6f414 Mon Sep 17 00:00:00 2001 From: Bram van Meurs <7422223+bcvanmeurs@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:54:10 +0100 Subject: [PATCH 01/83] fix(build): .dockerignore not picked up Using the git context of the build-push-action ignores the .dockerignore because it is pulled by buildkit. Instead use checkout action and use the path context. --- .github/workflows/ghcr_deploy.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ghcr_deploy.yml b/.github/workflows/ghcr_deploy.yml index 58cda02c31..872c033cf5 100644 --- a/.github/workflows/ghcr_deploy.yml +++ b/.github/workflows/ghcr_deploy.yml @@ -25,6 +25,9 @@ jobs: if: github.repository == 'BerriAI/litellm' runs-on: ubuntu-latest steps: + - + name: Checkout + uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -41,12 +44,14 @@ jobs: name: Build and push uses: docker/build-push-action@v5 with: + context: . push: true tags: litellm/litellm:${{ github.event.inputs.tag || 'latest' }} - name: Build and push litellm-database image uses: docker/build-push-action@v5 with: + context: . push: true file: Dockerfile.database tags: litellm/litellm-database:${{ github.event.inputs.tag || 'latest' }} @@ -54,6 +59,7 @@ jobs: name: Build and push litellm-spend-logs image uses: docker/build-push-action@v5 with: + context: . push: true file: ./litellm-js/spend-logs/Dockerfile tags: litellm/litellm-spend_logs:${{ github.event.inputs.tag || 'latest' }} @@ -92,7 +98,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@4976231911ebf5f32aad765192d35f942aa48cb8 with: - context: https://github.com/BerriAI/litellm.git#${{ github.event.inputs.commit_hash}} + context: . push: true tags: ${{ steps.meta.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, ${{ steps.meta.outputs.tags }}-${{ github.event.inputs.release_type }} # if a tag is provided, use that, otherwise use the release tag, and if neither is available, use 'latest' labels: ${{ steps.meta.outputs.labels }} @@ -128,7 +134,7 @@ jobs: - name: Build and push Database Docker image uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 with: - context: https://github.com/BerriAI/litellm.git#${{ github.event.inputs.commit_hash}} + context: . file: Dockerfile.database push: true tags: ${{ steps.meta-database.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, ${{ steps.meta-database.outputs.tags }}-${{ github.event.inputs.release_type }} @@ -165,7 +171,7 @@ jobs: - name: Build and push Database Docker image uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 with: - context: https://github.com/BerriAI/litellm.git#${{ github.event.inputs.commit_hash}} + context: . file: ./litellm-js/spend-logs/Dockerfile push: true tags: ${{ steps.meta-spend-logs.outputs.tags }}-${{ github.event.inputs.tag || 'latest' }}, ${{ steps.meta-spend-logs.outputs.tags }}-${{ github.event.inputs.release_type }} From a55d690d894090b752158b8ec7961aea857adaf3 Mon Sep 17 00:00:00 2001 From: Bram van Meurs <7422223+bcvanmeurs@users.noreply.github.com> Date: Thu, 18 Apr 2024 19:37:55 +0100 Subject: [PATCH 02/83] add commit hash ref --- .github/workflows/ghcr_deploy.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/ghcr_deploy.yml b/.github/workflows/ghcr_deploy.yml index 872c033cf5..4045056e3a 100644 --- a/.github/workflows/ghcr_deploy.yml +++ b/.github/workflows/ghcr_deploy.yml @@ -28,6 +28,8 @@ jobs: - name: Checkout uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.commit_hash }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -74,6 +76,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.commit_hash }} # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. - name: Log in to the Container registry uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 @@ -112,6 +116,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.commit_hash }} - name: Log in to the Container registry uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 @@ -149,6 +155,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.commit_hash }} - name: Log in to the Container registry uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 @@ -182,6 +190,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.commit_hash }} - name: Log in to the Container registry uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 From 8838c8af66efdd1cb676e436799087dce9da862e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 20:32:08 +0000 Subject: [PATCH 03/83] build(deps): bump azure-identity from 1.15.0 to 1.16.1 Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-python) from 1.15.0 to 1.16.1. - [Release notes](https://github.com/Azure/azure-sdk-for-python/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/esrp_release.md) - [Commits](https://github.com/Azure/azure-sdk-for-python/compare/azure-identity_1.15.0...azure-identity_1.16.1) --- updated-dependencies: - dependency-name: azure-identity dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 755e9ec90d..27af79a86d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,7 +27,7 @@ pyjwt[crypto]==2.8.0 python-multipart==0.0.9 # admin UI Pillow==10.3.0 azure-ai-contentsafety==1.0.0 # for azure content safety -azure-identity==1.15.0 # for azure content safety +azure-identity==1.16.1 # for azure content safety opentelemetry-api==1.25.0 opentelemetry-sdk==1.25.0 opentelemetry-exporter-otlp==1.25.0 From 1a847ec47c2a259a0b769837336cadb4c5a8e0bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 20:37:41 +0000 Subject: [PATCH 04/83] build(deps): bump braces from 3.0.2 to 3.0.3 in /ui/litellm-dashboard Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] --- ui/litellm-dashboard/package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ui/litellm-dashboard/package-lock.json b/ui/litellm-dashboard/package-lock.json index 80efdd2cfc..100478a210 100644 --- a/ui/litellm-dashboard/package-lock.json +++ b/ui/litellm-dashboard/package-lock.json @@ -1550,11 +1550,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2862,9 +2862,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, From ffea0a2aed20982c65f36513455834c748484b96 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Wed, 12 Jun 2024 10:40:31 -0700 Subject: [PATCH 05/83] build(pyproject.toml): require pydantic v2 https://github.com/BerriAI/litellm/pull/3670 moved to pydantic v2. This created issues for people using sdk with pydantic v1. Move to requiring pydantic v2 --- pyproject.toml | 1 + requirements.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8ce9c280a1..4f718a9ed3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ click = "*" jinja2 = "^3.1.2" aiohttp = "*" requests = "^2.31.0" +pydantic = "^2.0.0" uvicorn = {version = "^0.22.0", optional = true} gunicorn = {version = "^22.0.0", optional = true} diff --git a/requirements.txt b/requirements.txt index 07dc7e347c..4b4ba17a44 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,5 +43,5 @@ certifi==2023.7.22 # [TODO] clean up aiohttp==3.9.0 # for network calls aioboto3==12.3.0 # for async sagemaker calls tenacity==8.2.3 # for retrying requests, when litellm.num_retries set -pydantic==2.7.1 # openai req. +pydantic==2.7.1 # proxy + openai req. #### \ No newline at end of file From a0ecc6f414cfda5d748fc3f97d6d426d63057ca8 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 08:41:12 -0700 Subject: [PATCH 06/83] fix - send alert on router level exceptions --- litellm/integrations/slack_alerting.py | 2 +- litellm/router.py | 11 ++++++ litellm/router_utils/handle_error.py | 47 ++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 litellm/router_utils/handle_error.py diff --git a/litellm/integrations/slack_alerting.py b/litellm/integrations/slack_alerting.py index 21415fb6d6..f37f5070f4 100644 --- a/litellm/integrations/slack_alerting.py +++ b/litellm/integrations/slack_alerting.py @@ -1453,7 +1453,7 @@ Model Info: pass else: verbose_proxy_logger.debug( - "Error sending slack alert. Error=", response.text + "Error sending slack alert. Error={}".format(response.text) ) async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): diff --git a/litellm/router.py b/litellm/router.py index 4d7a36a386..f07a82d8bd 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -66,6 +66,7 @@ from litellm.types.llms.openai import ( ) from litellm.scheduler import Scheduler, FlowItem from typing import Iterable +from litellm.router_utils.handle_error import send_llm_exception_alert class Router: @@ -576,6 +577,14 @@ class Router: return response except Exception as e: + asyncio.create_task( + send_llm_exception_alert( + litellm_router_instance=self, + request_kwargs=kwargs, + error_traceback_str=traceback.format_exc(), + original_exception=e, + ) + ) raise e async def _acompletion( @@ -4570,6 +4579,8 @@ class Router: default_webhook_url=router_alerting_config.webhook_url, ) + self.slack_alerting_logger = _slack_alerting_logger + litellm.callbacks.append(_slack_alerting_logger) litellm.success_callback.append( _slack_alerting_logger.response_taking_too_long_callback diff --git a/litellm/router_utils/handle_error.py b/litellm/router_utils/handle_error.py new file mode 100644 index 0000000000..e9fb2d390d --- /dev/null +++ b/litellm/router_utils/handle_error.py @@ -0,0 +1,47 @@ +import asyncio +import traceback +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from litellm.router import Router as _Router + + LitellmRouter = _Router +else: + LitellmRouter = Any + + +async def send_llm_exception_alert( + litellm_router_instance: LitellmRouter, + request_kwargs: dict, + error_traceback_str: str, + original_exception, +): + """ + Sends a Slack / MS Teams alert for the LLM API call failure. + + Parameters: + litellm_router_instance (_Router): The LitellmRouter instance. + original_exception (Any): The original exception that occurred. + + Returns: + None + """ + if litellm_router_instance.slack_alerting_logger is None: + return + + if "proxy_server_request" in request_kwargs: + # Do not send any alert if it's a request from litellm proxy server request + # the proxy is already instrumented to send LLM API call failures + return + + litellm_debug_info = getattr(original_exception, "litellm_debug_info", None) + exception_str = str(original_exception) + if litellm_debug_info is not None: + exception_str += litellm_debug_info + exception_str += f"\n\n{error_traceback_str[:2000]}" + + await litellm_router_instance.slack_alerting_logger.send_alert( + message=f"LLM API call failed: `{exception_str}`", + level="High", + alert_type="llm_exceptions", + ) From 63ddc3d0128db7bc0d4d1fd53fa68b48e802a660 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 08:45:04 -0700 Subject: [PATCH 07/83] test_alerting --- litellm/tests/test_alerting.py | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/litellm/tests/test_alerting.py b/litellm/tests/test_alerting.py index 9dfec3dcfa..0cbf6cb6d3 100644 --- a/litellm/tests/test_alerting.py +++ b/litellm/tests/test_alerting.py @@ -25,6 +25,9 @@ import pytest from litellm.router import AlertingConfig, Router from litellm.proxy._types import CallInfo from openai import APIError +from litellm.router import AlertingConfig +import litellm +import os @pytest.mark.parametrize( @@ -743,3 +746,37 @@ async def test_region_outage_alerting_called( mock_send_alert.assert_called_once() else: mock_send_alert.assert_not_called() + + +@pytest.mark.asyncio +@pytest.mark.skip(reason="test only needs to run locally ") +async def test_alerting(): + router = litellm.Router( + model_list=[ + { + "model_name": "gpt-3.5-turbo", + "litellm_params": { + "model": "gpt-3.5-turbo", + "api_key": "bad_key", + }, + } + ], + debug_level="DEBUG", + set_verbose=True, + alerting_config=AlertingConfig( + alerting_threshold=10, # threshold for slow / hanging llm responses (in seconds). Defaults to 300 seconds + webhook_url=os.getenv( + "SLACK_WEBHOOK_URL" + ), # webhook you want to send alerts to + ), + ) + try: + await router.acompletion( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hey, how's it going?"}], + ) + + except: + pass + finally: + await asyncio.sleep(3) From bd5d1be1f6f53a703e8d4c0911b4a1d87a3cb47d Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 10:11:24 -0700 Subject: [PATCH 08/83] feat - send llm exception alert on acompletion, aembedding etc --- litellm/router.py | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/litellm/router.py b/litellm/router.py index f07a82d8bd..491a34d1f1 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -1106,6 +1106,14 @@ class Router: return response except Exception as e: + asyncio.create_task( + send_llm_exception_alert( + litellm_router_instance=self, + request_kwargs=kwargs, + error_traceback_str=traceback.format_exc(), + original_exception=e, + ) + ) raise e async def _aimage_generation(self, prompt: str, model: str, **kwargs): @@ -1230,6 +1238,14 @@ class Router: return response except Exception as e: + asyncio.create_task( + send_llm_exception_alert( + litellm_router_instance=self, + request_kwargs=kwargs, + error_traceback_str=traceback.format_exc(), + original_exception=e, + ) + ) raise e async def _atranscription(self, file: BinaryIO, model: str, **kwargs): @@ -1396,6 +1412,14 @@ class Router: return response except Exception as e: + asyncio.create_task( + send_llm_exception_alert( + litellm_router_instance=self, + request_kwargs=kwargs, + error_traceback_str=traceback.format_exc(), + original_exception=e, + ) + ) raise e async def amoderation(self, model: str, input: str, **kwargs): @@ -1411,6 +1435,14 @@ class Router: return response except Exception as e: + asyncio.create_task( + send_llm_exception_alert( + litellm_router_instance=self, + request_kwargs=kwargs, + error_traceback_str=traceback.format_exc(), + original_exception=e, + ) + ) raise e async def _amoderation(self, model: str, input: str, **kwargs): @@ -1555,6 +1587,14 @@ class Router: return response except Exception as e: + asyncio.create_task( + send_llm_exception_alert( + litellm_router_instance=self, + request_kwargs=kwargs, + error_traceback_str=traceback.format_exc(), + original_exception=e, + ) + ) raise e async def _atext_completion(self, model: str, prompt: str, **kwargs): @@ -1750,6 +1790,14 @@ class Router: response = await self.async_function_with_fallbacks(**kwargs) return response except Exception as e: + asyncio.create_task( + send_llm_exception_alert( + litellm_router_instance=self, + request_kwargs=kwargs, + error_traceback_str=traceback.format_exc(), + original_exception=e, + ) + ) raise e async def _aembedding(self, input: Union[str, List], model: str, **kwargs): From e736e4952e1b6bad4c4454ecc576c1141ca357fc Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 10:21:06 -0700 Subject: [PATCH 09/83] ui - fix team based usage crashing --- ui/litellm-dashboard/src/components/usage.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ui/litellm-dashboard/src/components/usage.tsx b/ui/litellm-dashboard/src/components/usage.tsx index ad1aa0e574..1ac91dd109 100644 --- a/ui/litellm-dashboard/src/components/usage.tsx +++ b/ui/litellm-dashboard/src/components/usage.tsx @@ -667,9 +667,7 @@ const UsagePage: React.FC = ({ showLegend={true} index="date" categories={uniqueTeamIds} - yAxisWidth={80} - colors={["blue", "green", "yellow", "red", "purple"]} - + yAxisWidth={80} stack={true} /> From d8acda9f39d71116d52d987d35a9fe0dd6cece58 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 14 Jun 2024 14:39:36 -0700 Subject: [PATCH 10/83] fix(proxy/utils.py): fix reset monthly budget fix to reset at the same time each month (not at start of month) --- docs/my-website/docs/proxy/team_budgets.md | 2 +- litellm/proxy/utils.py | 36 +++++++++++++++++++--- litellm/tests/test_utils.py | 36 +++++++++++++++++----- 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/docs/my-website/docs/proxy/team_budgets.md b/docs/my-website/docs/proxy/team_budgets.md index 9e897d507e..54f5efddff 100644 --- a/docs/my-website/docs/proxy/team_budgets.md +++ b/docs/my-website/docs/proxy/team_budgets.md @@ -46,7 +46,7 @@ Possible values for `budget_duration` | `budget_duration="1m"` | every 1 min | | `budget_duration="1h"` | every 1 hour | | `budget_duration="1d"` | every 1 day | -| `budget_duration="1mo"` | start of every month | +| `budget_duration="1mo"` | every 1 month | ### 2. Create a key for the `team` diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index e40440ee35..ebe30789d7 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -2115,6 +2115,16 @@ def _extract_from_regex(duration: str) -> Tuple[int, str]: return value, unit +def get_last_day_of_month(year, month): + # Handle December case + if month == 12: + return 31 + # Next month is January, so subtract a day from March 1st + next_month = datetime(year=year, month=month + 1, day=1) + last_day_of_month = (next_month - timedelta(days=1)).day + return last_day_of_month + + def _duration_in_seconds(duration: str) -> int: """ Parameters: @@ -2141,13 +2151,29 @@ def _duration_in_seconds(duration: str) -> int: now = time.time() current_time = datetime.fromtimestamp(now) - # Calculate the first day of the next month if current_time.month == 12: - next_month = datetime(year=current_time.year + 1, month=1, day=1) + target_year = current_time.year + 1 + target_month = 1 else: - next_month = datetime( - year=current_time.year, month=current_time.month + value, day=1 - ) + target_year = current_time.year + target_month = current_time.month + value + + # Determine the day to set for next month + target_day = current_time.day + last_day_of_target_month = get_last_day_of_month(target_year, target_month) + + if target_day > last_day_of_target_month: + target_day = last_day_of_target_month + + next_month = datetime( + year=target_year, + month=target_month, + day=target_day, + hour=current_time.hour, + minute=current_time.minute, + second=current_time.second, + microsecond=current_time.microsecond, + ) # Calculate the duration until the first day of the next month duration_until_next_month = next_month - current_time diff --git a/litellm/tests/test_utils.py b/litellm/tests/test_utils.py index 742199c7f9..7d581a0fb0 100644 --- a/litellm/tests/test_utils.py +++ b/litellm/tests/test_utils.py @@ -26,7 +26,11 @@ from litellm.utils import ( get_max_tokens, get_supported_openai_params, ) -from litellm.proxy.utils import _duration_in_seconds, _extract_from_regex +from litellm.proxy.utils import ( + _duration_in_seconds, + _extract_from_regex, + get_last_day_of_month, +) # Assuming your trim_messages, shorten_message_to_fit_limit, and get_token_count functions are all in a module named 'message_utils' @@ -467,15 +471,31 @@ def test_duration_in_seconds(): now = time.time() current_time = datetime.fromtimestamp(now) - print("current_time={}".format(current_time)) - # Calculate the first day of the next month + if current_time.month == 12: - next_month = datetime(year=current_time.year + 1, month=1, day=1) + target_year = current_time.year + 1 + target_month = 1 else: - next_month = datetime( - year=current_time.year, month=current_time.month + 1, day=1 - ) - print("next_month={}".format(next_month)) + target_year = current_time.year + target_month = current_time.month + 1 + + # Determine the day to set for next month + target_day = current_time.day + last_day_of_target_month = get_last_day_of_month(target_year, target_month) + + if target_day > last_day_of_target_month: + target_day = last_day_of_target_month + + next_month = datetime( + year=target_year, + month=target_month, + day=target_day, + hour=current_time.hour, + minute=current_time.minute, + second=current_time.second, + microsecond=current_time.microsecond, + ) + # Calculate the duration until the first day of the next month duration_until_next_month = next_month - current_time expected_duration = int(duration_until_next_month.total_seconds()) From ab3ece37c07a6fc75da823aeaca0ac987c4ac87b Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 14 Jun 2024 14:46:23 -0700 Subject: [PATCH 11/83] docs(users.md): update user docs to show reset budget --- docs/my-website/docs/proxy/users.md | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/docs/my-website/docs/proxy/users.md b/docs/my-website/docs/proxy/users.md index 77fbcb4448..dca9f190e1 100644 --- a/docs/my-website/docs/proxy/users.md +++ b/docs/my-website/docs/proxy/users.md @@ -413,6 +413,52 @@ curl 'http://0.0.0.0:4000/key/generate' \ +### Reset Budgets + +Reset budgets across keys/internal users/teams/customers + +`budget_duration`: Budget is reset at the end of specified duration. If not set, budget is never reset. You can set duration as seconds ("30s"), minutes ("30m"), hours ("30h"), days ("30d"). + + + + +```bash +curl 'http://0.0.0.0:4000/user/new' \ +--header 'Authorization: Bearer ' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "max_budget": 10, + "budget_duration": 10s, # šŸ‘ˆ KEY CHANGE +}' +``` + + + +```bash +curl 'http://0.0.0.0:4000/key/generate' \ +--header 'Authorization: Bearer ' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "max_budget": 10, + "budget_duration": 10s, # šŸ‘ˆ KEY CHANGE +}' +``` + + + + +```bash +curl 'http://0.0.0.0:4000/team/new' \ +--header 'Authorization: Bearer ' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "max_budget": 10, + "budget_duration": 10s, # šŸ‘ˆ KEY CHANGE +}' +``` + + + ## Set Rate Limits You can set: From 2732ff5d56f617c2bec9ec85f54fd4e733aebad8 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 14 Jun 2024 15:08:01 -0700 Subject: [PATCH 12/83] fix(utils.py): return traceback on unmapped exception error Fixes https://github.com/BerriAI/litellm/issues/4201 --- litellm/proxy/_experimental/out/404.html | 1 - .../proxy/_experimental/out/model_hub.html | 1 - .../proxy/_experimental/out/onboarding.html | 1 - litellm/utils.py | 19 ++++++++++++++++--- 4 files changed, 16 insertions(+), 6 deletions(-) delete mode 100644 litellm/proxy/_experimental/out/404.html delete mode 100644 litellm/proxy/_experimental/out/model_hub.html delete mode 100644 litellm/proxy/_experimental/out/onboarding.html diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html deleted file mode 100644 index f2e61a560d..0000000000 --- a/litellm/proxy/_experimental/out/404.html +++ /dev/null @@ -1 +0,0 @@ -404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/model_hub.html b/litellm/proxy/_experimental/out/model_hub.html deleted file mode 100644 index 8d95f44aab..0000000000 --- a/litellm/proxy/_experimental/out/model_hub.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/onboarding.html b/litellm/proxy/_experimental/out/onboarding.html deleted file mode 100644 index 7b6369ece0..0000000000 --- a/litellm/proxy/_experimental/out/onboarding.html +++ /dev/null @@ -1 +0,0 @@ -LiteLLM Dashboard \ No newline at end of file diff --git a/litellm/utils.py b/litellm/utils.py index aaf2c1b945..830c45610b 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -8420,7 +8420,7 @@ def exception_type( extra_information = _add_key_name_and_team_to_alert( request_info=extra_information, metadata=_metadata ) - except: + except Exception: # DO NOT LET this Block raising the original exception pass @@ -9956,6 +9956,9 @@ def exception_type( response=original_exception.response, ) else: # ensure generic errors always return APIConnectionError= + """ + For unmapped exceptions - raise the exception with traceback - https://github.com/BerriAI/litellm/issues/4201 + """ exception_mapping_worked = True if hasattr(original_exception, "request"): raise APIConnectionError( @@ -9966,7 +9969,9 @@ def exception_type( ) else: raise APIConnectionError( - message=f"{str(original_exception)}", + message="{}\n{}".format( + str(original_exception), traceback.format_exc() + ), llm_provider=custom_llm_provider, model=model, request=httpx.Request( @@ -9992,7 +9997,15 @@ def exception_type( if exception_mapping_worked: raise e else: - raise original_exception + raise APIConnectionError( + message="{}\n{}".format(original_exception, traceback.format_exc()), + llm_provider="", + model="", + request=httpx.Request( + method="POST", + url="https://www.litellm.ai/", + ), + ) def get_or_generate_uuid(): From 0404d30a9cf989af174b52b111f9946b9dde06f8 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 14 Jun 2024 15:15:53 -0700 Subject: [PATCH 13/83] fix(main.py): include traceback in error string --- litellm/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/litellm/main.py b/litellm/main.py index 31cb8e364f..9d369a4ce9 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -368,7 +368,9 @@ async def acompletion( return response except Exception as e: verbose_logger.error( - "litellm.acompletion(): Exception occured - {}".format(str(e)) + "litellm.acompletion(): Exception occured - {}\n{}".format( + str(e), traceback.format_exc() + ) ) verbose_logger.debug(traceback.format_exc()) custom_llm_provider = custom_llm_provider or "openai" From 2d2650a2b64fc348845108170df9169d24ead097 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 15:17:32 -0700 Subject: [PATCH 14/83] fix use safe access for router alerting --- litellm/router_utils/handle_error.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/litellm/router_utils/handle_error.py b/litellm/router_utils/handle_error.py index e9fb2d390d..d848fd82b1 100644 --- a/litellm/router_utils/handle_error.py +++ b/litellm/router_utils/handle_error.py @@ -26,6 +26,12 @@ async def send_llm_exception_alert( Returns: None """ + if litellm_router_instance is None: + return + + if not hasattr(litellm_router_instance, "slack_alerting_logger"): + return + if litellm_router_instance.slack_alerting_logger is None: return From 6bd7e24fdd538468e99fbcf863206732a4d5fd2a Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 15:54:14 -0700 Subject: [PATCH 15/83] fix - team budget exceeded --- .../common_utils/management_endpoint_utils.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/common_utils/management_endpoint_utils.py b/litellm/proxy/common_utils/management_endpoint_utils.py index 2aa4f9e70a..eca385d079 100644 --- a/litellm/proxy/common_utils/management_endpoint_utils.py +++ b/litellm/proxy/common_utils/management_endpoint_utils.py @@ -26,12 +26,12 @@ def management_endpoint_wrapper(func): user_api_key_dict: UserAPIKeyAuth = ( kwargs.get("user_api_key_dict") or UserAPIKeyAuth() ) + _http_request: Request = kwargs.get("http_request") parent_otel_span = user_api_key_dict.parent_otel_span if parent_otel_span is not None: from litellm.proxy.proxy_server import open_telemetry_logger if open_telemetry_logger is not None: - _http_request: Request = kwargs.get("http_request") if _http_request: _route = _http_request.url.path _request_body: dict = await _read_request_body( @@ -51,6 +51,22 @@ def management_endpoint_wrapper(func): logging_payload=logging_payload, parent_otel_span=parent_otel_span, ) + if _http_request: + _route = _http_request.url.path + # Flush user_api_key cache if this was an update/delete call to /key, /team, or /user + if _route in [ + "/key/update", + "/key/delete", + "/team/update", + "/team/delete", + "/user/update", + "/user/delete", + "/customer/update", + "/customer/delete", + ]: + from litellm.proxy.proxy_server import user_api_key_cache + + user_api_key_cache.flush_cache() return result except Exception as e: From e18002023af4e3c4de6eb10e14042b941351e214 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 14 Jun 2024 16:06:47 -0700 Subject: [PATCH 16/83] fix(slack_alerting.py): allow new 'alerting_metadata' arg Allows user to pass in additional alerting metadata for debugging --- litellm/integrations/slack_alerting.py | 60 +++++++++++++++++++++---- litellm/proxy/_super_secret_config.yaml | 4 +- litellm/proxy/utils.py | 11 ++++- litellm/tests/test_alerting.py | 23 ++++++++++ 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/litellm/integrations/slack_alerting.py b/litellm/integrations/slack_alerting.py index 21415fb6d6..2c558af07b 100644 --- a/litellm/integrations/slack_alerting.py +++ b/litellm/integrations/slack_alerting.py @@ -330,6 +330,7 @@ class SlackAlerting(CustomLogger): messages = "Message not logged. litellm.redact_messages_in_exceptions=True" request_info = f"\nRequest Model: `{model}`\nAPI Base: `{api_base}`\nMessages: `{messages}`" slow_message = f"`Responses are slow - {round(time_difference_float,2)}s response time > Alerting threshold: {self.alerting_threshold}s`" + alerting_metadata: dict = {} if time_difference_float > self.alerting_threshold: # add deployment latencies to alert if ( @@ -337,7 +338,7 @@ class SlackAlerting(CustomLogger): and "litellm_params" in kwargs and "metadata" in kwargs["litellm_params"] ): - _metadata = kwargs["litellm_params"]["metadata"] + _metadata: dict = kwargs["litellm_params"]["metadata"] request_info = litellm.utils._add_key_name_and_team_to_alert( request_info=request_info, metadata=_metadata ) @@ -349,10 +350,14 @@ class SlackAlerting(CustomLogger): request_info += ( f"\nAvailable Deployment Latencies\n{_deployment_latency_map}" ) + + if "alerting_metadata" in _metadata: + alerting_metadata = _metadata["alerting_metadata"] await self.send_alert( message=slow_message + request_info, level="Low", alert_type="llm_too_slow", + alerting_metadata=alerting_metadata, ) async def async_update_daily_reports( @@ -540,7 +545,12 @@ class SlackAlerting(CustomLogger): message += f"\n\nNext Run is at: `{time.time() + self.alerting_args.daily_report_frequency}`s" # send alert - await self.send_alert(message=message, level="Low", alert_type="daily_reports") + await self.send_alert( + message=message, + level="Low", + alert_type="daily_reports", + alerting_metadata={}, + ) return True @@ -582,6 +592,7 @@ class SlackAlerting(CustomLogger): await asyncio.sleep( self.alerting_threshold ) # Set it to 5 minutes - i'd imagine this might be different for streaming, non-streaming, non-completion (embedding + img) requests + alerting_metadata: dict = {} if ( request_data is not None and request_data.get("litellm_status", "") != "success" @@ -606,7 +617,7 @@ class SlackAlerting(CustomLogger): ): # In hanging requests sometime it has not made it to the point where the deployment is passed to the `request_data`` # in that case we fallback to the api base set in the request metadata - _metadata = request_data["metadata"] + _metadata: dict = request_data["metadata"] _api_base = _metadata.get("api_base", "") request_info = litellm.utils._add_key_name_and_team_to_alert( @@ -615,6 +626,9 @@ class SlackAlerting(CustomLogger): if _api_base is None: _api_base = "" + + if "alerting_metadata" in _metadata: + alerting_metadata = _metadata["alerting_metadata"] request_info += f"\nAPI Base: `{_api_base}`" # only alert hanging responses if they have not been marked as success alerting_message = ( @@ -640,6 +654,7 @@ class SlackAlerting(CustomLogger): message=alerting_message + request_info, level="Medium", alert_type="llm_requests_hanging", + alerting_metadata=alerting_metadata, ) async def failed_tracking_alert(self, error_message: str): @@ -650,7 +665,10 @@ class SlackAlerting(CustomLogger): result = await _cache.async_get_cache(key=_cache_key) if result is None: await self.send_alert( - message=message, level="High", alert_type="budget_alerts" + message=message, + level="High", + alert_type="budget_alerts", + alerting_metadata={}, ) await _cache.async_set_cache( key=_cache_key, @@ -751,6 +769,7 @@ class SlackAlerting(CustomLogger): level="High", alert_type="budget_alerts", user_info=webhook_event, + alerting_metadata={}, ) await _cache.async_set_cache( key=_cache_key, @@ -941,7 +960,10 @@ class SlackAlerting(CustomLogger): ) # send minor alert await self.send_alert( - message=msg, level="Medium", alert_type="outage_alerts" + message=msg, + level="Medium", + alert_type="outage_alerts", + alerting_metadata={}, ) # set to true outage_value["minor_alert_sent"] = True @@ -963,7 +985,12 @@ class SlackAlerting(CustomLogger): ) # send minor alert - await self.send_alert(message=msg, level="High", alert_type="outage_alerts") + await self.send_alert( + message=msg, + level="High", + alert_type="outage_alerts", + alerting_metadata={}, + ) # set to true outage_value["major_alert_sent"] = True @@ -1062,7 +1089,10 @@ class SlackAlerting(CustomLogger): ) # send minor alert await self.send_alert( - message=msg, level="Medium", alert_type="outage_alerts" + message=msg, + level="Medium", + alert_type="outage_alerts", + alerting_metadata={}, ) # set to true outage_value["minor_alert_sent"] = True @@ -1081,7 +1111,10 @@ class SlackAlerting(CustomLogger): ) # send minor alert await self.send_alert( - message=msg, level="High", alert_type="outage_alerts" + message=msg, + level="High", + alert_type="outage_alerts", + alerting_metadata={}, ) # set to true outage_value["major_alert_sent"] = True @@ -1143,7 +1176,10 @@ Model Info: """ alert_val = self.send_alert( - message=message, level="Low", alert_type="new_model_added" + message=message, + level="Low", + alert_type="new_model_added", + alerting_metadata={}, ) if alert_val is not None and asyncio.iscoroutine(alert_val): @@ -1368,6 +1404,7 @@ Model Info: message: str, level: Literal["Low", "Medium", "High"], alert_type: Literal[AlertType], + alerting_metadata: dict, user_info: Optional[WebhookEvent] = None, **kwargs, ): @@ -1425,6 +1462,9 @@ Model Info: if kwargs: for key, value in kwargs.items(): formatted_message += f"\n\n{key}: `{value}`\n\n" + if alerting_metadata: + for key, value in alerting_metadata.items(): + formatted_message += f"\n\n*Alerting Metadata*: \n{key}: `{value}`\n\n" if _proxy_base_url is not None: formatted_message += f"\n\nProxy URL: `{_proxy_base_url}`" @@ -1622,6 +1662,7 @@ Model Info: message=_weekly_spend_message, level="Low", alert_type="spend_reports", + alerting_metadata={}, ) except Exception as e: verbose_proxy_logger.error("Error sending weekly spend report", e) @@ -1673,6 +1714,7 @@ Model Info: message=_spend_message, level="Low", alert_type="spend_reports", + alerting_metadata={}, ) except Exception as e: verbose_proxy_logger.error("Error sending weekly spend report", e) diff --git a/litellm/proxy/_super_secret_config.yaml b/litellm/proxy/_super_secret_config.yaml index 5504d7a61c..15b8bc93e6 100644 --- a/litellm/proxy/_super_secret_config.yaml +++ b/litellm/proxy/_super_secret_config.yaml @@ -79,8 +79,8 @@ litellm_settings: failure_callback: ["langfuse"] cache: true -# general_settings: -# alerting: ["email"] +general_settings: + alerting: ["slack"] # key_management_system: "aws_kms" # key_management_settings: # hosted_keys: ["LITELLM_MASTER_KEY"] diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index ebe30789d7..7741e5382a 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -455,6 +455,7 @@ class ProxyLogging: formatted_message += f"\n\nProxy URL: `{_proxy_base_url}`" extra_kwargs = {} + alerting_metadata = {} if request_data is not None: _url = self.slack_alerting_instance._add_langfuse_trace_id_to_alert( request_data=request_data @@ -462,7 +463,12 @@ class ProxyLogging: if _url is not None: extra_kwargs["🪢 Langfuse Trace"] = _url formatted_message += "\n\n🪢 Langfuse Trace: {}".format(_url) - + if ( + "metadata" in request_data + and request_data["metadata"].get("alerting_metadata", None) is not None + and isinstance(request_data["metadata"]["alerting_metadata"], dict) + ): + alerting_metadata = request_data["metadata"]["alerting_metadata"] for client in self.alerting: if client == "slack": await self.slack_alerting_instance.send_alert( @@ -470,6 +476,7 @@ class ProxyLogging: level=level, alert_type=alert_type, user_info=None, + alerting_metadata=alerting_metadata, **extra_kwargs, ) elif client == "sentry": @@ -510,7 +517,7 @@ class ProxyLogging: ) if hasattr(self, "service_logging_obj"): - self.service_logging_obj.async_service_failure_hook( + await self.service_logging_obj.async_service_failure_hook( service=ServiceTypes.DB, duration=duration, error=error_message, diff --git a/litellm/tests/test_alerting.py b/litellm/tests/test_alerting.py index 9dfec3dcfa..47d9ddefc8 100644 --- a/litellm/tests/test_alerting.py +++ b/litellm/tests/test_alerting.py @@ -159,6 +159,29 @@ async def test_response_taking_too_long_callback(slack_alerting): mock_send_alert.assert_awaited_once() +@pytest.mark.asyncio +async def test_alerting_metadata(slack_alerting): + """ + Test alerting_metadata is propogated correctly for response taking too long + """ + start_time = datetime.now() + end_time = start_time + timedelta(seconds=301) + kwargs = { + "model": "test_model", + "messages": "test_messages", + "litellm_params": {"metadata": {"alerting_metadata": {"hello": "world"}}}, + } + with patch.object(slack_alerting, "send_alert", new=AsyncMock()) as mock_send_alert: + + ## RESPONSE TAKING TOO LONG + await slack_alerting.response_taking_too_long_callback( + kwargs, None, start_time, end_time + ) + mock_send_alert.assert_awaited_once() + + assert "hello" in mock_send_alert.call_args[1]["alerting_metadata"] + + # Test for budget crossed @pytest.mark.asyncio async def test_budget_alerts_crossed(slack_alerting): From 9e8eacbc77a288dede4f0976c245cf73a37025e7 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 14 Jun 2024 16:20:54 -0700 Subject: [PATCH 17/83] test(test_alerting.py): fix tests --- litellm/tests/test_alerting.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/litellm/tests/test_alerting.py b/litellm/tests/test_alerting.py index 47d9ddefc8..ef2ed40c3d 100644 --- a/litellm/tests/test_alerting.py +++ b/litellm/tests/test_alerting.py @@ -227,7 +227,9 @@ async def test_send_alert(slack_alerting): slack_alerting.async_http_handler, "post", new=AsyncMock() ) as mock_post: mock_post.return_value.status_code = 200 - await slack_alerting.send_alert("Test message", "Low", "budget_alerts") + await slack_alerting.send_alert( + "Test message", "Low", "budget_alerts", alerting_metadata={} + ) mock_post.assert_awaited_once() @@ -286,7 +288,7 @@ async def test_daily_reports_completion(slack_alerting): await asyncio.sleep(3) response_val = await slack_alerting.send_daily_reports(router=router) - assert response_val == True + assert response_val is True mock_send_alert.assert_awaited_once() @@ -311,7 +313,7 @@ async def test_daily_reports_completion(slack_alerting): await asyncio.sleep(3) response_val = await slack_alerting.send_daily_reports(router=router) - assert response_val == True + assert response_val is True mock_send_alert.assert_awaited() From 75d5609705798868275e5f9ec0412c3496e2ebf6 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 17:00:43 -0700 Subject: [PATCH 18/83] send team_alias on team budget alerts --- litellm/proxy/proxy_server.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 901267d929..fe2401596e 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -1269,6 +1269,8 @@ async def user_api_key_auth( spend=valid_token.team_spend, max_budget=valid_token.team_max_budget, user_id=valid_token.user_id, + team_id=valid_token.team_id, + team_alias=valid_token.team_alias, ) asyncio.create_task( proxy_logging_obj.budget_alerts( From b31c084b5372a712dc1c051b8d0cd17aaa7aa7a4 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 17:05:59 -0700 Subject: [PATCH 19/83] add team_alias in alerting info --- litellm/proxy/_types.py | 1 + 1 file changed, 1 insertion(+) diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index ccc8ed3479..7d272933dd 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -1362,6 +1362,7 @@ class CallInfo(LiteLLMBase): customer_id: Optional[str] = None user_id: Optional[str] = None team_id: Optional[str] = None + team_alias: Optional[str] = None user_email: Optional[str] = None key_alias: Optional[str] = None projected_exceeded_date: Optional[str] = None From 6f715b4782d43e26468e13da4fa236abb148003a Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 14 Jun 2024 17:15:44 -0700 Subject: [PATCH 20/83] feat(router.py): support content policy fallbacks Closes https://github.com/BerriAI/litellm/issues/2632 --- litellm/__init__.py | 1 + litellm/exceptions.py | 12 ++- litellm/main.py | 4 +- litellm/router.py | 105 ++++++++++++++++++++++++- litellm/tests/test_router_fallbacks.py | 56 +++++++++++++ litellm/utils.py | 52 ++++++------ 6 files changed, 197 insertions(+), 33 deletions(-) diff --git a/litellm/__init__.py b/litellm/__init__.py index 15f562d159..6ecf70d0d7 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -240,6 +240,7 @@ num_retries: Optional[int] = None # per model endpoint default_fallbacks: Optional[List] = None fallbacks: Optional[List] = None context_window_fallbacks: Optional[List] = None +content_policy_fallbacks: Optional[List] = None allowed_fails: int = 0 num_retries_per_request: Optional[int] = ( None # for the request overall (incl. fallbacks + model retries) diff --git a/litellm/exceptions.py b/litellm/exceptions.py index 8b102d791b..9674d48b12 100644 --- a/litellm/exceptions.py +++ b/litellm/exceptions.py @@ -324,7 +324,7 @@ class ContextWindowExceededError(BadRequestError): # type: ignore message, model, llm_provider, - response: httpx.Response, + response: Optional[httpx.Response] = None, litellm_debug_info: Optional[str] = None, ): self.status_code = 400 @@ -332,11 +332,13 @@ class ContextWindowExceededError(BadRequestError): # type: ignore self.model = model self.llm_provider = llm_provider self.litellm_debug_info = litellm_debug_info + request = httpx.Request(method="POST", url="https://api.openai.com/v1") + self.response = response or httpx.Response(status_code=400, request=request) super().__init__( message=self.message, model=self.model, # type: ignore llm_provider=self.llm_provider, # type: ignore - response=response, + response=self.response, litellm_debug_info=self.litellm_debug_info, ) # Call the base class constructor with the parameters it needs @@ -407,7 +409,7 @@ class ContentPolicyViolationError(BadRequestError): # type: ignore message, model, llm_provider, - response: httpx.Response, + response: Optional[httpx.Response] = None, litellm_debug_info: Optional[str] = None, ): self.status_code = 400 @@ -415,11 +417,13 @@ class ContentPolicyViolationError(BadRequestError): # type: ignore self.model = model self.llm_provider = llm_provider self.litellm_debug_info = litellm_debug_info + request = httpx.Request(method="POST", url="https://api.openai.com/v1") + self.response = response or httpx.Response(status_code=500, request=request) super().__init__( message=self.message, model=self.model, # type: ignore llm_provider=self.llm_provider, # type: ignore - response=response, + response=self.response, litellm_debug_info=self.litellm_debug_info, ) # Call the base class constructor with the parameters it needs diff --git a/litellm/main.py b/litellm/main.py index 9d369a4ce9..77fe38fd2d 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -401,6 +401,7 @@ def mock_completion( stream: Optional[bool] = False, mock_response: Union[str, Exception] = "This is a mock request", logging=None, + custom_llm_provider=None, **kwargs, ): """ @@ -438,7 +439,7 @@ def mock_completion( raise litellm.APIError( status_code=getattr(mock_response, "status_code", 500), # type: ignore message=getattr(mock_response, "text", str(mock_response)), - llm_provider=getattr(mock_response, "llm_provider", "openai"), # type: ignore + llm_provider=getattr(mock_response, "llm_provider", custom_llm_provider or "openai"), # type: ignore model=model, # type: ignore request=httpx.Request(method="POST", url="https://api.openai.com/v1/"), ) @@ -907,6 +908,7 @@ def completion( logging=logging, acompletion=acompletion, mock_delay=kwargs.get("mock_delay", None), + custom_llm_provider=custom_llm_provider, ) if custom_llm_provider == "azure": # azure configs diff --git a/litellm/router.py b/litellm/router.py index 4d7a36a386..b8844fd336 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -108,6 +108,7 @@ class Router: ] = None, # generic fallbacks, works across all deployments fallbacks: List = [], context_window_fallbacks: List = [], + content_policy_fallbacks: List = [], model_group_alias: Optional[dict] = {}, enable_pre_call_checks: bool = False, retry_after: int = 0, # min time to wait before retrying a failed request @@ -311,6 +312,12 @@ class Router: self.context_window_fallbacks = ( context_window_fallbacks or litellm.context_window_fallbacks ) + + _content_policy_fallbacks = ( + content_policy_fallbacks or litellm.content_policy_fallbacks + ) + self.validate_fallbacks(fallback_param=_content_policy_fallbacks) + self.content_policy_fallbacks = _content_policy_fallbacks self.total_calls: defaultdict = defaultdict( int ) # dict to store total calls made to each model @@ -1998,6 +2005,9 @@ class Router: context_window_fallbacks = kwargs.get( "context_window_fallbacks", self.context_window_fallbacks ) + content_policy_fallbacks = kwargs.get( + "content_policy_fallbacks", self.content_policy_fallbacks + ) try: if mock_testing_fallbacks is not None and mock_testing_fallbacks == True: raise Exception( @@ -2016,7 +2026,10 @@ class Router: if ( hasattr(e, "status_code") and e.status_code == 400 # type: ignore - and not isinstance(e, litellm.ContextWindowExceededError) + and not ( + isinstance(e, litellm.ContextWindowExceededError) + or isinstance(e, litellm.ContentPolicyViolationError) + ) ): # don't retry a malformed request raise e if ( @@ -2034,6 +2047,39 @@ class Router: if fallback_model_group is None: raise original_exception + for mg in fallback_model_group: + """ + Iterate through the model groups and try calling that deployment + """ + try: + kwargs["model"] = mg + kwargs.setdefault("metadata", {}).update( + {"model_group": mg} + ) # update model_group used, if fallbacks are done + response = await self.async_function_with_retries( + *args, **kwargs + ) + verbose_router_logger.info( + "Successful fallback b/w models." + ) + return response + except Exception as e: + pass + elif ( + isinstance(e, litellm.ContentPolicyViolationError) + and content_policy_fallbacks is not None + ): + fallback_model_group = None + for ( + item + ) in content_policy_fallbacks: # [{"gpt-3.5-turbo": ["gpt-4"]}] + if list(item.keys())[0] == model_group: + fallback_model_group = item[model_group] + break + + if fallback_model_group is None: + raise original_exception + for mg in fallback_model_group: """ Iterate through the model groups and try calling that deployment @@ -2114,6 +2160,9 @@ class Router: context_window_fallbacks = kwargs.pop( "context_window_fallbacks", self.context_window_fallbacks ) + content_policy_fallbacks = kwargs.pop( + "content_policy_fallbacks", self.content_policy_fallbacks + ) num_retries = kwargs.pop("num_retries") @@ -2141,6 +2190,7 @@ class Router: healthy_deployments=_healthy_deployments, context_window_fallbacks=context_window_fallbacks, regular_fallbacks=fallbacks, + content_policy_fallbacks=content_policy_fallbacks, ) # decides how long to sleep before retry @@ -2206,10 +2256,12 @@ class Router: error: Exception, healthy_deployments: Optional[List] = None, context_window_fallbacks: Optional[List] = None, + content_policy_fallbacks: Optional[List] = None, regular_fallbacks: Optional[List] = None, ): """ 1. raise an exception for ContextWindowExceededError if context_window_fallbacks is not None + 2. raise an exception for ContentPolicyViolationError if content_policy_fallbacks is not None 2. raise an exception for RateLimitError if - there are no fallbacks @@ -2219,13 +2271,19 @@ class Router: if healthy_deployments is not None and isinstance(healthy_deployments, list): _num_healthy_deployments = len(healthy_deployments) - ### CHECK IF RATE LIMIT / CONTEXT WINDOW ERROR w/ fallbacks available / Bad Request Error + ### CHECK IF RATE LIMIT / CONTEXT WINDOW ERROR / CONTENT POLICY VIOLATION ERROR w/ fallbacks available / Bad Request Error if ( isinstance(error, litellm.ContextWindowExceededError) and context_window_fallbacks is not None ): raise error + if ( + isinstance(error, litellm.ContentPolicyViolationError) + and content_policy_fallbacks is not None + ): + raise error + # Error we should only retry if there are other deployments if isinstance(error, openai.RateLimitError): if ( @@ -2256,6 +2314,9 @@ class Router: context_window_fallbacks = kwargs.get( "context_window_fallbacks", self.context_window_fallbacks ) + content_policy_fallbacks = kwargs.get( + "content_policy_fallbacks", self.content_policy_fallbacks + ) try: if mock_testing_fallbacks is not None and mock_testing_fallbacks == True: raise Exception( @@ -2271,7 +2332,10 @@ class Router: if ( hasattr(e, "status_code") and e.status_code == 400 # type: ignore - and not isinstance(e, litellm.ContextWindowExceededError) + and not ( + isinstance(e, litellm.ContextWindowExceededError) + or isinstance(e, litellm.ContentPolicyViolationError) + ) ): # don't retry a malformed request raise e @@ -2294,6 +2358,37 @@ class Router: if fallback_model_group is None: raise original_exception + for mg in fallback_model_group: + """ + Iterate through the model groups and try calling that deployment + """ + try: + ## LOGGING + kwargs = self.log_retry(kwargs=kwargs, e=original_exception) + kwargs["model"] = mg + kwargs.setdefault("metadata", {}).update( + {"model_group": mg} + ) # update model_group used, if fallbacks are done + response = self.function_with_fallbacks(*args, **kwargs) + return response + except Exception as e: + pass + elif ( + isinstance(e, litellm.ContentPolicyViolationError) + and content_policy_fallbacks is not None + ): + fallback_model_group = None + + for ( + item + ) in content_policy_fallbacks: # [{"gpt-3.5-turbo": ["gpt-4"]}] + if list(item.keys())[0] == model_group: + fallback_model_group = item[model_group] + break + + if fallback_model_group is None: + raise original_exception + for mg in fallback_model_group: """ Iterate through the model groups and try calling that deployment @@ -2400,6 +2495,9 @@ class Router: context_window_fallbacks = kwargs.pop( "context_window_fallbacks", self.context_window_fallbacks ) + content_policy_fallbacks = kwargs.pop( + "content_policy_fallbacks", self.content_policy_fallbacks + ) try: # if the function call is successful, no exception will be raised and we'll break out of the loop @@ -2419,6 +2517,7 @@ class Router: healthy_deployments=_healthy_deployments, context_window_fallbacks=context_window_fallbacks, regular_fallbacks=fallbacks, + content_policy_fallbacks=content_policy_fallbacks, ) # decides how long to sleep before retry diff --git a/litellm/tests/test_router_fallbacks.py b/litellm/tests/test_router_fallbacks.py index c6e0e54111..545eb23db3 100644 --- a/litellm/tests/test_router_fallbacks.py +++ b/litellm/tests/test_router_fallbacks.py @@ -1109,3 +1109,59 @@ async def test_client_side_fallbacks_list(sync_mode): assert isinstance(response, litellm.ModelResponse) assert response.model is not None and response.model == "gpt-4o" + + +@pytest.mark.parametrize("sync_mode", [True, False]) +@pytest.mark.asyncio +async def test_router_content_policy_fallbacks(sync_mode): + os.environ["LITELLM_LOG"] = "DEBUG" + router = Router( + model_list=[ + { + "model_name": "claude-2", + "litellm_params": { + "model": "claude-2", + "api_key": "", + "mock_response": Exception("content filtering policy"), + }, + }, + { + "model_name": "my-fallback-model", + "litellm_params": { + "model": "claude-2", + "api_key": "", + "mock_response": "This works!", + }, + }, + { + "model_name": "my-general-model", + "litellm_params": { + "model": "claude-2", + "api_key": "", + "mock_response": Exception("Should not have called this."), + }, + }, + { + "model_name": "my-context-window-model", + "litellm_params": { + "model": "claude-2", + "api_key": "", + "mock_response": Exception("Should not have called this."), + }, + }, + ], + content_policy_fallbacks=[{"claude-2": ["my-fallback-model"]}], + fallbacks=[{"claude-2": ["my-general-model"]}], + context_window_fallbacks=[{"claude-2": ["my-context-window-model"]}], + ) + + if sync_mode is True: + response = router.completion( + model="claude-2", + messages=[{"role": "user", "content": "Hey, how's it going?"}], + ) + else: + response = await router.acompletion( + model="claude-2", + messages=[{"role": "user", "content": "Hey, how's it going?"}], + ) diff --git a/litellm/utils.py b/litellm/utils.py index 830c45610b..7f37bcf7c5 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -3436,6 +3436,7 @@ def client(original_function): isinstance(e, litellm.exceptions.ContextWindowExceededError) and context_window_fallback_dict and model in context_window_fallback_dict + and not _is_litellm_router_call ): if len(args) > 0: args[0] = context_window_fallback_dict[model] @@ -8637,32 +8638,33 @@ def exception_type( ), ) elif custom_llm_provider == "anthropic": # one of the anthropics - if hasattr(original_exception, "message"): - if ( - "prompt is too long" in original_exception.message - or "prompt: length" in original_exception.message - ): - exception_mapping_worked = True - raise ContextWindowExceededError( - message=original_exception.message, - model=model, - llm_provider="anthropic", - response=original_exception.response, - ) - if "Invalid API Key" in original_exception.message: - exception_mapping_worked = True - raise AuthenticationError( - message=original_exception.message, - model=model, - llm_provider="anthropic", - response=original_exception.response, - ) + if "prompt is too long" in error_str or "prompt: length" in error_str: + exception_mapping_worked = True + raise ContextWindowExceededError( + message=error_str, + model=model, + llm_provider="anthropic", + ) + if "Invalid API Key" in error_str: + exception_mapping_worked = True + raise AuthenticationError( + message=error_str, + model=model, + llm_provider="anthropic", + ) + if "content filtering policy" in error_str: + exception_mapping_worked = True + raise ContentPolicyViolationError( + message=error_str, + model=model, + llm_provider="anthropic", + ) if hasattr(original_exception, "status_code"): print_verbose(f"status_code: {original_exception.status_code}") if original_exception.status_code == 401: exception_mapping_worked = True raise AuthenticationError( - message=f"AnthropicException - {original_exception.message}", + message=f"AnthropicException - {error_str}", llm_provider="anthropic", model=model, response=original_exception.response, @@ -8673,7 +8675,7 @@ def exception_type( ): exception_mapping_worked = True raise BadRequestError( - message=f"AnthropicException - {original_exception.message}", + message=f"AnthropicException - {error_str}", model=model, llm_provider="anthropic", response=original_exception.response, @@ -8681,14 +8683,14 @@ def exception_type( elif original_exception.status_code == 408: exception_mapping_worked = True raise Timeout( - message=f"AnthropicException - {original_exception.message}", + message=f"AnthropicException - {error_str}", model=model, llm_provider="anthropic", ) elif original_exception.status_code == 429: exception_mapping_worked = True raise RateLimitError( - message=f"AnthropicException - {original_exception.message}", + message=f"AnthropicException - {error_str}", llm_provider="anthropic", model=model, response=original_exception.response, @@ -8697,7 +8699,7 @@ def exception_type( exception_mapping_worked = True raise APIError( status_code=500, - message=f"AnthropicException - {original_exception.message}. Handle with `litellm.APIError`.", + message=f"AnthropicException - {error_str}. Handle with `litellm.APIError`.", llm_provider="anthropic", model=model, request=original_exception.request, From 52b54da35466cb40d57bc975edbd86ae40b231a9 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 17:38:33 -0700 Subject: [PATCH 21/83] fix -better debugging before sending emails --- litellm/proxy/utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index ebe30789d7..a04bd87995 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -1960,6 +1960,9 @@ async def send_email(receiver_email, subject, html): email_message["From"] = sender_email email_message["To"] = receiver_email email_message["Subject"] = subject + verbose_proxy_logger.debug( + "sending email from %s to %s", sender_email, receiver_email + ) # Attach the body to the email email_message.attach(MIMEText(html, "html")) From 84b281bf2a59f5841dc1cdba1dcc5e65f75123da Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 18:36:04 -0700 Subject: [PATCH 22/83] feat - send email alert to team members --- litellm/integrations/email_alerting.py | 136 +++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 litellm/integrations/email_alerting.py diff --git a/litellm/integrations/email_alerting.py b/litellm/integrations/email_alerting.py new file mode 100644 index 0000000000..0a959433e1 --- /dev/null +++ b/litellm/integrations/email_alerting.py @@ -0,0 +1,136 @@ +""" +Functions for sending Email Alerts +""" + +import os +from typing import Optional, List +from litellm.proxy._types import WebhookEvent +import asyncio +from litellm._logging import verbose_logger, verbose_proxy_logger + +# we use this for the email header, please send a test email if you change this. verify it looks good on email +LITELLM_LOGO_URL = "https://litellm-listing.s3.amazonaws.com/litellm_logo.png" +LITELLM_SUPPORT_CONTACT = "support@berri.ai" + + +async def get_all_team_member_emails(team_id: Optional[str] = None) -> list: + verbose_logger.debug( + "Email Alerting: Getting all team members for team_id=%s", team_id + ) + if team_id is None: + return [] + from litellm.proxy.proxy_server import premium_user, prisma_client + + if prisma_client is None: + raise Exception("Not connected to DB!") + + team_row = await prisma_client.db.litellm_teamtable.find_unique( + where={ + "team_id": team_id, + } + ) + + if team_row is None: + return [] + + _team_members = team_row.members_with_roles + verbose_logger.debug( + "Email Alerting: Got team members for team_id=%s Team Members: %s", + team_id, + _team_members, + ) + _team_member_user_ids: List[str] = [] + for member in _team_members: + if member and isinstance(member, dict) and member.get("user_id") is not None: + _team_member_user_ids.append(member.get("user_id")) + + sql_query = """ + SELECT user_email + FROM "LiteLLM_UserTable" + WHERE user_id = ANY($1::TEXT[]); + """ + + _result = await prisma_client.db.query_raw(sql_query, _team_member_user_ids) + + verbose_logger.debug("Email Alerting: Got all Emails for team, emails=%s", _result) + + if _result is None: + return [] + + emails = [] + for user in _result: + if user and isinstance(user, dict) and user.get("user_email", None) is not None: + emails.append(user.get("user_email")) + return emails + + +async def send_team_budget_alert(webhook_event: WebhookEvent) -> bool: + """ + Send an Email Alert to All Team Members when the Team Budget is crossed + Returns -> True if sent, False if not. + """ + from litellm.proxy.utils import send_email + + from litellm.proxy.proxy_server import premium_user, prisma_client + + _team_id = webhook_event.team_id + team_alias = webhook_event.team_alias + verbose_logger.debug( + "Email Alerting: Sending Team Budget Alert for team=%s", team_alias + ) + + email_logo_url = os.getenv("SMTP_SENDER_LOGO", os.getenv("EMAIL_LOGO_URL", None)) + email_support_contact = os.getenv("EMAIL_SUPPORT_CONTACT", None) + + # await self._check_if_using_premium_email_feature( + # premium_user, email_logo_url, email_support_contact + # ) + + if email_logo_url is None: + email_logo_url = LITELLM_LOGO_URL + if email_support_contact is None: + email_support_contact = LITELLM_SUPPORT_CONTACT + recipient_emails = await get_all_team_member_emails(_team_id) + recipient_emails_str: str = ",".join(recipient_emails) + verbose_logger.debug( + "Email Alerting: Sending team budget alert to %s", recipient_emails_str + ) + + event_name = webhook_event.event_message + max_budget = webhook_event.max_budget + email_html_content = "Alert from LiteLLM Server" + + if recipient_emails_str is None: + verbose_proxy_logger.error( + "Email Alerting: Trying to send email alert to no recipient, got recipient_emails=%s", + recipient_emails_str, + ) + + email_html_content = f""" + LiteLLM Logo
+ + Budget Crossed for Team {team_alias}
+ + Your Teams LLM API usage has crossed it's budget of ${max_budget} , current spend is ${webhook_event.spend}

+ + API requests will be rejected until either (a) you increase your budget or (b) your budget gets reset

+ + If you have any questions, please send an email to {email_support_contact}

+ + Best,
+ The LiteLLM team
+ """ + + email_event = { + "to": recipient_emails_str, + "subject": f"LiteLLM: {event_name}", + "html": email_html_content, + } + + await send_email( + receiver_email=email_event["to"], + subject=email_event["subject"], + html=email_event["html"], + ) + + return False From f6d0c6c2729c38761b2b137cb2fa1c3ccb4bb201 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 18:40:56 -0700 Subject: [PATCH 23/83] add email alerting for budgets --- litellm/integrations/slack_alerting.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/litellm/integrations/slack_alerting.py b/litellm/integrations/slack_alerting.py index 21415fb6d6..2adc16349f 100644 --- a/litellm/integrations/slack_alerting.py +++ b/litellm/integrations/slack_alerting.py @@ -1297,7 +1297,9 @@ Model Info: verbose_proxy_logger.error("Error sending email alert %s", str(e)) return False - async def send_email_alert_using_smtp(self, webhook_event: WebhookEvent) -> bool: + async def send_email_alert_using_smtp( + self, webhook_event: WebhookEvent, alert_type: str + ) -> bool: """ Sends structured Email alert to an SMTP server @@ -1306,7 +1308,6 @@ Model Info: Returns -> True if sent, False if not. """ from litellm.proxy.utils import send_email - from litellm.proxy.proxy_server import premium_user, prisma_client email_logo_url = os.getenv( @@ -1361,6 +1362,10 @@ Model Info: html=email_event["html"], ) + from litellm.integrations.email_alerting import send_team_budget_alert + + await send_team_budget_alert(webhook_event=webhook_event) + return False async def send_alert( @@ -1401,7 +1406,9 @@ Model Info: and user_info is not None ): # only send budget alerts over Email - await self.send_email_alert_using_smtp(webhook_event=user_info) + await self.send_email_alert_using_smtp( + webhook_event=user_info, alert_type=alert_type + ) if "slack" not in self.alerting: return @@ -1440,7 +1447,7 @@ Model Info: slack_webhook_url = os.getenv("SLACK_WEBHOOK_URL", None) if slack_webhook_url is None: - raise Exception("Missing SLACK_WEBHOOK_URL from environment") + raise ValueError("Missing SLACK_WEBHOOK_URL from environment") payload = {"text": formatted_message} headers = {"Content-type": "application/json"} @@ -1453,7 +1460,7 @@ Model Info: pass else: verbose_proxy_logger.debug( - "Error sending slack alert. Error=", response.text + "Error sending slack alert. Error={}".format(response.text) ) async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): From eafcd5effa2d7f295c1fa088447258073b78b45e Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 18:41:51 -0700 Subject: [PATCH 24/83] fix show email on config --- litellm/proxy/proxy_config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/litellm/proxy/proxy_config.yaml b/litellm/proxy/proxy_config.yaml index 015e53ef15..27d49a33dd 100644 --- a/litellm/proxy/proxy_config.yaml +++ b/litellm/proxy/proxy_config.yaml @@ -20,6 +20,7 @@ model_list: general_settings: master_key: sk-1234 + alerting: ["slack", "email"] litellm_settings: success_callback: ["prometheus"] From 0ec52e57b42406603ab4e2c07e4a14bc1a722bdc Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 18:52:13 -0700 Subject: [PATCH 25/83] fix - send team budget crossed --- litellm/integrations/slack_alerting.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/litellm/integrations/slack_alerting.py b/litellm/integrations/slack_alerting.py index 2adc16349f..38cdc9ef86 100644 --- a/litellm/integrations/slack_alerting.py +++ b/litellm/integrations/slack_alerting.py @@ -1361,10 +1361,10 @@ Model Info: subject=email_event["subject"], html=email_event["html"], ) + if webhook_event.event_group == "team": + from litellm.integrations.email_alerting import send_team_budget_alert - from litellm.integrations.email_alerting import send_team_budget_alert - - await send_team_budget_alert(webhook_event=webhook_event) + await send_team_budget_alert(webhook_event=webhook_event) return False From 4eca63ede65848388b59f4a65fb77fa27648014b Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 14 Jun 2024 19:04:16 -0700 Subject: [PATCH 26/83] docs(alerting.md): add alerting metadata to docs --- docs/my-website/docs/proxy/alerting.md | 61 ++++++++++++++-------- docs/my-website/img/alerting_metadata.png | Bin 0 -> 211667 bytes 2 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 docs/my-website/img/alerting_metadata.png diff --git a/docs/my-website/docs/proxy/alerting.md b/docs/my-website/docs/proxy/alerting.md index 5584267569..08030f4784 100644 --- a/docs/my-website/docs/proxy/alerting.md +++ b/docs/my-website/docs/proxy/alerting.md @@ -32,41 +32,33 @@ Get a slack webhook url from https://api.slack.com/messaging/webhooks You can also use Discord Webhooks, see [here](#using-discord-webhooks) -### Step 2: Update config.yaml -- Set `SLACK_WEBHOOK_URL` in your proxy env to enable Slack alerts. -- Just for testing purposes, let's save a bad key to our proxy. +Set `SLACK_WEBHOOK_URL` in your proxy env to enable Slack alerts. + +```bash +export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/<>/<>/<>" +``` + +### Step 2: Setup Proxy ```yaml -model_list: - model_name: "azure-model" - litellm_params: - model: "azure/gpt-35-turbo" - api_key: "my-bad-key" # šŸ‘ˆ bad key - general_settings: alerting: ["slack"] alerting_threshold: 300 # sends alerts if requests hang for 5min+ and responses take 5min+ - -environment_variables: - SLACK_WEBHOOK_URL: "https://hooks.slack.com/services/<>/<>/<>" - SLACK_DAILY_REPORT_FREQUENCY: "86400" # 24 hours; Optional: defaults to 12 hours ``` - -### Step 3: Start proxy - +Start proxy ```bash $ litellm --config /path/to/config.yaml ``` -## Testing Alerting is Setup Correctly -Make a GET request to `/health/services`, expect to see a test slack alert in your provided webhook slack channel +### Step 3: Test it! -```shell -curl -X GET 'http://localhost:4000/health/services?service=slack' \ - -H 'Authorization: Bearer sk-1234' + +```bash +curl -X GET 'http://0.0.0.0:4000/health/services?service=slack' \ +-H 'Authorization: Bearer sk-1234' ``` ## Advanced - Redacting Messages from Alerts @@ -84,7 +76,34 @@ litellm_settings: ``` +## Advanced - Add Metadata to alerts +Add alerting metadata to proxy calls for debugging. + +```python +import openai +client = openai.OpenAI( + api_key="anything", + base_url="http://0.0.0.0:4000" +) + +# request sent to model set on litellm proxy, `litellm --model` +response = client.chat.completions.create( + model="gpt-3.5-turbo", + messages = [], + extra_body={ + "metadata": { + "alerting_metadata": { + "hello": "world" + } + } + } +) +``` + +**Expected Response** + + ## Advanced - Opting into specific alert types diff --git a/docs/my-website/img/alerting_metadata.png b/docs/my-website/img/alerting_metadata.png new file mode 100644 index 0000000000000000000000000000000000000000..e75f0c72bfe83689dadffd06696b719edbf34b65 GIT binary patch literal 211667 zcmeFZhd-PBzdvpiEk(6O?a?Z&b*t8_(U#JxReNjgyC<_Et4&#!N`es=a3r zv3HCb5d`_A_vf77`999g{TCdMN91z3@}95xe7@cZ*HBZUrevlhA|j%Gp{($lh=^Q( zi0G2kWpctD#EuSv@J8(MTInfKX&>tv;SV1x{TJ4%szmn**O!Sd5i=8!{dt7&k|k#O z|F54D^AVB$eV>Gg=z|^6rT=3?5e zlKS&8?b4P?!rK*BWdjc)A_ks6FX9)k@BAhrk|%nh@I>2(cmqWNU>(IA?!e*q69j8J z>MdBxzNpfgr#io){dSj&>?;wM4DnMwu1&1EGS3w*nH+gryAh426pWnTu+|HvWnYXJ zonPQU-Z}iekq`$xqy2P`v0>BG9_~J0@0rJRVwbMT6A}O4um4+v|C59NQv>;|e5&_; zQbec1zQheJJow9NL?o9vgZ|eqc^a~8Nr8y$Ypc4!uF$dPR{wnDe?B44N*tKZP7$iY zbmcc&*T;xo=RO=)O(gob>v(4w>d{ly0T#}^{l7c?e_CWFIgyg3&Uv8z(>tq&<1f^+ z^OQI1{iURDnonu@5vo>UilvJ8X#ZtmmVZqg7@rxJ&*!}R`P00}z~%EzEFUSc_1l{}&n&|f>Eu{b zF6fuAWb*2Cvj|-4UXCwA>z;t^m23oQ+d})}m>6WQ z($HP(U$g!q>A8FDo_C1*wpjzdyIFYVXI#|($k2aZ5q33DbEbO5WGirKx-myRlZoMl zZ%z1r|NERNp|}QafMiSy1B6Ds@{idQ9U5O_QgP=F_vUx`+OwaH+BluU&AxSb@70Ln z@s9WZ(su1lz7;cQ;>($rx#`W@CIt}baoWD~C&`H=$(0h#(w;QAzuB{z+IltObB*%n ze`)*Z8eh9vC!lQs$rD(^_^~|DeWy3)>IIKxRmzw5@@2`SXKIe=CB2Dx#Kv^~@JTw6Cq0aQBkVZPqd)kQ2Kp0M8 zDL+*X2?#9|w*wNaL)?ede_7xGHj>su^ud<1R_VHmw%TvMLe7|6D8S1Z2WVt07|Mrn z6!U5xDjLQ4nrwWK0;W;le*8|IpRa}5Z!$12%);6bxCVaE^!%K}C z0NC35`TA&;$h25z$;$xkBbmyDMmR~w< zB<$%oLnzptu6%&92!s8~&l?x&6^#2DYT){pz6eN%MJkK<%*1$&m#>lC zB>_V&KgXt@OAtgDBK>FrpU``bB_<#eD0URA>G|75vTgG{T z;UdV;uJ9}g<2LMfD_E@54ApHu-tO;b6zWA0Z1YlG&svSO(3#Lpm-@IzBFD)2EH-!v9@=`jEpK1g7<#b@iGuvZ+PSG-mbY)#ruJw@v zK(#5=<4ZW}C30*+->xrlM03aoHbVmx`aa{2@s{gl=c@!kYWdiS8Ebr;Rt}sP!3LG~ zYDPtu^#Lslr*v zRb1RSH!)+CYmsr)iQCdAo*A#+$)T~TbSGe{$Q#jX?||rV6R1bG&C0}9$da{@8te#` z+pxtdvE2u|DXE7sm~Cb^E;E)UD2|y9{_I)XLFr~deT3GAQ|P};CyId`m}GMjgfxXvFH&H~MBvUV3H^PQD2nc0NE%?zQzbyGBg6T7#R~+R=Pw662*ywr zX*AL7L8W|Y8_i4)^Ti!=wM4D!pwRt79y4RzClMEJ-%Aqbs=x)vCbG{?zkYWP;)R@K zfY8#cQjp$g#u1FvE6Ix9L_3-0ecuuU!#f(?lq0jLmQ}b*_S-Z) zr8o=;IYG@O*wrVE7y#;QX^B{luX=FP$C$wo@)Mt_ypyRfux#>K z3S`{hTvu~araiZvrmJ?W5EN`?h^F_ERA|}hnsPEBN7ji0Azz>$e7PTtjde=kHAwNF z>UO9sWMe1BbMPf0I_TzLFK589=b z^|Jk)=c{qgehyc@{%J2Qusc&(hl&CZ^#=gD8UTT2Z%!R}p$_a9y(<7xl~3hh&qD)` z_X~17Xz92Q>O1LkK>%pgxV}=P?D&USPib-K)9lc&FSi1$Bv>Vdl9Der#=AFN!5^3> z^C6`(d2L^4A((-&in4&Rg=W2HWZT$P4;DZ_**ogRmF!|b*TC^mfvAp@@a(nxpM*~I zL}kW4CT{_$StS6^t#n3dF(|98w2OuA!{wSca{-0-i!!HRo_qHZR@B<7HRa@Y0pQd~ z7Ne}6ZAF_?Dgy~^nS^Of?-Cq%0Br60lJKf0DZlOQmvy_J)=eMDaq4T%tH&%~l&2b8 zUL7xsq=Oe9-}Z(GU0!?}rs%EYI8-96BSk%Co1&14s&p5q?=2n(t>zD-VLJ*{R&2Ek zr<{|zK#YRqeW_}aT4$#p1wfpqrw%`(3nF=NHin1oDb(B&Ek8?J*wJ{gC%M!sOdg^`(^uvHT+#@5>sFk(p5EpuJzp$W4dUR4b+DVuoJ(etb zkO0>yNxH~fb-+wlc|bM*6;Q9TIjB}?B{Vxw1XSdXQMbv6XT5lkd;?O}#wEm5Y&ACB z8d-594B_0O;iVM!UguWgAhgfR0GpJjBQ@&VPo5D1UhG#g{<(`nD)}rM%GIRuNH+L1 z){BEp1>$B!TJC1U@&Qs$h^Mqr(Eacs9+>mdCwsG(#1U`bQR(RFW*EMr&KA6IbfJv4 zEYf50#71Ex$(IBKu3O-)7IpdV0+4Uk95a7#F-%ZSL%qM~z*wg9^YXSoM!%<}xx4r; zefYColN<6%g`kYR!P#P*G-hq&EKtr!&0549{rXkY_Q;NF0h_~ zQYpzK=5jjvg89m;Gk#R~DVi1>sfkW>?_KquMxT6U_DUfpQ!jWWK34i(6zavZ_5H$3)2 z^$8y5ZnG4vBEW$&(eIBLwr}TN3_XS391yW&Q}J^8;mW~g1aY%w@urDC0;o<$~qv#R>|N(Jxor;#;x?H=LY%&FV>MvWYL+dWe?yT%%h8X z>a5$iIqalTxbHRd?va=C64Fx|ikoI;nA5PVLz$nG%KulcF8??fQf|qnHzs1uVgtz$ zqd`r1HTQjYS`l;tN<;l2(B11OD8X>=du2Gws$>?`SKoF%4T~=7>Z)dab~TiH&ZMh4 zcAx4Zx5_C_;$+deY0+JKuewgHIvWeH;l}qN4dY{&6TK^&?gt> zk=Is}|Fj}iT3mSrkQeH#S|VMZOfM$HmgW|{>SuItU;2i8tIo7e z1=j}|v)@t^>K0h3*qDp=;8< z{@sgXoXbf;k@t{?f5wnqZp{LP7%-i=Z|GysDozlhG7zuD!aAW*m-POs=!~z^+uz#{ ze*3+|ukl_uk^>Tkva;(Z7JXh{0#buOVT#{0DyT{BblD)BTuv)Iki0Nwvs*@&6o=8g zw+1UtE>7{TDc{Mm=oafM2I651Vq3)s&&p&PuW7&PJx{pHnxIKG+DmRw7U>_})x8d* z?z4%nrLf$^9Yz7=5o_ER4v*&2iADF>0_#l^Q^nP*R1s+a?|yd^m%JsiVI*T~DSA3` z^m&QnSZKz@F%M_-D^7_#$Avzz1ILA-aBIUm{6^ablFi8s1-m@3O!V&c(HnJJqYk&4 zQ`6cR%RbQKh4e0Tf!9{AnZK%S;a<|@8Y}C-kWwZj@?F01%0{AjzZu}?jBuyVt$FU@C_pz71=*kI>nU@;zIkIbl`lZ8)F|KmwLTO5 zTiR#vxYe4^FcrNErF)k%+SY#pBttuzU>y^h^oB03Yrk3F4@uFjf_-cd2&(Fed=yae zcx_BY>cY%9gKL&U4^nQuS&JVR9vl@}H9u3p9HK`ox)Ys`&Ck-(L|eFJzss=J7qy@5 z9ZJ@Gx+uK~lJ^gul@PV)b4!DH5MX+CdA;s(PSrA2X+(WMoPduE&F#bsXL4=zPPBdT zL|dld_jIHLq(t)#b{J(OX_77yQ{+Bm5A~EP`6VL}BNNB|O8(+7rQ)XfXG!Xst)w@D zCbZm|GF~z@;u#8vQ>@?@6N`T_;V=@ZHddFkiPDK_YlU%NR~KxFDV(Fu8S7EKo#016 z4o}=Bo(*W9EiBg7T$tVk$rlBI94A1Z)#bCKt@SSzI?DC#H(Rn8zliH!ht@xO)xY^2 zu@TsCTU%ESc;R;J(v_84u{az=$r%ZsV)s*)%5h?SC`ZPjDFW_<_*v$439ViUE9I$d z^D2qk?RKJVJ(zrkcRRu)v0oG=TwZ+EBnNS9hx982@EBRk+UPG*K1RA%P`BMFR0s3I z^eW7Vn9oB5|Mu_E;=z^+T@#o zcnD3qWN&YuQ(CI)hgs)|xr{F$&vf$eh;>9lRGC@CJI6|lLZIgZZ&^uXfUB^g=8(5r zX1Y%N%bEj#5b}vUs^!X#xF_oYAZC1d?wcri(@X1Ubgo%rpzl4nG36+yTBdCEv`tGG z_0Yh8hLFj3j`KpCC7xLhLeOACr8{0z)tmG?Ux!SZ5ENRvrweJy_|}{D5J%K`rTwJi z(;mr*<4UuzgmI*`Is%j$D zF19CEVX`+9?K1sJP2A3kJnot?PJ0~4M+cV|b>tDn1FAN)~N zaL`%lW`T4$>h{Zv+VYI!W2$DPtqBc5zR70Ck}u9>D&$Sc=D+asG6Nx1X93x5N5iXb zd8te4al)gg3P&(N{WanUp+^$^$)~hqptKeHd+fow#3ssy;$y|O7-g*4-h)QKUJT87 z5l}G6<-_)j({?i3mu@=A-HK2+%h)>AR>)7UnNo`WO~1POJnF#t+y&-yx8!eWcoIB& zSdl?tqkm~{wKi|h#f!bi0dZ=Fkw_Bqk<(kz1*xrfTQza(u?Z+hh7|(wZd{X3(-nm@ zH0feau`@Fcxuu!Ee^LoE_(s^VpWn;P7rAp&I#V#E(oS@!TX5hJ)w_TM9G} z#u=LrLLF6TV6mCp&m&pyao|>yP3NS&HsXpvZmNOz@9(|_BK8wpKxh_Ie!Ws-o|O#m zz!+%K^7+~UtcCs+|xu=#QK7xtCB=l9B+@L2eFc;>s=E(7i z<1sd$YMLs;$nfCuO@$_W=qrZfSK_EOpl(;_2PLbewwFg8s;WaHX~iR@-bX{pIuGp1 zIw0lYN;=@f;?lXM(!v)5uN7nbqC z{oBXSO*px@!No7r#GcSGnXseOEwRml6+UdSbr0U%K3{RI1T;PoQ$>ti;!r6>hi@54 z`pKCx!<~UD{p`UNbTvmuKR&NBe$|`t%+%@e;Y+1ZQ993yQ3{$bbP*72-a${5d;+}X zB_~08dk|x3MSo&?k6eH<@;T`>KJj2)hRrywQhuoEAjkPGfR87*l#p{ijdcRSQ{;5& z*BTt2Bj;RHeow8x0HC%iFT_#hn}nlnjVIc2oU9doPnm_`$J^?SP8dCW(wwEQ>rCXH zm|W4nW3O?~MEtQ+CB7!^SmUcxx<~-*RWj_uhSZyPpHWuD#SZ$sRE$D#iKc;yTa9?) z@aLP2S~1FZxD!pi!uJaczlLGZOWuvA^#qeHXxI4cTXY(*FW<5!X>e#{CSz0{4cU@YR)?g~)gcc0c{n`UCX} z-{HKZhXrbPw;JI7c-%~UN(!?wgvVd}*u_cc#^PSWQ$cO;;Ca<#*uJA3wRPn!+b{Hi%t1>GwBfW?`wX z!lHngtfFYX?ZX<2C^e=siD@!c$Kkp&r{jG)_uABQO-)TMK|#UYO#GCvFg%&92vHmp zbNhM6=MbBYhm0D7$6++=0*Rngma~m}QR)(N62ki5u6TyESJ_c?-i~^l^1#gdZjzXk zKxXQo`9p3N}ZLg}e z4iiP$I`vThGu?L#YjSk2&x0Z2vIwD=VblU`MZ9_Y11EPb5{AH&SIAVgW8--6(qdsT zVAABku1^kMcVOP?61XQ_i^~9796xrMzVQHfzUO(|HaqR@{W@3V@CJmLg5zN)yDlB6F7=~< zcno4D`U88Qf|?BG=Fz_IO2;&Cn@7}!Jz2BqTXX$%SL36H4-eHN=6%i#W2DWh5vcGD zS-$(RAFL0&%km!Fk@E%RZb(;nGPi#E!sQ$2tIr@-)sZ#L#U%IF9g0Z1)VDD?2(2*P z4xMd;xuSN40dvAiLc}X(0r&Cu3=>xJ5&j;!p~n8$$U8i)=YkBuU+FqVlPcq5C$dbB zUmXd_Ijd08m3>5B6H0(Ko#8fDdJP9m`;tYWT4g`|z{DZaTXib3K5c96`-4iIGiPVC z2G#cQ-h}1biWLr6qna*nsJN%u^c0ahFmVHhVo5UDnWF_MlaC>Q*t7kW#$T8C>mr=+ zQ*Q0)?yFoBz)Bfew}W<3O8t{PGicXrbBN_sjoSlYAFJa<`y?^*{zMfc10?4pp#@dn^+q`3+oohy3s&Eby zFokxtQ_9$V)~Z01RG{0GUj`UdSty(uq}U)OUuz}smvzrAu(!1LRva7ByJms{?z6IU zR!~^z*jRkDEVGm2-QbB96Ca)vk=*&UP@mO0_kry`R_+=LV4xMERO8797;b7$=uNG+ zI8`#EABDP@ZTs)c^EfweYHniZ*;bDkAZvyuP7_S?Uot>MUXU&{3b=Xh5X$=T-?aZ`1h{u6v`r(ZwtA0uCoG zRo4!hu8K=;%v5n-_WG=PgA_RPPwA|Xdx?PVDIdVAjjsY%_N7KNW0Mn+Y z!s`y--VsMEM9P)QoXTL^N@Kn~p+MeMn=%PJEgHj!Y#3IY4sbpD^uT;@gPTFlFK5rZ z5wrBkKu3~RU%}XaabTw;7*$L4Y^aO}7u4af9k%GL-s*x^Gux2Zur??=H`LRxCRzKe zMA2RyLTc5FtG!#X8-iJev4iWjuIex5lA?@%$fP-!LaK_;!}((+_vm({%I${l`W{cL z3~dceN$$NJ5;Cq)2Bb%H#`1=fvw2Ne6$=a*`!rrE_U``5yt6`B_srQm0JqK_^ch5p7NIaKkKLuD7#k}gox=YK?kBEY+$lM>@bqet+Am4b0;W?Ca1L6b&3IUr;Bos_bP_;{4vky7V ze?VxbmLJA9RakY`-#Nu$6J@Kb3%>H!%Xx1-o){lr%}w@QqXy-_|LxVJ3m zeEMl3y-UBrKNOk-nZ6|hTfk_fUw7v!2*S&~E2P95I6|T}5mH5W5ANHX8~*O|5wplw z21Kp<=cNm_2ZhS|;9F=jZ0vK^D!;H>Y3Ug(8!VePTO#8i6Lek~Yk}>NY`X&?w7>~_ zliwC$KzwKVqhd6Pb5*~~FssO-r`c_5*4JP*-lB;+o#Mt-+dEwrYhAl@yz2nj(thB4 z=fT^4DfGhi_4$-b*lBF$!Nm39JoVTR+T=mg2BDsGTVQqx8|)CPB~XZK z7$qP`o_%q{t+szo#iTmF}DuH*WBR15FU?HH!{r@iX`> z#BPkJ9ILqMJ+l$~wXMKE`HvuGVc zV(nG9A{Aq2LWz;pVcEBe?FL+zNPExMh5($OC?6rjQ6~;8$$?h(Fq%sCVdu)!#uXFNh1KuYewj%MPP_!si7pB}uB;+_xOdWGX%vA# zzM0rSxH!e^;pxBfN6~g49{M^Ho{}FHe{0g9LAD~w4|2phZ4<CNX? zYF9WJiK_{)TwHbAo5~PWB8gGX5!Any;E5g!@B7O4OV`9i@cZ*GaZX66N(*q?iZ$ml zq&6zGR>X1jnu`o|dT-1YK^P>2*Sg~QhkIXFtu?sY#{1iDGfb?`%e3P~0zw?6ANn7< z3Zs99QdJ7R^FLSl7q!ighC(UeBp8#uRFo1$=YC?{G1`>nuVD*n z4327;2Qm7mY{wFB6M*Y@qPE#eER&Du+8}uzQG%0j>gi+7)a@If5Xy_$6Y7&iXg?4`L4Y} zF1ziM_N56UKb5+|uU4kX-41mFx4>1La&g<>x$7JD` zSM{sNxKG-7hEAr$hw6xJ`kyH;c|vD%=fOlT_lg2zEk3e0}{8 zBbI4UUYoy!_t2dT`)ubp>Z~7^zJB4SXwMF@7@drKsqaBIZL~00t+*U{c!{jZhbZooabA(p=f~ zoK#o=#{~@RqH&f{+Y#`Xnc+UWx#s ztIAW%ctYe&OiK3GN4t$aO1s3z+cv|RAf*Q1z`<{=6~ko}Qoj7tk?pe*h?kx-qEP%e zIM)929(G(8 zH}e*NnS3^rZ5elL zBn+PiN^w!ZtBPFK`Z-kT&M^PS#ZSl5qs}z$l3cF3GBPrv{GT0B;f{HFa%EAIaCqW> zxT^B;01;Wv$^U(JLjLH=>McOF!S$n!k}m=Ih0-X1q?3a>ONpqZ;y%a9&G?_!H1IjO0s$((58|6$qWqZkIt9jN#Yqq^B!Im-B;#3w$d zgC86br|oO9w%w`DenVVA@-deWL+De*oW2SgL0@`kX~k4UTHiF}e67h@i8B!^L$sV*v01TeRzbw5A9l%aZ^Wp49t z=BV(5!UkvxU>O$JCmxtR(l?+8_hzDXJ)9q zSB}oLy_0v%NR3-Q)K|33HHo!iv^81#Q4wZB8piL-?Y&(%IAhR{o+d@-Zja%wBh z_Ojgs?6E>+kB~A5d{>HEcW+D(GP(<$+Vuvfy@S;8CyArFi<% zdxYwD*NZlZBRu+#;;t5hv6P1cANr!(ZTb^JsTi$v&69JtP;lt}_Kf;85F8x(t$Sl) zi0z-NLQt%VYXjwuR5uT!D)|Z@R>TeQf7=hfLnW32%Ulh&OcmDjHCBI?mCY@t%W!4S z{)d_Isn*d#bz`CoHZ3KL^Tqk|$@+Y$f-PSyojChdZqW4I5jul@4Id5)^_%t)jmRgs!acMAM!7W*$&Essqt=IpK}wk zrbro%uQ^@q2c`9S4EZOBr|(;(S`%{qD>y>v$>!mLgKSn1+;Wn`j+$xU5&h9>dtX9f z;r$7ir$gNxnf1wNu4i{{&ZBi-(bjXbevR7JyO;SmOYuJHQWjq5N~fZC?cnwuq~Zs? z?lqto?~6ez5Ch}}VJIol#ztmy! z{ej)bgg4E>k-I4=&vs+m`Ioj3QoB50o>O?cYVp?y+NhVR@r_%NCtr{)?k%EpN5}~2 z+=-MiH~8u5#%a-FT}bxzD-M!uPBYUt-KM#GEd#fZ)25OX=PZhSup>FKG`ZvnDSH9> ze(lXA_Ojn{{&=@enIG=* z{o6RjC48i3@YO_ov-rYFlyHmAKedHm_oN_BPpI&2%`6FMa@!_ujH7Aee}5MMGWf)C zk7xZ^X}5|tErO0uD)?JV7=uZw-`fyBz0gIE;iAQnf?nsg2$sKGu1}N+E}E)a;^map zt#mB(17)Rs%N9^=`_^xB^eh|;c^N{N`t)KEV6gYDi!^G@NmyxdEHTwmGX!1Z0zYGl z5h3N?MQgRZo{_%KtNsNR6e|3LhQ`d8F24UnWiehS-A4Xor}52E3lkmFp!oevsVsvn zKfycHMsG7aMV!OJ$oS9pto0jk=1Lm#u>6)?G6T?L1S5Yv@Li?9k^}t<6a3sPE^vwAPIb*Rdz1PC= zm5_G}c&zlsQn34U08NItKClYlwxO9D@a^gAU!E_;>zT%*@qQu229*$*?ZwX6#Z%sT zv%Bh3ChP0RT@_2+mdz(*yU<3w)>!GLG9rV^H4FSB#dGAU;TXyT=*j1jdrPfGhvzJu=0X8 zeRX}xjGUTzwYIU+HfCyJjMI0s8i5=>qMaYr(bHR5Pr0jwozyz;qWY}FP3OB;0$s{w zH2Vra3xFOXq;?W>+b8=~Q^h*hM~gzB?(TtSRWBt=HsjS?z|`H|?6wL0tU2g=mIqkB zy~rOuCi*qRJM_-h3V9e|1B8HFz+%%t z%i-Swo3iur68|vbiRNg07#wfX*YRAyguyAynaW58yC1%&vtDpA~P6El zXup&4i3(4g*b!*v$cy*8ozTbZ%+ncY=1EgEu-h8iC)%ts!}m_6UYrKQ(1YP1E&rvMUWvVwO}I8jU-!jKbuJWfh%LRKNF; zsSJv)tc<4oPjWe35A3D|x#o&rmIIyn`yQ{^Sal}|x;F)H$JS2;9e<>2S*jXV+p&I< z7I4s>TTn1TCcz$mM8%+tKRaD4dqx|t`ThAzLjGtB7$kG=t6c#eg-|DN1@3^3tP(%= z`3;yIqRnfBt~U7fGBZiOecvPD6DFP&*i-!7a&@-Z{Rq)Wr}ds@(QF6PT^H=brU5$H znb`dmtKQj0%~JmaN1D%eM|5gM1Ch~)U&thoJ~pP0u~U1d=>$A*XR;{t51aC?^7cc{ z@2P$6hrxTdqyQhi8|+8#A8ms&6PEaOm7OwWAM}ov6C$t9renX_{h^4ZI(3jP#ARkH z_Y1avMHa`@e}MAVlSby(&%P)3iF~|!8BzN2Z+LmM@i3R_m$4A6>A13Ambbt0_q+Gc z-V7#l;%bub%(?3K9Ur#WP283;x;rR_Uj1&F#}Cy5GrK%*qY`f5BOFDFzXIR9|Dkq5 z)G)Fy>*zon9IYaZ^Lr%{l3q)m4j69jl-q9}-n(9QxQF-ZIxeYAeROR&TtLlw=R0FaLei4;rIl{Zn%&)OfM7-j>7Eri1z!nH-p9+pkq`uj$WeI{zUE0182nB@oEWMnRwVJ^?})+QWGIk z3Ys`AwWFYu(`|eeGW|e`W#I_|VrCqmiYrPw6U25z2-gcRN|~kG?VR%CGZ~8ydtCx~ zy=OdJfJ}H8MobcavNvh--hVwdGg?KczV0;e_blm_j>+T-*w{6u*tquo@<9mg<5e=n zhrcWHfrJxV$~*lugJ&j9_Ux8K>T&U~7iAR@5Ep8&x)p5CW3t)VO9DlR2izz=>0w zUk_#$CoEVWPKx8*BoC@LaQhz|@V9Oh573|m!cr$mXpg%=Y-x>{F{H&i`V=)A#wphY zRlijy;HwPB51Tkzc+iJF<$+Cg(3#4svTT_cX+nLD^wJmc>3yMqpS{b!UEpwoE0Eqm z|46pB4ZRwJYiIJxJ-rXr0py)}LNyw)$K{nvgp!4bE4sFHF!okz#LR%{q%3e7709}6 zJ{_yxH7bW!1eX0Adc0^FVD%(4=C+bwGbxC0!|u0I$YYpl%0rRm>emTv2Lu!5O`NNO z?5;+`5Y-)`vK`;Jq3V84>n{KiEr$SQ>ymnQ;e^#+ZUYSu2t-LHMC8=nR=uTGPweZ5{- ziT9ARb5#%`RD@)Krhk@Aof>X1)9o;ev_d2O132771s@cdG0M;M)~~PK#_4upY{E=% zihzJm{2XhKwJbE89FV%=US}Slxw%R27@LH!C2;>%bl&n9o|m@p3&Oti95Pyw0C%1I z=3w;vE^23dkMK1IIdTcQN;wory0?vn_ZJw3y5T%C57LvVI(OnB4<`vxe+2(deXohO&atjknwcvfMw zN0Se2=bqlU5`lm@iMbEWjgT2VjykQX)fp? z^H(JX?M_Vp!|r$0;hCA3?eNy#inkV_&?byp;z^&LMRz4&=YZ5t$qIzsabaXK&Vn@$U$_0XytJJq^n6AzQ{P1YvOj7E10V*y!d_eQpDV)LY+)+W~ zCvMZ)0D2Z}1)7QFQVRL(30E$Gpx@+)fL@ zwpY88&NP`etWD1=58$~wAa!|Y(iZO)?s?nIqx+Hh97p&r2XDfx+6&5JBWS6NdAa>4 z+zppSC4nSrAZI=?Y79KB(^FilZjDH+A%iL%xp+&BVFVpnM6Ijp2n^`-ngh6A=(y`P zN_H<4Ljb>RR}g6+V^`pZcwgn$liLH~d*cWE+mY=4e93vLN%2J z%uw$W@o2tG)5g7cHfP;u3Sl(|j~gFjK7Y2fTC1mh75>snG2R$A(w8Krty6O*WriAa zu|uI7A32A$wSGWn;(weht(6HF%^XXW#BcFG%4_`C+qK%!O!rR^NMoO*B!sP`cb|hX zpk>&}T;!6#O|jGx{-cWCR8{HDSfyawDvRGEAlBj`5^5=*?U{$G=Ez^+@NO{3^GkZ( z6fN6>92s*Fn?B<~PXQXKRe51~*Y$h6KnLl%o#oUA-hGdK_siQYPmihZb@zxpae>Yr z*kaf7U=5zr^T=@)K4ArPLIy7i}HzO%^XJy8aYr8J-vF+eS!?e1P8mJ5}tnO{P z@RVXpJxQO-rUn|a*7NR6D0*k%#_io?kfIg3?^p0)VExZsD#qelo2D++UA-?4=h;+u zrNadraQ{Qa4HKeB_9(UnP>b7SM_^f6QZ_5>l|c)pm{sPbyy zr@f0;rM@F>YX3fyF><4qvi9hRrsX46oYSpQ@VsLaSxqEj12Jpz&%IZ=?`aVh+msRJNP9Q`bWES6Vw zS9T?B?}bb72Kvk|#L8@3W$6jy zB`II~cw={k2<)d~{>VZ=r8WdOx@G$bHXG_wDNx97h{wx#>W8K+zhm(`_^y;K5)pv) z7BvGH!S7W*dSvLabKb!_d08^Tw>YdCE*30MDp?6-jyl?kh+DfQOl@DyvM z$JTDI8kB(6^JpUQyx^azSB{#m#8=>E8N{Wz@0iupzZi4uaIJ`1y&`T^cWi>+FU9MWSE?N&s+Ky<*`oaS zKRh_+d{?IYNieh7y9{@IX9ABCg5ki%t-O#Ez4>>IPeVvw*nf(Am>6!v8Y8-WHg+ba z^S!sH-FpTr7h^LY8xg*W!Sd((9U)h@cT<5lHWA+;ndApnv`2l=#--lbahN9|tlaC} zCDfF37U~qe{Uos%&BVi0HlPT1GOBeCWlQKaHQU+W*e#>df2h)Es>w7VJpYcQfN{2u zK4`4^t%XCAJ4lL_sgt)_8HVArCvFzuuoQviNnSf#cUE1)D8xe*fv{FWI z{R1jLvv9hP1;$r&2Qe6+t!+*YI>+^#G2kn3jD+DHxVKk<*Ma%G=uDanuz@7^K50iy zgw>72_ezW0%+e1bK8U{A4N7BtOeq-fhal{ntlsuzV|rwtvtLrwZI}P2q}qGRH}PbV zSI$Y;dp;+8vpt#JfB9su&Rj7T$TONKT%+L(-;7ji{`9I_AYuRZ^Q+zg4s5Et2+kCL}Fc1EHs-!rHU#YfDU$Q=j7KlreZ|8im6B%MduhenZ zT(d{LpF??vgV7_^&M25H!)N{lm@Ga%em5p6Eje-QF@FC4W9%(};@Y-#VQ3&U?vemO zgKHApU4y%82*KUm-Q8URp>cN&7F>e6)3`PA_rCYMb6@>uzjIF&RZUT~=sCw4bI!3o z8B6wbm!st^;jcze6Rq7o?qh2a5)QQ+=U*tSR;QKwzSsvZ@r75A^=%fni>3?2!Wzdt zBcpJ&l{rWR{g~($e{Fu-?95r=r3$LzH4tdN8R56-h%`?bn2%OeF@ZO{C%3F5mZ-5h82iVu{nAhgv z%P-e}V23f2wYup?l=6M%QDo*Xsy)M2eHB1h?r9tVAce$_TUi zK8G}13zbLTH>4G&k7i9{ci!gUaT#*`!+p)4WOwB?MG%waqqkKs>QCzqj=Std&x=1P zM;SWEqUgCB0e%qGmIVXnXJ7VYW=#8|*?DcE#vo(;;s!(Oy7pU}V_(ldmp}HM&>K&b zN#nO&Y|*Uvu3f|$n+JxM{*`d>e@~kiNLvL*C%*U)GxdYQiuj929xr^O)f%I3%b7>Z zc>s&7xVTv7Lv;0MAci2ttLITyt=$xbYn6yZ6d^fcn|M8jBWZRxoA;m3+;{B?k<9f~ z%L4`-iX~rorJVNq#+#nTmz(PA-C&~v(fNcruZvmS4(F>4!1Il6E4;U_bxupQw=*U& z>AOsM9p9#mxwpdl%nZFdo;E@S@x41{Bk&kZcZTC@e`H$NkNhHy;{`u9HN6S_y5@bi zy0c9RDQgFNL)sSTtf7{JjN6Zqn?mMcPv?jlBTT-Kw)V#n%i7*5rTpWNlO`xvGI&_p zfaqz{adUeMlhB|8Cz7grsb))p+2PWY+C^p1w)3$~?=!?wzC6KmEo{W(D$~?cWyr6Y z+0^?nC;75iR3{J*&Bi=r-4qj-`}dXIJX^LCtF1d1C8_r0PhJ|G0ja z&%M-%H-FnraomZ$(=4Rxv=qH8iGg%&El29Pi<^NlIlk-ex@~9`0XJc^H2i zJShQ+xrP#4og``{&jdXMr)tZOJIp-(h@@V_2&5T1jyAVqP>_k(dsYsNQ=R{RR9v@) z!Ed} z_18`9DcF}fftQ-wrvbaa+-DUoEGs)7 zT-2y-`rBygwmVS2>p))biHDV*^x&6&A-m=j)-{(gG$4$CaIaD<&TykW8>TZ#o1PP7 ztyX<=^5%gZh@{zFj}lU-Hl(;(_Hpl-*DRDJuVCQ1+~(P_^b@6zqxO-YHz%JC){Lux zN_$`5kZZknr4GD~ITz!1;2)QrKfbD}@@crqcN`kSk<59u%{>V6x?@I_p0lAR*vXG; zRqnQK)Qng7&S^SGukMbaQAY+JpxlJGeA)^A#?NY}Ly?c|wo>RM3yj{Y6#MU@9?nFK z+`XOmpVZO+=4>PT4G4duudD|qwEE=;r-EyHIwtFBEV-^+AG8cis_QO{6`*EmX`r5X z*;)GNz9q()Xe0)yeqkrPxLv+7o5*T$0DIpJFaoQD19D$azPoR{AnuHP65JX0nOuSo zM8vpkc53WXv1uH1UU*fTuhb$+wHw`Iy3Brs_}ZilX_%fYvYlF}cR+qV-BfdW^dNWK zca`SGGjzR*a__6;CT;eGx(g%g(RzjI5SW~;xI6Sg`GDzSS+l2R`?bno;|#Nl`DNSD zSYL-^uiH=iqkmaQz85VIMic!P=J7R>@AU~~tzkpZa=tPiYGPuNeD9O?&2XFawVge! zh;09MVTsT)Kg-ldiTrND9coxs(tx>>1#LV{K_h(vlWjzxRz`-j&atbb2YWsUa1YcZ3p$Jrh zBSzGS>4NX`V#%?(7kD#{@6u)KDJA9a&dV(B zeU4CMSl^e?OktzbX&-fU_2H4^A1BHq z&rmCxSzYFMt&8`#9U)FsR!y9dKPAq z)PlIHgu;_&<~kPCSIv*{duCpi-OovYtBDL;qZ;V#V^=8K-zRB=T zPLDE?2{>!^a|fAadS1;%GHCDIu#Xp@WS6#~kqWHHw%Tp>I@QJfjWzdx3gmUzE4nI9 zvbeM*@W`O<9ovAed;n>6w(YWN@TXioc77eoZY-TSZe4nI8`2MG^nE&2`w&R9$+(Ofbi;H|D-pko}Pbv1)oj;(7OQ>?{01D>g=_*=z2oFl8;H$U?rGQ|F5> z=W~_4r_G;EYxCK0MGJ@A>tpH<|N7MKC$x!RH7~rWBZBg;6~jN-s=Og&Owd71Y);I- z$ans!-BRQOq_<4zuK!C8m^rP}-f9?KycK}* zm!#%-?eD-MamGB8O?)5}z_U+G`a;aFMGCfwo>NJSMW}S2|~*?mP$- zS`2vE9upt-hXI(;OfEM6I#&6I>QC?WK=BOz8j`<`vwGs0*fve~H_EZ$az9_j72m8G znbtaxF{&o5mFtF!2LI{JcsWw*sNBn1>;7}fld|;V(?U}!hvHJg% zDrF+HTCTLV9sLTc*40N!Rw|W-cCh7F_)GqG?DQ8vW-z&2ec+h`&oBQWuLl{@StK*+ z{dZNw3epax;S@<7r2~zSG>~l41l|c#+n3!yLxZ8ix?bCv``ws$=_P9P6TS8 zAB!kbUHKbXo@)0N%!~8qR>nlAWHOaV92Od6p-y-w)(qG~uR~?#zsXh@z!D1X_B;Hg zyO95P7cd~1Vgdl3QRcE{>f7H;;2#+|BJ1ZTezdQZ^rN`chJ)_^nf(!Be)fBx-^0U3 zevXq0_-DHRYyYPQJlg((M-SO z%UoS<^Nd}OxB8f#{**Y@?w*Wg2u}zr;rG{ve~`ZrXm`5e<<%=_X8qX9YOujg_YS0( zxB2thd!cQ|APR=E8^{Xyw;w`JVnV6W#}NB7o9)(Kkp<*K=&!O~3CI9wA5OdOO z`>~T$ZQ$&Ky`E9NW#skqqIj~7`9H__Z!Q-J^kXJkxD%ae4Xo;yKu1Ar1J}_1Kn&bg z-{(^wruk0>;Ezd`XS#Uy9!Gshbh3DZ6KjE=F(4MR>3^N|e+Ncb(hm<`I5dsue`5M? z#!Com3k3D{5{Y=_{9iZW-&_z71H-@=fX>GG9}Z^?(=a%gGw7c0f4^&gjUS%GpNd0U zQESK=7p+XH><>~|q8HnLaw(<)rlP~cYk-$v;~yi8NHRf$pa0>E+9|t{QNV=uNdKLH z|7Pz0m7~CqfJzYXW4A8%bs z{8mMl_RVrUG2w|3)}m~`#;1Ru`TtlPesF)?Randxz`tL75 zCxgZeQD}$$|18^oA2sMaG>xzbeZ1KJvzT%DL6eLaCjQ5Nmc#zt&?FN#yuX6!T-UaFR)-gaW^wFEZl96Jr4!PDSkEF zGNSF);x-DwBsKZ(jfqu!11e9!bHCb4-e)#wWt7k2gC0YYF~k%qB~h1)7uz)b$qX90 z6QSF&{oy!~kUMbX>x+tti4#lTsSngfN&ViJukK{yS7K>@v21DqFOjULbOIGVR8W;v z^$KmMV*L67SHchdQ~3Sey6>0Y!H;=O0-m0~MOWAFSM)PJmy1J&)wag=bML&n{nt!aZWA_8MA;4?z1ySn2;7_($Sw@c=gFW=a)UnDyJK7A)+aeVSkG z(P3R%+~tIY)7F)B)im$n7#KL7guk>=Ls|U->FtG`cp}ahY*OZXDQM?VS%ysrbCA_| z1_##Lk432j)jCbWPxmtlof`cbLHqzT0}C>Ty)kk~i}SL}#j5K%WW}83*w4;&;peLH z0w;9j7@1J>nJG}~QR(S?*pu#o+jcR>%AJ1hv zl|2ikd@t@9*~^hTuz&`6g9*fbCCCt{KaXL=WIDw9g||7 zAK}xZ(9(KzCP$=nVoCFLhx+)t0{QGemy1D2;0Tr`8%J*NaV$+PBgIj>qK@hBoG(SP zsq)6p7X`qbx@OsD7)o(!>eT(y2zNZ(+On>VQ z(Mlw=MvLG1H88v>T0D)ER;k;dU8&zOZ;~BLhp@%<0n3^P!37b;lvV$B?*FLMCQ3l_gU48u3F8i%Gku_Y*dRd#h}USpTV~F#9U7lVAPg|w#gkStJKPQ?L?!2=M#N6)M>`O@WAG?nqTNz zxbw$e{$T?H8A;k`6GOl&Iz*^Kl}@}^1}~cOH9m1P>TO-r`pe1ePc@a#R*T)u*NDbs znnp(5Sk*2O_}ZO&ksh`7~~9Q>C? ztc9O_ZM>V=cm2FLg9#t`0>3RZMsqnG&|o{{o^5FVT*nnW4w+xQEKXXa(3q!3d-`8fe{`NjAoLOX*jNCNY9VBQ zv}Uv0Fsw<(myuU25W{G0#|Xz+!nx;}a^YHl?U{&c3JG6s0!w+dI-fGWcN2PBbid|E z8{{N&a;uYlJX>Cv_Q|v48|JQXLCn=WC%oZ9*&v-2R>~KQfnYYwh!wiTb(~@u{#~8j z8r^pR%+G7A=*PX1Zt1F?oe^p5jv2I&sN;LmQ9T9BaR>xW6efgwer;V42_Rc)JDnZc zzUE3fWclJ};Xb3d!Wu>sTc9eX^hWp@G5Xv$8xb)l=@$ z@*WHn0(PDkJ~;UJp7$Vj7~~~`IH|>ANE8P@J%qr_%RD1qC+f$XjUbOToln5Cl;Pmc zuzy!2m?`OG$#E}<@}bv1yL#F=G0FaXLBfsiro*t_>9}0HxlD{biGcCa16&mDc1Ez- zM`rE=ijn*M>ilx7ZhU_p?_&h`9ifW*H8312><=)0y+2h>8;uIbCng3s4=(EbaBbW+^4 z=A8T!h~A=x2OuoKZv`6Ktc`T|-_37Wx){mQ`fED9J>t!kszJzD#dpizq$8vFOv}y0 zA%HjYZM!4McsIv$iQ9ZJ!d&i`v(gq*$50vy_zv*m(+6!Hl^}DN=N!d=|CJBb(7y&j zBxc^bCI&_UkzNzz_ieQzIE~*t=ZS>iMW@}Z{2F}%Aj(~VFW$fd zT|Sphg=GXHEJo(pSn2bY|F0uztJniAV6iSp&ly@E(CY5%P^gV0y}{fd;jms~>|^M~ z(G9K+iGRmumP@B2q54Bx&0~~G;U&ziW&&l4=u$4`cmGwQqXNOP18wZ-r1oXMPrzlS za7~T*Z`Tw{L|$k6w-RLe6dSqeHX`DYVBR+Xv*Bm#izV+5Ks{)m*n;X*dv}R$dw9^j zCBX;H+XjanCx1Ud!XTfyN-aHgv`7Z;DZNAod@gZNt1x=xfNV;He0JNr`3S`rr=oVC z+zUC(W?}6$&-He!u#$RN4!NXgpoTt9^=B)pMw`_V^s5xi#U|S>LjFDLx5lve513XD zqM&>5Y)j@hA;P<3!MMsB-KrAR?6-vp4L{b~ozY=wUtaFFTkoH)Zj8IT7X}QJMrMRv3|3vCtFLix3qi~5N`1&L$s^u?Z#AtU8?VRGcXEjyftW%SNsxXno&rqVs z%uX%Q%?x-;*N-!Q-~yB|>ywO1IQ}%I&{_)0K5jvU)_A}kWE3BiCy|XI(n1^)N`dB8 ze;xMuEc^`_yB!;Gs9h%o3rG#X^eOkE19_dZU%$bRkg*L=M>c0NOR2D(==&@u~AyZ9N0u4t^RN| zV6&Ut@H5HK*>w>fO`Ca7DUPRdjwR%<3gt}SqLH)6dF4arr!tm~!;ii{n#kL^qP@6| z=-X%X8rJS|UKmVDq#trlHlD+jxnQ{^jO7=6iLyn3o59+=xbOHI6C)gu`ce-X;!~yM4ZhpBVX_O5RLk{y{ zxj;OZ5M>$Kb8}JtK0?0UYHlSg_GvR9xE_3Br!9I_u=q59pKfV9nyRz=OsOi>Q1P2L zBv?N_2bF|*K9+wFph-g71}Sf_bLD(#H@f@COc07SEcL6=TWxJtoWFI{hqzi%8Rbqtx{2VhvG*8Uw>JtRD3{Xv=1JQd=BpMyfr4Y5c)KdaoUYs2QAM{Slj$)5u3CXjCRWYn-N8Q{n{9#a+x8&E;~Onj{IGWN>*u zMlIGKqSU-@z+S9BzedR#X#wusTmyE=aAn>7NS^Zzprb1#%%$0_6FtCH2nxm$vFom7 z@0^tOcmvFbLwFY?!ZQ2w%LC)QTStdTFmi->VM6|UK_8L%sd5v~>V+jHzZJsWf&^>I z+arx@Yk!WJE1Po%?-qj&4>b#Ecm*sPBy~yOwPvGcO>@d)F{(-w{9=V%eN|cmd7=1l z!4+Qkcp8N)>~-JQz(TI!fVIQN6t zALOZqkk!25z3=8KTIkcz-*Zv<%mmTX9)q7Zp2g9zCtID5(adW3Hnx4kz&aJzDijK5 zD-@j3IIk~PECZ8*;t%jK5p$OF+A;ASpN5&vb$3T71P7KRDo@*Xp6#PL6X75jVGX(7 zKM5LEFq$sjM1&cMh7P|_hz+GR4ZZdLoyDE#$6DwXzBO1A7M8`9!_8Mbk=tdMq{Qn# zVOjCsph@#&I~#IzT)nFs;K?ZIsP+r{gV@EEc=1O9?-#osNr^CudZoN>oGpZi2VF8> zf%uPR^clY=BDRNOMs3ksTtvjBNqrW-ji|KwPxO3)uc`i_@q_+yrh~w13u%i#A<=H9 znagV@Oj9BNyYvvf!z6-rP)9534NvtCj*%Hc-TH&X0+>~zHFNHm=?dyJN z&eu%im3!A&GY3d7O2Y@=0MgNvYRpjd=K}}*SAWI44+Wh#n!OaW(Re+_HHw=74vZth z4@f?x?!c!J;R;{M3%#{H0V?Gx&GLd_c|M}f8Wh~ebEp2r)a{w7n@p#Ec)c179QGJUj5F6Lkd}#lIWyZ2H1i-bcfY~r-Or<;KErXTXjj7D-J)V*J4yNxZtHhv zs|uS-^KShjbK%DqKR1bBF#>N{Ijq)eR0bI}cC-GxRDHmB**7@eIqgXseJx>sFJik% zG?YQ7RDdW3tucy{A@3sQ&~v^_QT|Gd^nZqoe$odO-6BiqpZ1Y4!_ zORSOv3DBwY+KfLmu3D3*yNyC2hpz(V8ci+V^}{>Ja+A%da}u<}UUn(niNmQjyG4~p z_Iaj=^;)7Pr{$U|F1=!$$TT$$&@+hGg3Ms_com){nwu;kHzrQHB6g<9E@EDK0}HfQ zPvQF~SXgy$EPeM000tVAOD7JBd=MOJb^0}J)~UW((=KR2Lf^lrS1e-| oVohlYL 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

n7Uat!OS3K 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

Qm)+0)NRuk z3hCfQ*H>B2*h=z6;OTt*`+D8P-M=*~9X!3Oro2z_?1z3q-2^BR^KdX2he+?+FY&|j zGvge~$I`p3!y6Xzj8IZSBZ?+JOVn~7)%I*{`NGA}&Dw##Px&^Z*esXVx3P!Vj!_%> zbXrUlq1d@e^hQu*hibxJp)O`Gs79r69jJiMwgAteB|B8MUs4 zXr3J(txZY#T<~`_#^p&c$Sgn0r7rJn_mgd_F#Xj8DDExTLCMC;dnq4|#T4-P9vWN& zUHkc-!0`C{eo4O_KG|cc7_FEdSK+GcCls69;&4v{F7)(crG;qNF!(GdF!HY!rA1HP zr^x{Gq4c}6u~+?jQ6o&K(-7{cd7xJx^%s3Ds2YD>#!0P&hoQ)u!u+`EqPpPD9zTkb zPb=2O@q^`9o7pP+;jCNw-%y|jBevXsm9;S41=kfw)3RpKJE014WY9Waq7IR|D(~(aRZ%%bENgj+amW#B;Hhq`CI@l9t#H2< zk<~Yhd42}S=4BO2^4RuRsnhK^d2Vh?=H^aJzRdskI^P4L=3N$jtg5= zMkJ{_$!)pwmc%%i5#|ddug`sKKrpf=NxhWUY1ebGbQ*NJZsQooSuW+)Z&$97oW}kv%XV=Q6DRhH-f`8_KDX@t4z<)+fM6-(#qxG?oYJ{W!N%>26ua6N26iCImS zEwND{i<^k$We?{0GH*erJ0)Trb^Imj zk%+;I)rOS19MF9of>ZIhScvD4_yW7IneV5`HoJw6%6;Zp&@plUj9AIKH>gB57tCyK9lJ4;4cJ%2cH7^zJ^`VllatkWlNEYE16=y^#<6{J%bQ~(NBqZ{ z+{&#fez^DC@uR3usEyv_o&ziGi+7Me;;OS8f(X-9=Nz!Mv{9az3Z_O&GWX(s$)rQ9 zR6?cgSx1Yxt)?TO6v)i>h!>PuwmQ4(3pIlV``g zlSbNFS{+JBg4o)H&M@z-oY$guI81*P1FluPy83!vYrtt*4?&}JLTuE3jo|5@d`t0D zeDf;`fAWTbZGucDE_sw8mk-V@CVXB}dV*7r$L@;)MZM>mqEVwY#;UR(GjW*=>Ch2s zaXdxmnjF@09Qhzd&HxX1X$5RON~Y9PPrHgS`wflJ9nf8 zmvmjDy9E#W;L9sEijtII+y@JFkNT4 z^Uw_*MKl><1YUx0)3=hsN9I2hg+5Dp0m0{e&}HDwJu@L_eIawIAX@HZiQX~N>Y(-; z`~EUmAnvd3$%xFAr-4@Wf-WLuY>o#Wkh}I?6uc%p9b# z1aj-I)fw|fNr-P~KJiI;<4d&uEe^9`6yd3qZ==o4${3lIT{@P8QR}GMofry2XmZjj zSq;DDxbB%J22LDdk9b?#;B5KK!V7|}7?7t283|NY5=U=nBto@XaHl_ugtEzn;@mjw zCcb)4o>If$z5NZ%661J5YSRds(2%eEc0&oJ3!OBAS(#4Dt54aVX-iegcY;W`o)fnQ z@1#qqU48Vq?BZ|Xddn-u!D-!b{}en$X~%7!fSShgdItpnt&RpBzi4Bu$!NUFN}J60 zmRIKut|!0lH1En3zyHa<&8;S9j8O zt_GQ~2!!MZAM9dy0G)0j$H`&T=qg;ve%)i;K#|!gC_|H@m}XMdC-oh8^BD;NLQ~(W zP-6Ga=A&Xed}?u#(C=7k4X_+OC?mTCPwCAocqZ=s_1m4s0npeV1^ol(T)BnZ)N=WJ zT8a*&m27U&mFqIiGxj+v#V%OnpPc3gdU)pc8@#qbmHqna#W|jkS|HxUCmSPnpnjKP zlnj|oQ=WS-xNe&3gNK$cOKqDmd4W0vsN!;{!a*#h&6aLYB`Mq}>vG=ROlL zg+5i$cT&xFC=X+?V&6dVqb1+KY1WoQu$SZVK&`PrON-<^^NpA4aWBUjYno<>Tw{7%Y?1m~ zmDnjZ35B=|K5Z3L(K+1T0^Fns4e#+c7*>l>&U|tNO3>S~)9R0|>KGN_hjWDcp+-K< zT5f^UtsxB-A&AuhaAfU!_xQo9?G3OcN>8a?oxWaKiPsY68eOacvP1 z5sNRhr^ea~0EJv46G;zB`!-6WxUdalA4;zNfa(1QmH=nX0d3e5DrEWollE`5WsBnj z1!C82lzRfQ*&Nf}XIhpmDh!CihYTNo@sgi-geaj6E$t@_JK9H{YaI4y<){^J2*dxh zQvoC|C)wvL8p=MJM?UaKh?S?vS@WY)&ku4reO9@UOngdGRRh2z`)!$n(RLBka-&9Z zB{V%B4wRV+6(J`Yh}Fz-^PZ;pJ0*j+7?{1%U#z#0H4Z}1ue~3{5}@)9*p6G=#yfeP z4(3*Ue^i6Gq8{t96}{%m+%TIKc~fsQmS)wR8@!nd&Ihq^3IVDGoKO9v9XhuQ+UKA&{N}=wq%XR!oPxJyrUR|lUX3@Al z5E(pzYRO3(#{NM#3G79LuR4o?KGn|9~w!&JxBx_7wp!J>CtVG}8{Tv0Iz zvVG*$5;PML39^MsRy|zb-9;Mfv2B20cV;esKBXEBMa@2`_uBZ4jt+ci&v)1$7}YoZe?@Sl7;rF(af==ylawkx@1alH z?M}=g1G1^1>yR=-FmwsQo=!e7mX8L4gkZ7z)3$}~ki+XedPq+@Z+X#bpEZlm@gy9aq=5Q!e~0^{Yf7PqlyT;jF{|C5XS(otBH69q5O0?x zRZDdpQ@RPNi0O5X4>9Ze336`hxP2eFl5nHJbHr@>A;c6>nI+ZcWmI=uL}IKp0bKOiqT6PIv3QpY>f z81nJp+>u`jvY8#6v>~fsHPVcVmY^sZ^k-Qo;A9&Jx<8>VG7xI5n&|pzX%yLar<%uR zY@kk2YxU(v*>Rcp7z?-#e~~~&yt+ATQz&X)Q_C9^iR>RHa%yugbf1uZ7j&St`Q3Sn z_fLR_Z)3O^T)z<6h%_%I6TzI9?f-;TjgrIj5XF>L5EQl9f^o)qO-7OBcc*oKBgLNvYxbI$k6f_i3 zQYiz)Ig*&Mi!_dVXLi1ElG&4j(}egRQp_oXogO3HV@Ha)snNxH>Uve?qmeKj-U&U+ z*+1+12mN^BbcT-(U*|WLxkqSF6pL(SH%EExlYcZSU`yAci42wvU1IFc8b=H-)$A|0 z-_>2~qNAK(%>!F5epCTAyEr-1$AV8$ijUvvxI;EUBHj5>iJGF;0lPa|W)jYiV=|R= zO+o{l#k~&8*&(Wt8m~%&ReBjKD0;{?2O@~9GDj^&<;s^t|7ei7e0>@3U>+fQNzvb} z##tvg!Fl^XBb;N`yyeSt?biLByviA>iecjsp|TT(LpA%u6B~%Vpbkt~r2LSO(p2Zu zH5m?$VaK;|S!SJz8(9!dKk|EeQ6+kgUzM2)R@UU;(AeDU(sRpKOe1O{72!x!vToSl zJpC41<~yfKwaGO~O~WN%o7q%Lc1#(k(0tu<^^5|I<}PXl#%Hn2AUr!V?tqZ8I}r;$1s`cK2U$%&hqZ1Y4zZ(Fcuy>r)2D9nFxjU1W?6FHEH z+2qPk&OEDP&7^{-7Ga#BeTl&&mbhY>6eOw%Qr;G$0fE^)p`XN8D^L4EFvBy^> zEJUz0VKE3UQK;{j*vG2D*=#Z$gMwbJ0VO2q5x03&(G(kQ=;;fCH4EAkiDCZNAJ3n4 zf3#XNlgF50Q*ZUW4zMrf=zQzd{f!aYp0QIB=5&xB+-YI8G9J{q;9R(e%tYM;xKeq! zx_ag%jT+TW%QkX)C$4So;TXj6#_X5NuGqrX{UH?GP8 zfv-m<0pV>kM%6r+QU8FHsoQuwvY=x;E3~Y`NXV{vLW_>>3bH*woZBpOBRiy2X@RwT zaTkLIq>Jx=)en@LPl{1V`)VeoeN@@B&{evdS04zTwAf{hg?6;VkkKTJXW;2{xIw@_A-VciA?2#cJ+|_I3$8gp6=v08HQuw1s_99yj|fA&^v*~unaf&Q zB}P9@D5!G0=h|2`5|gQtrC((X9#KFKyB^z?aeDIecYr3T2V^Ce%J!%K?4tmHnIvJC zDFsHfy>8=!{XcQ6#uD19atw=#O`6q-CX_8n35$&`lZeyWKP{ggF*0lsr(zy#`JXUkM&29>Pqa-iDodYx;fX7ODNUN7L=oORbl{j6O^A9;hyJR9rA|*$)F}Zg z4t1B2Ao6L7UI0G5`vIa?a=bOEcmo6a^BA#rzt9zfRB{mN*fyv4F+PWX~X`Q z$`Yf%-93o@kt*)Th>NtE&oP_zzb)lQe zNpZ01=hG#eQADS1_@nCGO>hIuXm+|EuTuT{u7^%|C*C7<+`&1?>BKcZ7s zx%XA|WMp9(Uko6l zSRY_RtV6pyv35dw0g9k+SaUgj##0FD`|Z=rM{y;=E8(<=K|K(2d<3dyf>I;bu2M}_ zl!K?}&4PKpF}VD&@VtQ=k+fgdQI5&funJQ=&80Q93`$zn6qHfpXglaAY@-&?eyDGz+(Q-LT6J`@kpwnUsJS-Bn-iE8VBXvFcpzgvi~Z*SrdG)P_+o)@w73} zrOa7ro5#r|1im9^JaScdZ(ZDaWj+sY-c6KDd|zF^)F#UL(y93x+!8KLJMP}cgKDtq z2&Nbyh~c%KsxgaXQV={VX(#sR@W!IN8y|$uAuh197ueTbmeSU;*F9>^O^RF`9V^~? zb<*2N>iIU@h0F>|R@$wBFZRGn;)1j|IUM}^-XT|_igc4mD(gPA>ex69&D_{(j^mHs z<+J>$H+@p=eOj%5Jb&A}=7B;PTC8YmfldFUC;qnZuNH?N8W5ldyZy=X!)Np_A#gRw zNMhh!0cQ-V{`r!= zXc@q2i72jH&$~`vk5d~~u8HB;Bcyi~qnlgn%KuXR&_*17`^IPoV*)q-QHme2J1;w} z_u0-7y+JAQXkV8<&9PstUePo8m1OVp?b2n3Y^7w_J?rntFxY;&&B;!f_nAaN?k#(Z zFSTJ?`Nd5bYJ9dk24>Q>ADN#feUR_4>bhBRi@<1%W<#|Y%pup@3=91(+Uq*&=DGLY ze&?)IBqV?2%v>euz%`LF#?w**8^W>RMr8#?=oRi|t$$bCERZ=up5KwxEOu%xYvnFL zncJl7w^f=I8qSLKS=3*uA|A!IOwJruVec1=Ra&5k6Vht#GqckQV)utp^9RcL{etKM z=xxzsdYZQAQXseD)-9)J|1htUK}jNOxN(L~yzN_;jHlXN7b2vw%adK-E|M?Tdzo_t zo=QWPdZL9#?Vj&CE>_SfrhB+VY#9`}9BtHFY`YD3GZs#B?^$5FmJdd%yp(qyT6|ky8f;k>l_*@l zCVN{c4Ug1uSz7;$|E!U|`RU}F&UyjeJ;FW$OMsoSdqhU)lOSv=RlKj7z3W+Ng zt?!*hc8t(Jx4%o>7&$mY9#=dF@w&hsRX1-r6>Gbp3#*ep>sN=h6;GR{Uc59u*Gl9T z3MWa%*Xw+?5~ZRj;Q5!huNJr56}kBI zDD)lnxDyPcrv6dRXE|1~3>k1o_EAfuDWXu#=Le5=WYZxeO!8yoXvlu9lGplO&kC(Q z6O3Ho`ge3|ehKTvzS70>qs2%iQOf3@vnK!vIXE;-X+Xc+{o_ zeplh3!u^8Qq4#NF^7(#t*msMFW#RMVh5QyQPOr2ntWB=X#0G{Jt2Q_dKyGB%cvwrA~yWLNdw#nJ^L*vH8#Kd@85whmJ#BH5HA(u9QR*F-E zdUhrD({}QP>&5BpEKD-ezo8#F~31_2tWbqz3nku&##bG9VW@wR9yCRd;oT6 zW82)6K(p=IDYSgPVG0)71USi7WRed7<>l=$8T-_T$zcN^yV2P{8SsWt=c#-#^B_S! zUHU+x82jF$cKNsASw}T2^PJ9)zG0s8U?0Bw4T66f)O0$%y<71SIUaz0mb4T6Io1OS zP_BFM8*8l$BsU*x&ti~iVCw!g*NZAPH#`w`8IzK9g8U!l9^q2b#E3~5!!P~ z#pt02wO%{V^}Ryax=OM;(Z?Fm{`;rAKce?Fny{NT1K*zsQXNgGdLAu)2A}VQh5e*( zPjhJ)pw0c}xSpF`^|raQ|0@rgAgADXH>TMWT$Jm27)Nxo!zj@KNDtQOALMC>1RJcc za(d1aG0!ayhSv-r&kn1b8*g856lCfq+(fsrlq>-HV@|*Tj7bfkbtfIzPB-YmT5ys= ze@?`z9#*)Y4>5PcOh!GVoDtb;G9RJiJD`(-bK4@Ee22YWGnRa?0`CS}ehecW&M?ua$uq zNP0RC+z*UA4yxjKW{b~eCXrucuZN#62Cw)T9@3rmL z?~vpmkWg}Vr>3d<3;#h$5=-p1k>o+!K?-asGWl#VrtN86*s>8}C+6*0-o*{P7ZZbv zpCiBRoYW3@Z7K6-f^j>48Lpxue^I7S-q|=Iwj9b$;+LC`ZTvtt-GQk-KU)FM;+S5j z2CI3|8B76N*#%4XA}Tp8dC%77vqU@&0sl|1PfFL0C(k`hbbLWw&LxxP$Xi=F@en zahqoB%xBovGY6Un3;AQ&4PD5=q*Ky&z@dj!gY>V+ba<(tLGv(1AnY90SEBC!mhl`!o8tzn3`MCP~V-wGS z1?_FvQT++E+PHz$?DZHkpkJ$=t~E#cuA{4HQb=jnsD&S@a+)w+|2vQA7go0{Wu^s! zJoy(bs|#jFqPWjIO`1YYYcRd^b9>akWRZa_9h`T+)DoP^7jY&_;zf(%Pa3~S{6N@a z-bPs1eQ`E$aVCSu>iRYFYmJ^x;C+HRoxmN*2XlgM*!sJ|UoqWEu-*1SffoZ_#c#=% zEw9Gdc+Op=n`;Iy#;wv1IzBv4bmv?u>1VSO(IcK-KWI6agaIc8dy{W$`)!^665b_! z%`-2m9pD`x`njNTkT;HT>U~)r$^QQ-?5*RXe7A;QNGaO-$U#n|w?|XaAofzp;4(hJ+Bt2MN0;)kl$LfySc0_V@2&U-Qj(9te)iYfrykx6HC6xhyA`5O(($YQo5^MH;i zd?}AvbaoI-%Q;*Jz9J7_=#F8@2}Bi1*GoY}8c6fALJ9OrYc zaH^L#2*}l0@N-ODo;(Lzr?D$FQr1$&?83xpng(#!073LJ#A;|ID0(WnZtgwF!1Hqo z0+YU&4!t<9F|=dZ&a3Hk zL_DIbg6}mL-`GR{9W>ai)Q%WG$BxtDL}W6GPFH>Y&VcUEL4Ox|7EL7<@_%KyX%oiaaeDPbiQI5+7)^z-*ePST^+AD(P3!I=MFZFw^~W!&FPK}%HjWnJgi|cPnMIGvs&O4vesd|Y zH0N3=7ygs4ID}Re51|u8s-u8=QZL~&`QtkPbZG5EoG*#y{XVeB9_?J>cBn%uK2mAK zz*N5x?s-{*bEe{|=aQQ0>5H3SNaOrFAWzxA8s2n6BkavqCR1TL1oR3I=7c43mn`<3ebQNSp#m-wRwJ@U- z8v)B`Bp*1Z%aLRY3FgRj?O@({fVXb>Bk?tI_XnDVhvk!|8m7C8B1=nIWHIr+%gY1c z5WbI{J8Yzkx!|cu=@#vB<&S9+EL$DVj=b3-m!uBf`Y|$~ymV(#C7yZp#v3de_^ibq z4?L9})#q@RS;m3wFk-8%(!RCfl>ArXYrKBWt544Xz^i$%Mf-h_pdJ`Jq{6PsBp+OuJv%U?-7vz8}1B z{|>bhdt@R3MV~$$!TVmwNed(H%3ueZPxKg?;;k#q)<_wNf?fpIh%%u2m-1JizQ!nI zwYS%B_=0cw+PY+-f?v8Rb~v;{;d@X(&!8DQ0Os77N(Lf3Qx6>rPoxQgSzOWa-3g$(V(16f}Z$lLFCAtEnq<*fpr{Vg(317JeYLnp7X@@ zRXL7Pbe!)XrdH>LU^k}6%LsY$RuFqmIFU0$?wCzJ6}u&L`rC)h3*>zH;BX!MEHM@A z8ygR`&#BW6@33#Y*>cG$%XWx4k`lotS@wK1cN^Y_A3&*%fv}Z26A4a$yE)KQ*DvEx1$5iIJD*Rs=7a2 zdWY$}u$De%o^X#HH-aoRt0#xOXI5kDGMIC8>~!$)YAOIxYG*Bv6X$J+fTrvo6E}zU zpB$Yvl&M8vK=1+Eja%FxyV%!~9(Oi}=XD~SNg824-^mPoVqYHD*N?@Ibde_od3=t= zj)yzrJBEz-@v!EQ4){R%k%>n3@zO)Kz)_T5ukE;YcCVQ5LBLxv&*x&ab zf6IfLt8r?wtVfY^oANjO&}HA$NqI9Ok!X)wWs)4evasmoHdtT%+|RFs)m&YUBhijfe1k|dOvg@$#3Km2sQHLnxshLaj73_k{1W8EaQ_%XL(#=p-8S@A3^M0Q5 z3gh7`7T`L*=j@GjFK9zUJ8!!DdLKN-O_Y}vb=RD{QrquGh*Z_@9ew$RuV|IkfYf;B zDs|9FEBu(A2*X5V6a^=o4H<9u&%S_TT+cqA^~s&B=I%+h`p5fkl7>YDv@yWWPODo)=|>J{aVKfEAOC~#1ZdmL8#aWmgNa7h-NBWqiB*z}?$l7ZIRyU0oy&qCOg9*@A4G%rbxEAj8A>w&M#z8Q#g*N#X$FwER&_Ko+7 z=o=^SGWDC0jF?&O3rx@@#uoI@WGKhVgMZ&l)PJIPa`!B&O)VU`B&1xnU~%YHQhT3$H@bOnkf5nX3AbN>JPqTZ6JJ~0&St^+x7dXpad(ACXpLg8WLnB6F+V;MI8QPoe{`ek`ko~+ zxf)UIDlgQnINe-o8QHQ zzc{b+RfL~~^Ko^w8fKjafH+ zrv}ojr5;B6mEhd(F>9a#R~m@aof5U8C(W>B-Pf%@;@AV@2c&q&IN-J}A&sBEc1?F$ zeQ+>O3W_#W&U9GHI=&c+4fGIgwA>Ray^^Qhfu@&1&ljUOsMd^K76w~8!*^6&Z0N1m zX;c`V zF4^XtJ4tr8YNT!qU@rE0&j@LnYN=;cYw<29jI>&cKGvl0`#ktn`+Fn|U0;D?khfs> zZ7sg)2IFtZUsDiLV8hJ0x8QHqUdfYr)*KNM`=CoOju~(5ercAEQJDpPm`Fz0fFml` zy5@$%3Okd_T+th!i?zdVD)r6C0u)Ub1p!tjUJf5$yeT9G6)v5x;TXY8m# zveS8`Yq48?chX({o!P47ql7Q369|?}YEI`4d$R4wyD<;4UOU`1c4&Kd4K;m^2{p}c zb@)!p7YdpkiTC9=P*5cGRrR?>G^;u9ce43|(>*h?ERXS128Cy7q7}T+v~$MiuHEMV zGPf&opaIXlXVEG;>=H@cjgM@S8$ z46YltFmEc)Ffb#zSD22S$IJZ0BWhNcq#z8wx~6aTS}Q`FEz$!wETgH$?d14o1jCf1 z;gK}LUr$j>>B|FgRX9*<)fHI!CoA8p88uMAMlAv5n=-v3l z9)D7;`LR4c_G6U4Eic5`lXwYe9ss}E%n6RFr2?09ha3eW@7ZDNQAed1OI;5zMt$~l zz?=8x&#`xgAXi<}4fZO(+Qivs))4bjD0yS55`zZ(ZpjA+p^Ot})trU28(ji>kwK{R z>A{*^fAW*Ja@l01cKrJU)+oaOZN?3C0f%A402Z0dyL*n%iW3V;+)!_DP(D5a{ldqD8^E%h?V}?W|MWJ(BS$6BVPB=RqTi0Tv zZ&$03D9o2KB+>0fN2-I`@hW?m;KX(_zcUJk{an}$5thnRW$gfy&(xhHV?uT)d;Cpq z#z6mL)M9 zKI*j=F;KmHpV%|&>cf+H1BDIOb)GajL?NRcc)C_~eao-k0aAh3TmYBHQaOT~O>$-I z)zbXu11mZ7vAn?5qk5svbAB?848}*us2)5YOh}bK5bdC}B9}Q|a>9W>e#=tJpg;Y2`+@7bBMcr-|DPymY$PYg*J) zGr=$0eC*Vj7RGpVZ3cDsJ$Jj+dTQ~%iVU+1#tIpy9Fj7}Uk#U{xPe;%Os~vf-PTej zPW_;u@1sN6SfUi-tWqZ#aImG@01LJIpBL(zG)=I1pb^NN1xQhP;jnG$gw{?=Q*D;6 z>zp2|;6kwzX&#V`m*=_g>AwHfGwN2^9gem&0)4^c-`N@-O2d}wgU?3`Vv$;zqUN_~-?ASA%mR?!Ns%xzsS1oN)Z@iIr)u^ONdC=kBfT>9` zS71Znok{f;@M_x<^~*K8O|(PQ@y9O4i&n$e^NW-#CBzIT{Up5sb$_jCeOX zj)dl+EFLm|t1+S(PwC3+^9c?PXN9d5#Y-7or=Pr;lLk5sb#=1|8&gw^4BcQC1bcx_ z0Q{6ap!1D?`t%fXFI*ZP62km-x2_NtI?fJb#N4)h=R{-}6Hf!_PXZkdl|lrGx;y54 z9h=Fh_jIx-1GN0*Lc=TaBNHi2{B)zDI^_4;W-n%Dd3eM8v)zxeeTT$j*BVfY&l9I( z=ar1q;&vYwi>|Fhk1IQ^Gg)hvKRW2NRft6lDk#w47y};Rl&4kRQPqg$+-IBV><;ib zdK$oyxWPnhcddOU2&BvLtv({b?j5=h`egS!`~uFK!3V!=@w+X1Yr_{Yz@c>;F7`k~ zC(Bfhy}IJ~de0l`hV^-n({-m#w~yJ#5L#^x5K@t1dU!>EVV!d>Q$N(9K9{edn-)G&lMHn1w{3s{*9~_{Hf4?y-khtNo=t zh;x=IZ<%CIbCY>>R{A_xWKs)yPIp3jat(BQt!)K1o;NqDkr9h%3Bo(23K&150{NZ} zZRGB592z^iQ#8k89fn#($C$N969aBqnrDLv$m#noyfQ#FL@)(Ea)n?x1wr+#+1JOy zzdh5rPnrTxd-u`t)U9XtX3e+de&CawKXdtpt_|Js)p~%UHoy^NQ*FPN9B*Ve;+`k$ zO8Q!nLg9VuVZz}7HEZXuL}zUqPdK6{74UGck+A#RggJY@B1(mj75cYI zTT-b8qbYycweX9~bjrHK8t6VgjN%Q#7E7%fR{F^|2?;ah@9oMwGOMx?EQ(rM@G4G~ z7C8m-S~-3uNN0~^5&6U?86o>~8$(2-5IykIn#NB?c5smrLmR*zfQ5Lk?$2ceOn3x9 zD?xPS?+CwWjy;fZAq7C06X##!$TQ-p=PHGB=SUU3miy8~n?w`o@)6@ISwLaSKOq&Zl_Vt$!XG$U=ZG_!IfYQ-L0_uK1dGS0lfjw9Z94orYH*)E zQW*KfC_BiLV!V)Ska>b?r7Xibf){C(z=yw+kWTY=VwJiFWZaiCBK#KGI*v?Y3>k(H zT{6sXC#V!C7&AvAX z2z9?&59&&0Fh?y)j*R*1I`-6KT%W8u137TG zC+pDt#B4cw49f8FOt`bg533nO$45xBxEz)Qtum_%!0Bl(*`t=_-!*U#D&XX6Nt9#h zZdTETbg9jz=#umPT!T|yI^GrzJBK7 zo*jn&0kNh{l?P<+TMW%93uPn6+TSk$6)5bYlPQfFTPkPkJFuh}jqV=e-eU3Y4jUoZ zUU6V_D!;v^!^pD&SY40AT^8Y~u8X^VPE~)ZSMtAte=czbf!8g)1kq-PQAUTlAK)!A z<_t{palS3Px^tA5`vDP?m*`6eNk5*2R+a#g&FA8EX5SIV2wV}x0jMx;?q zjKniGA=5w(MFjFVQgA?W{r9Y$=IwbG>#RFAJxPyYexpUJj@qoH!&boru%%kYt=xDH zHAsXZui3k~E=!w33qB9I5xI+7&omh`whR=>SPP5!m=UCxgb4TG#-{;Vej+G@Vrq|N zXoZ(l#=x|!USTE*XRUy{CKtbXnp?~Cg>!{)uRl(YrkFWekHP(Bi>da>(z!s!3t!fO zO~N5{zKa`+B`((nRdQCA@?%5wYK~Mm&VDwZ5VyV|HJW~>Kz!9lnE5{GimIfH%%iPV z&yCOuDC@pG)AQ1A9G54Z)Xn()`E4TBD6Sv1Y_Re=Lc}-oSpTp*3V{#R7xgEVwe zJoDns?7kc_g>TX06Prk-@B)_RFcO#YH+i1<7^Zy{kWro!+DF{_;x08`YZNr}fU!iW(_=BYYs2NDsIF`xI;Wjzv7$($A$c$ecR)S2NEt>i zm#K_maoxGZ!%Thh3Cw=IGaMDTBxqjSnGs;?l8quiwTe%*k&9eRbZIUsusuQ@oada= zt}2qHg?zK|aheLUY?Sel`js}#rDMe!6S(~H9-bAOPRA}-{AW20hs7mf)*!Rbn~84H zoF8+^mI1cQFR6ajy9(Ix;LMD}=h$_-;(DJ2M0{SC+({ml(kBx)4MsT|b4O<>vc~E? z%eF4>Sir%nHf@r>2d0?n9j3;V-)%1>ai*Pbr`Q0%h>eo=ltLTbKLkvmc1#~qmJ2=m z!x~T_pDc?0;Dr}!A^S-dZGQif6p@AF(GlBC-P>o@@18@BPwn-jy&=^Qil7K$M$o3| zXl6N%hhx@*fCj!bEVETP6(9M(hnTxnqdny#=Q9E*_&BH@C=#;GoJfII)UR2u=Evws zqxxq<%)bW_&UV+3BgAGy4ZFJ{9xFE-)NPcSyhUowL|Wiw9((i+lPO%S@=h6Tt!7+3 z)P6GQS0>s}o=3o75Fr6^mE@p0)!gkpPX1tc(G8x@pLuPbHydewAsRNDR@Ln&pHbG0 z`i}SkHFWtHinwjJ9_lXh_`6 zbg^>V+G#P`kX6`kBpr3Xfvk(-p3sA3*rlvEQslhnk_reTZ%n)^*_Bc<<;pxtLPK*K zK2J)|8$1yW;R2Hh%wO+qwP?b=RnQ-h0a$uFHqs{-(m-ehBa8|jC7L@*V98a}>l4c-=xX=zgqLI&tH zg3w+BreViZDQ^(x5^6!eJ@WMg9#+bTY1v5T&PXzj-D!1fmR9yK=eY=A*ek45+x_G% zu_$G2@xCtIMYsxWJxEVV+OO$vTZ+J)U0DGF$MVgRlKeX;lCYwabw0?7GjziQUS-G0 z5!UB#%Sb>z+lHX@w!HM0!}_RB(O9I%CNc#m@XwM_nYeNUkz<xyrV)`B|*TuAB=)UEk-XyYbxqPn5(W&>iU(Gq(h3As(oQ=>b8U`R9d5q=SiUF#@#FFKDr?97G8?7$E1&ap7Svq3u?@xJ{v zYNg_WL&w&ObaC0Ca^z`10E#ms5}TuqyBb8i&)=o1`fUX3x@Z#D9qQz!_@(-SFNr+P zx1=l6YfxobVJ!o}?km2}2~u{st22}ljC=yjb~XKGe(U{)cU^D}W>5{ja^0Fs9fIuW zYN%Y~-Bw{A5oeYMs1mWQ0?2Mx!-|C zQr*tTc5{vBD;0Tl;|pW7@xJjzIUP_Z;xN1twv?nD%osxbMI?M(D4pLPDv)mP^k8hb z*fg?uM&b{vx&=Wy*-vlf6%ICUOcQ=1B_c|J)f0TOI-W}yFJTfd&7~Nlwc^Yofn5#w z;_k{H_(uK==#y=GA!bd?vg-5e>G+d==4u;UMlNjW7ug z5L?G`j;L!u!EI|l%!1)GY0XJyT{cInzw&aW9pp12y`*mfTCS`OnO0;gAg960pEKNI z&C^TPvE(g{K=;OVJIY8P`z|VCvCA0?Z(o*+60`ka7_(2+G1%vfE!CD^yZLLaD^D>V z{vvhb7J1M2{y^S=??gIw+ld>u)F2q{{9p;e$Jzcy?=wy!=RnSCS;2Q#*dzMdYFC>A zNz;&ioyK;VqoIZpW?wAYfnuO);^wQsOg*xtbVHrfs4tH~YuKIE6K4agQPPX~4sCah z-OVC6-D6p;hHv-=J<8U)6aMm=K3eKVY@dJVG=Bv}$m@FMd?hHaL}&LKWVqvtFsSJi zm>Sj+Wg#RpWz6>Pah$X5CNk1h>A+8cgwdUHN%_7Gc#r=FM|JWHVSJaJZGk(kKN|1C1LNkE?8);uj6I* zhZ>1sG74RSL;IiKYp$p1G~Tra)2taKhb0ZjgIVbEgfzg=wX!dYVFUNTf{dIaLz*kx zndyh_kHf19G$S}SKFP6t%gDCM;5tlyl)CZB4E#Corn@#eu0VxP_^6h*$6mg2-8JjS zk&CuR+%TDj-EB-eRH8zAh0phAL9Y^CCi1YzB?|jh+jc9~zn0q9(wT#;&AO!x>MCm8 zm2(Ai@9vLwuneG?>@ZrHk)dAk(vS?94&MpBEI@HT#!R&X6)Z9x@;?<;v^7mr$21ij z6R%*pYCVNP97``8rry&FqQdpSgIjEBj|&2}-LrEgeZdkoT?y_Ev-!5XrHTINx?08Z z(Tlc=7h6eI=~c!FoQb9Mp4+O+sP1@7^s=3LZA84`O}!u~i5+p<;|lHNX<0gKt@FU3 zgOZ5D$qY%71}oZ>Jia^DVex#LaEGKcL=H%Efr;&X++(ldNOQ|b9pqZ_iG38?XCHAO zW*>Fn8gNwtMt5|(Rmwg4*N9};%W{PQW#)C)OO2%T*gkB=KwwFl`{OK!l>qq8?atE{ zyX=D@UZ8~&ozs(uDqb!A?dUVIP}%jv$AAx+`qD(rZ0Hq5XEQ?*r0bDxC= z)exTr+lP6^h_8GVN-M?*`P(d2Y*M_u1c-7J0y(H|A6MVp^;<;)ZXn(*l_i(y)G`GCnp=k7AyjOHfh{T{@}1QUU9jKfYp>e7lcTXZGQ9N}e1}CzqrE27TSMZSe0-R% zM{W>Xw@-=5(_KPIWXP_-$(s&6-7#Z2CLRoloSE=VYMU3DXA8>dTC5|czY?`$hD279 z%*4Mqt-Htx4}~wI{U*K%ZA=$!{v>7|hA={)9=A1!B?V5x)sR3g-`Dy*C;<>tef$_N6^pxI2_Y)%^E!19(CLuh0YK)*39WuFsrD7F!#4&g##E0irNAP z=oBJ9>N$*|@;l`ZAPW~AZQ`~Q*Xg3&%`(Dx=$wF_i_d(c52J>OJB^+wOmJxM9&dp6 zvVKXbFt3#*QE8SBBXskhE`d6}Nd073AwQZ}KJ%sIhsl?F^l(1nwfGeIDJaQJYe(Gl zsiH0f{V^Zqxim2!kfCy5+n*Pqh8D0fx5>&_jt?;HDP8=Pl5sZrv;b!WLAxRrfy&w6 zWvky=SFFC7%6SV-QEbhZb=b}=O8tS=rNoYZrut!RIyX_`kT%EIlf67E<%_NwXW}`z zeIsf2@x$Xw!*Wx@O_GNd!VWfv+=4STi*nPc#|$y-K3S$OV#|rLzU3+;4@YW7 z7xmp3+!!2=J^D3}Ft|QAGU78K;oMk${MUkSv2xN~?iS@PAP+YZE-Dc;gCpH1?2@x- zHeXD2%eWT^;>NWE-PkAV>f{<}4iuHZ=n%V==GLh#6nvZLvb!nSRdM}PWYMPUs#4A~ z?;dm(K#|I>%mLUMnxZg82e~obL@SPqOaNMC!zIL%Cjro-9&|?bys5$#txRm_rdoYH z?9C|aO83d{KvUYuH1VWLmqM+(T}`Dk*N4e8`x%eFcH4Eg`@M89`wp2-$Pv{l z^1vh<hxN-cc(OUmMs371vNtcnPha#OW@ISkgOOPfBN#)*{jv! z6*BV1v3Gfr@6U2>PX6RJA6DugY&bZ&PwuZ-by~=sRcaxhAzf^Bo9xx@AsHdi@b^HL zD!}QZ4sp&if%aofewCX1#zp<*e!AXvr!_`^6q3t!O3j~Jx7qo1Ge4?xR0N#G$LFtY zcI}3Hn*LLTDzm4EeE6b%$3dZ)ha7;W;m&>H{@O;4p_<3!hoYvA7f{Ul6+nA`b|d_n zZDV+GRI2OsSKRQX8PQ2U5l+nimV_?lPuE^L0t(2_Q=QHW)W=mxG|so@HLQ67#hf#* z9_cgtT_wG4c%+)C3&2t;kv{1Yens+mG)FT?A|W+O>j` zj7DxHIZ=j&5XsIu&~DKZ2_5k-$q#X zTf4U^2GWQA3+Kqfh3uy^&Q2TSQ`L=L z2nxL4Ve{YcyiHj|i;rgAzvS^b%V~;k!;m@v$L?QA+8a-0QzEAl$TfR@2Bq;9DI|Y_ zJZs1|9in4+u+{ERV4&;ua#(cz7m{0Kgp5?7w=7F!3-T8w`JXUa$h^kQL;Q%N`MT_H z#?rY8M>scV*-`HRpKr49?m@>_#$EvJ;u{tY9qtv3B#!Nw6nQBPF`w{#4y|OdQ9FJq zoNmKbSvu?Yw?X4d4`xNHXn%UVkw2<4lz3%9-y^Hs%Rakm&6{F{bR)qsE%kW=u%`*2 z_ll2|dOHtNGGVc}4+_H4>pVG;pPn3hj7-{#-1@JeUJD} zF|nAee=bb&oN4nKj(n^6-=^V(4#DA0PaX?Q?D(Ps{R*iRT*k5_2h4lPnavS5OoH45 zRdcw%2pT9(H}Uhe$ue8h1eUPKl*;w)z=pGOy&tTbr|(O9-TpQUyg#Feh^M|ob^Zr1e+`f3Z%u&ud9O=_?l`6SVY6KqZ?nd#|w_a`kuY+eNN=@9Uy5v zpG^7hL|-N$f=|@a#nfZxTwd&|Z*Ck#9(^hYupqz&)hVrls#%QeQdj-z5t(G;xepv( zD$XK{#kIc;9S<+(e}x$%4SFHPR)6O6@Rng{<8t8>USq4CHWR(;jIqGtR3Id%E5DYX zRPv+zt=0?4e$`2z$MxmXKleZKiS!PzZ16c{mpyEku*j@?A=G*nto@?(uOsuX#v*S3 ztDY)@Je;_9L^lWPW4X{g@Y@Ir)@n4=kLA01Zn3C`G1yWzR&NxcGWRy26vDrK6Nz1%$+nu}x^Je=VIClQs z^l3fhLcy!^(7smOh{%K1;3Y(!$ZO&MM{$^#2o48(_*k$n(Z@~2O;52jFV-4vLctr3 zcX}ouMVaM(#``wdiZYvtPw)UtYKf+pHgz*7upF{4u2ddzB5D z2ViTg+eZVkkIsC(mYns|JR1%++y3=XtNNFA6GJ{vjf)^D4dI8_*AG<0#vJcUztLb` zP-$+2N2u)oSF3FzdQTg-BX!*SM79L>!9a6VJD6%O#O*!O!Mp6}VEH#!3Dti47T}~4 z@;xr^kc#aQsx8JnJ0k9djLAi>J0Id$Dn+Km|C9{?hz?LrDWpk!bCD)R@&LPXX*);c zBIJSN^>{KQ4N#)|DCG#g=eLxutq9Q_J|>IQ7g8B3NPqH`;d4aCfCsJXAAOhq=|R&@ z`g2x*!=acK`yB0BO%jhMI;c>s5+r{AsyID{fo| zKzTY80Q;D*L)qUsr&0O@(O%P?#|vI187!6&cUNPDo)^8c3yY@ZI1(FZ>%ow23(~6crRT2`kC-H5daU4za?}me1yL+LHO{N;dE^RpL9( zr(XS$8uIT;jFKc>&aA$|aIvTD>C@jr6A}5)lAJNFM^~8_H8c-LuDqKvPOZ&nJ>oBl z5bK3Z;3N(JCedj~m3i;S^`VKWV?Ao}jX!!xfN$7Tw{UikqdpA0VQ=0zB5^mer^C(F ze^B<5v#znPJ#|$UK=poxq@7ZC0(4s-<=f6L?N1VrT_vJB3o?HW*#G-r67uP$5+Xk! z$N0eRR0j}y77+U}$wulz^v661fC8mXf~3q8<9DX8ktcdYje&-qS66M48 z_W@}_Jp_#Lj8GgFkZa>;2ekRvVDDl{H8rIIM1^@m)`}dH*d{cALB2)bTek75|FZEkdQA%niC(g*o@=x&s{D;4p?j;WoK8fVW?MzRZQ=d z@DBN53`V~2Bz=TJd8(d2{;R@0JP+)TvJ@jA*@vd26&2~cuvuQvw^>3jQC2pN>Ft26 z^B%3yF}x9@l;xbcFHmt;>_bR&u~g09;iv$M=V35T>s09A?c%Az!J$0rHIdIA36^m+ zItvEzSNW=Fbl}ErE58{AWf`jv-!qDub^-0=Obd!{@AkXU*8s3D7AwFHBN6vZhy&luE>|~ zmEy!lT~|3G2du&b*6?W<<_(#7S~>nH2Im@=`ANiKqVo}K;^42!-{ivcQ!51TRKUSl zPZ(^EEPe{;jXkAG3CuIU7@&&l6&{jBKB+kdTh4e09NZm`!jFMV`A`4(LiQVDWbuOZ z=g#fy=R@?@j|>wX3739S^keuLNtTdVCNv$rRfzRK$3=`6}x_}^)??*$m5mGlOlw) z(7--)#n*MDcfAx4&vHsQ5hKcp_Mw-i@uAb^*?D@qI7p_ae83VK){QpkbZ=w7` zeC{Imxb7Ro7S~mbzAMU37F=&PGLT+(jt)A)gts%KUa%3k>UE3{=~4gVzk%oBNPX^N zI$QFT2^@-6kjI{FCF|K{-eZ0fwN<6Q-iS)MSfNnZhX5F>!CG}q$l_}q_Lz3qd)|nmU>W&$0#V6~r{b6j_2n+-dipmXF zN(!^hr0Y@peg;VMV}A@(DneQa^?gF;A5;797yCiRYMdFkINn31zmi{QZXjJ;wBe0; z7pVG&FCp3%EUWvh;QDM7TDWdFN;$cHHe}~8o!rX8U=nrw*B4qMP$U6+l+4Yt6bR}X zWEa+HB1#o14$YQ#|ERhFA!dTh2UEC_(dt57gBc!A!)%*b&DjP^*LQ>6f3V(v8Ie+W zQ}QUraG<}7U8>GaA5&1u0TK7YL^hhBi)*XgrgZ=L{&O(|6{T%E0|qm&y1;3FGwA2p z`aOLrXCpZJ$DaiImqxvy1MMpcrF^nAA)C$2D>66Co`CI0n2%x}qYMrnr~X3$EMA4^ z2@b7f4VQZ4F3*fs7wKAf15y>_N(()aq38OKcKvT%7$CJS<{iv;<;9N4nAO&uwFT5; zAIy5A9eq(te-sX|t%;{+-YaYC$kCNmHh2D1X`vW5*{pvE^zU(a$k=7dmTfHP{&}Xh z4*O;_zi}vN$0s$ze+3Qt!^~$3x!AV{aP{S9%s}h0TMe)IYkx1UQ?7rVkF+M;=SvfY z1F=2Qh0dmvLl<0XM<>Du#a{Z^|Bz`ei-2En+F9&q=zw)JNPl+Bq=ki{WcnlR{~nhA ztd}q%fu~;$e+498tXB=ms9~rP#%}l7x&CSM_yn_pV!i1^x$aTh2n>~0{~Bdv!)DB1 z$GwM0zz}ITHb9idvmzveni$C1F?%)jr{$hWG_LL%!U7BwCh>GKxT@}EtGQJ_}6t|i-60}J9aY@ABsHp?$31X|MjQ&o`VpS2%gi~Z-0~}4PV5B mKiFmY(|r8?*APpBOMFFpcw1vOG9C~3QGcLwzx19(=>G!}MRKYD literal 0 HcmV?d00001 From 408899dac8f9bf20a40f9af6ccaedba418ba21ff Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 19:48:22 -0700 Subject: [PATCH 27/83] fix - send emails on crossing team budget --- litellm/integrations/email_alerting.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/litellm/integrations/email_alerting.py b/litellm/integrations/email_alerting.py index 0a959433e1..434efb63b0 100644 --- a/litellm/integrations/email_alerting.py +++ b/litellm/integrations/email_alerting.py @@ -107,9 +107,9 @@ async def send_team_budget_alert(webhook_event: WebhookEvent) -> bool: ) email_html_content = f""" - LiteLLM Logo
+ LiteLLM Logo


- Budget Crossed for Team {team_alias}
+ Budget Crossed for Team {team_alias}

Your Teams LLM API usage has crossed it's budget of ${max_budget} , current spend is ${webhook_event.spend}

@@ -123,7 +123,7 @@ async def send_team_budget_alert(webhook_event: WebhookEvent) -> bool: email_event = { "to": recipient_emails_str, - "subject": f"LiteLLM: {event_name}", + "subject": f"LiteLLM {event_name} for Team {team_alias}", "html": email_html_content, } From 09b1d52ea19289953185e097f94a700e056fa104 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 20:11:16 -0700 Subject: [PATCH 28/83] fix send emails to team members --- .../common_utils/management_endpoint_utils.py | 90 ++++++++++--------- litellm/proxy/proxy_server.py | 2 +- 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/litellm/proxy/common_utils/management_endpoint_utils.py b/litellm/proxy/common_utils/management_endpoint_utils.py index eca385d079..2b4465caf7 100644 --- a/litellm/proxy/common_utils/management_endpoint_utils.py +++ b/litellm/proxy/common_utils/management_endpoint_utils.py @@ -2,6 +2,7 @@ from datetime import datetime from functools import wraps from litellm.proxy._types import UserAPIKeyAuth, ManagementEndpointLoggingPayload from litellm.proxy.common_utils.http_parsing_utils import _read_request_body +from litellm._logging import verbose_logger from fastapi import Request @@ -20,53 +21,58 @@ def management_endpoint_wrapper(func): try: result = await func(*args, **kwargs) end_time = datetime.now() + try: + if kwargs is None: + kwargs = {} + user_api_key_dict: UserAPIKeyAuth = ( + kwargs.get("user_api_key_dict") or UserAPIKeyAuth() + ) + _http_request: Request = kwargs.get("http_request") + parent_otel_span = user_api_key_dict.parent_otel_span + if parent_otel_span is not None: + from litellm.proxy.proxy_server import open_telemetry_logger - if kwargs is None: - kwargs = {} - user_api_key_dict: UserAPIKeyAuth = ( - kwargs.get("user_api_key_dict") or UserAPIKeyAuth() - ) - _http_request: Request = kwargs.get("http_request") - parent_otel_span = user_api_key_dict.parent_otel_span - if parent_otel_span is not None: - from litellm.proxy.proxy_server import open_telemetry_logger + if open_telemetry_logger is not None: + if _http_request: + _route = _http_request.url.path + _request_body: dict = await _read_request_body( + request=_http_request + ) + _response = dict(result) if result is not None else None + + logging_payload = ManagementEndpointLoggingPayload( + route=_route, + request_data=_request_body, + response=_response, + start_time=start_time, + end_time=end_time, + ) + + await open_telemetry_logger.async_management_endpoint_success_hook( + logging_payload=logging_payload, + parent_otel_span=parent_otel_span, + ) - if open_telemetry_logger is not None: if _http_request: _route = _http_request.url.path - _request_body: dict = await _read_request_body( - request=_http_request - ) - _response = dict(result) if result is not None else None + # Flush user_api_key cache if this was an update/delete call to /key, /team, or /user + if _route in [ + "/key/update", + "/key/delete", + "/team/update", + "/team/delete", + "/user/update", + "/user/delete", + "/customer/update", + "/customer/delete", + ]: + from litellm.proxy.proxy_server import user_api_key_cache - logging_payload = ManagementEndpointLoggingPayload( - route=_route, - request_data=_request_body, - response=_response, - start_time=start_time, - end_time=end_time, - ) - - await open_telemetry_logger.async_management_endpoint_success_hook( - logging_payload=logging_payload, - parent_otel_span=parent_otel_span, - ) - if _http_request: - _route = _http_request.url.path - # Flush user_api_key cache if this was an update/delete call to /key, /team, or /user - if _route in [ - "/key/update", - "/key/delete", - "/team/update", - "/team/delete", - "/user/update", - "/user/delete", - "/customer/update", - "/customer/delete", - ]: - from litellm.proxy.proxy_server import user_api_key_cache - - user_api_key_cache.flush_cache() + user_api_key_cache.flush_cache() + except Exception as e: + # Non-Blocking Exception + verbose_logger.debug("Error in management endpoint wrapper: %s", str(e)) + pass return result except Exception as e: diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index fe2401596e..ff44d4154b 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -8915,7 +8915,7 @@ async def new_user(data: NewUserRequest): ), ), http_request=Request( - scope={"type": "http"}, + scope={"type": "http", "path": "/user/new"}, ), ) From b6fee33307c0363011d24444b910b0b014161286 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 20:23:10 -0700 Subject: [PATCH 29/83] fix redact_message_input_output_from_logging --- litellm/litellm_core_utils/redact_messages.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/litellm/litellm_core_utils/redact_messages.py b/litellm/litellm_core_utils/redact_messages.py index d6dcb489f5..92a6f5c280 100644 --- a/litellm/litellm_core_utils/redact_messages.py +++ b/litellm/litellm_core_utils/redact_messages.py @@ -30,7 +30,6 @@ def redact_message_input_output_from_logging( if litellm.turn_off_message_logging is not True: return result - _result = copy.deepcopy(result) # remove messages, prompts, input, response from logging litellm_logging_obj.model_call_details["messages"] = [ {"role": "user", "content": "redacted-by-litellm"} @@ -53,8 +52,10 @@ def redact_message_input_output_from_logging( elif isinstance(choice, litellm.utils.StreamingChoices): choice.delta.content = "redacted-by-litellm" else: - if _result is not None: - if isinstance(_result, litellm.ModelResponse): + if result is not None: + if isinstance(result, litellm.ModelResponse): + # only deep copy litellm.ModelResponse + _result = copy.deepcopy(result) if hasattr(_result, "choices") and _result.choices is not None: for choice in _result.choices: if isinstance(choice, litellm.Choices): From 18f36b38f0d4aa8ecb5b0b9017b582e643335675 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Jun 2024 20:33:02 -0700 Subject: [PATCH 30/83] ui - new build --- litellm/proxy/_experimental/out/404.html | 1 + .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../out/_next/static/chunks/131-19b05e5ce40fa85d.js | 8 ++++++++ .../out/_next/static/chunks/131-cb6bfe24e23e121b.js | 8 -------- .../out/_next/static/chunks/294-0e35509d5ca95267.js | 13 +++++++++++++ .../static/chunks/2f6dbc85-052c4579f80d66ae.js | 1 + .../static/chunks/2f6dbc85-cac2949a76539886.js | 1 - .../static/chunks/3014691f-589a5f4865c3822f.js | 1 + .../static/chunks/3014691f-b24e8254c7593934.js | 1 - .../out/_next/static/chunks/505-5ff3c318fddfa35c.js | 13 ------------- .../out/_next/static/chunks/684-16b194c83a169f6d.js | 1 - .../out/_next/static/chunks/684-bb2d2f93d92acb0b.js | 1 + .../out/_next/static/chunks/69-04708d7d4a17c1ee.js | 1 + .../out/_next/static/chunks/69-8316d07d1f41e39f.js | 1 - .../out/_next/static/chunks/759-c0083d8a782d300e.js | 13 ------------- .../out/_next/static/chunks/759-d7572f2a46f911d5.js | 13 +++++++++++++ ...1cb6a88df1.js => _not-found-b1ee1381b72386c2.js} | 2 +- ...3f654c7747e999.js => layout-9bbef188642a56c0.js} | 2 +- .../chunks/app/model_hub/page-4cb65c32467214b5.js | 1 + .../chunks/app/model_hub/page-a1942d43573c82c3.js | 1 - .../chunks/app/onboarding/page-49a30e653b6ae929.js | 1 - .../chunks/app/onboarding/page-664c7288e11fff5a.js | 1 + .../static/chunks/app/page-4c5ebd62e10ab7aa.js | 1 + .../static/chunks/app/page-8028473f1a04553d.js | 1 - .../static/chunks/fd9d1056-f593049e31b05aeb.js | 1 - .../static/chunks/fd9d1056-f960ab1e6d32b002.js | 1 + ...a61244f130fbf565.js => main-160227023782230a.js} | 2 +- ...38c8e1915716.js => main-app-9b4fb13a7db53edf.js} | 2 +- ...c75b16b85d4b4.js => webpack-496e007a0280178b.js} | 2 +- .../out/_next/static/css/159e0004b5599df8.css | 5 +++++ .../out/_next/static/css/63f65dbb14efd996.css | 5 ----- litellm/proxy/_experimental/out/index.html | 2 +- litellm/proxy/_experimental/out/index.txt | 4 ++-- litellm/proxy/_experimental/out/model_hub.html | 1 + litellm/proxy/_experimental/out/model_hub.txt | 4 ++-- litellm/proxy/_experimental/out/onboarding.html | 1 + litellm/proxy/_experimental/out/onboarding.txt | 4 ++-- ui/litellm-dashboard/out/404.html | 2 +- .../static/QKxw7XOxQ8siV-V22vqEN/_buildManifest.js | 1 + .../static/QKxw7XOxQ8siV-V22vqEN/_ssgManifest.js | 1 + .../out/_next/static/chunks/131-19b05e5ce40fa85d.js | 8 ++++++++ .../out/_next/static/chunks/294-0e35509d5ca95267.js | 13 +++++++++++++ .../static/chunks/2f6dbc85-052c4579f80d66ae.js | 1 + .../static/chunks/3014691f-589a5f4865c3822f.js | 1 + .../out/_next/static/chunks/684-bb2d2f93d92acb0b.js | 1 + .../out/_next/static/chunks/69-04708d7d4a17c1ee.js | 1 + .../out/_next/static/chunks/759-d7572f2a46f911d5.js | 13 +++++++++++++ .../chunks/app/_not-found-b1ee1381b72386c2.js | 1 + .../static/chunks/app/layout-9bbef188642a56c0.js | 1 + .../chunks/app/model_hub/page-4cb65c32467214b5.js | 1 + .../chunks/app/onboarding/page-664c7288e11fff5a.js | 1 + .../static/chunks/app/page-4c5ebd62e10ab7aa.js | 1 + .../static/chunks/fd9d1056-f960ab1e6d32b002.js | 1 + .../_next/static/chunks/main-160227023782230a.js | 1 + .../static/chunks/main-app-9b4fb13a7db53edf.js | 1 + .../_next/static/chunks/webpack-496e007a0280178b.js | 1 + .../out/_next/static/css/159e0004b5599df8.css | 5 +++++ ui/litellm-dashboard/out/index.html | 2 +- ui/litellm-dashboard/out/index.txt | 4 ++-- ui/litellm-dashboard/out/model_hub.html | 2 +- ui/litellm-dashboard/out/model_hub.txt | 4 ++-- ui/litellm-dashboard/out/onboarding.html | 2 +- ui/litellm-dashboard/out/onboarding.txt | 4 ++-- 64 files changed, 126 insertions(+), 69 deletions(-) create mode 100644 litellm/proxy/_experimental/out/404.html rename litellm/proxy/_experimental/out/_next/static/{sTvd1VbHSi_TBr1KiIpul => QKxw7XOxQ8siV-V22vqEN}/_buildManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/{sTvd1VbHSi_TBr1KiIpul => QKxw7XOxQ8siV-V22vqEN}/_ssgManifest.js (100%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/131-19b05e5ce40fa85d.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/131-cb6bfe24e23e121b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/294-0e35509d5ca95267.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2f6dbc85-052c4579f80d66ae.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2f6dbc85-cac2949a76539886.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3014691f-589a5f4865c3822f.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3014691f-b24e8254c7593934.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/505-5ff3c318fddfa35c.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/684-16b194c83a169f6d.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/684-bb2d2f93d92acb0b.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/69-04708d7d4a17c1ee.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/69-8316d07d1f41e39f.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/759-c0083d8a782d300e.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/759-d7572f2a46f911d5.js rename litellm/proxy/_experimental/out/_next/static/chunks/app/{_not-found-4163791cb6a88df1.js => _not-found-b1ee1381b72386c2.js} (96%) rename litellm/proxy/_experimental/out/_next/static/chunks/app/{layout-1c3f654c7747e999.js => layout-9bbef188642a56c0.js} (60%) create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/model_hub/page-4cb65c32467214b5.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/model_hub/page-a1942d43573c82c3.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-49a30e653b6ae929.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/onboarding/page-664c7288e11fff5a.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-4c5ebd62e10ab7aa.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-8028473f1a04553d.js delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/fd9d1056-f593049e31b05aeb.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/fd9d1056-f960ab1e6d32b002.js rename litellm/proxy/_experimental/out/_next/static/chunks/{main-a61244f130fbf565.js => main-160227023782230a.js} (99%) rename litellm/proxy/_experimental/out/_next/static/chunks/{main-app-096338c8e1915716.js => main-app-9b4fb13a7db53edf.js} (54%) rename litellm/proxy/_experimental/out/_next/static/chunks/{webpack-887c75b16b85d4b4.js => webpack-496e007a0280178b.js} (98%) create mode 100644 litellm/proxy/_experimental/out/_next/static/css/159e0004b5599df8.css delete mode 100644 litellm/proxy/_experimental/out/_next/static/css/63f65dbb14efd996.css create mode 100644 litellm/proxy/_experimental/out/model_hub.html create mode 100644 litellm/proxy/_experimental/out/onboarding.html create mode 100644 ui/litellm-dashboard/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_buildManifest.js create mode 100644 ui/litellm-dashboard/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_ssgManifest.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/131-19b05e5ce40fa85d.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/294-0e35509d5ca95267.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/2f6dbc85-052c4579f80d66ae.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/3014691f-589a5f4865c3822f.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/684-bb2d2f93d92acb0b.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/69-04708d7d4a17c1ee.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/759-d7572f2a46f911d5.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/_not-found-b1ee1381b72386c2.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/layout-9bbef188642a56c0.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/model_hub/page-4cb65c32467214b5.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/onboarding/page-664c7288e11fff5a.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/page-4c5ebd62e10ab7aa.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/fd9d1056-f960ab1e6d32b002.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/main-160227023782230a.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/main-app-9b4fb13a7db53edf.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/webpack-496e007a0280178b.js create mode 100644 ui/litellm-dashboard/out/_next/static/css/159e0004b5599df8.css diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html new file mode 100644 index 0000000000..794e8d66ae --- /dev/null +++ b/litellm/proxy/_experimental/out/404.html @@ -0,0 +1 @@ +404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/sTvd1VbHSi_TBr1KiIpul/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_buildManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/sTvd1VbHSi_TBr1KiIpul/_buildManifest.js rename to litellm/proxy/_experimental/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_buildManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/sTvd1VbHSi_TBr1KiIpul/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_ssgManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/sTvd1VbHSi_TBr1KiIpul/_ssgManifest.js rename to litellm/proxy/_experimental/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/131-19b05e5ce40fa85d.js b/litellm/proxy/_experimental/out/_next/static/chunks/131-19b05e5ce40fa85d.js new file mode 100644 index 0000000000..92aaed0ddd --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/131-19b05e5ce40fa85d.js @@ -0,0 +1,8 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[131],{84174:function(e,t,n){n.d(t,{Z:function(){return s}});var a=n(14749),r=n(64090),i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"}}]},name:"copy",theme:"outlined"},o=n(60688),s=r.forwardRef(function(e,t){return r.createElement(o.Z,(0,a.Z)({},e,{ref:t,icon:i}))})},50459:function(e,t,n){n.d(t,{Z:function(){return s}});var a=n(14749),r=n(64090),i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"}}]},name:"right",theme:"outlined"},o=n(60688),s=r.forwardRef(function(e,t){return r.createElement(o.Z,(0,a.Z)({},e,{ref:t,icon:i}))})},92836:function(e,t,n){n.d(t,{Z:function(){return p}});var a=n(69703),r=n(80991),i=n(2898),o=n(99250),s=n(65492),l=n(64090),c=n(41608),d=n(50027);n(18174),n(21871),n(41213);let u=(0,s.fn)("Tab"),p=l.forwardRef((e,t)=>{let{icon:n,className:p,children:g}=e,m=(0,a._T)(e,["icon","className","children"]),b=(0,l.useContext)(c.O),f=(0,l.useContext)(d.Z);return l.createElement(r.O,Object.assign({ref:t,className:(0,o.q)(u("root"),"flex whitespace-nowrap truncate max-w-xs outline-none focus:ring-0 text-tremor-default transition duration-100",f?(0,s.bM)(f,i.K.text).selectTextColor:"solid"===b?"ui-selected:text-tremor-content-emphasis dark:ui-selected:text-dark-tremor-content-emphasis":"ui-selected:text-tremor-brand dark:ui-selected:text-dark-tremor-brand",function(e,t){switch(e){case"line":return(0,o.q)("ui-selected:border-b-2 hover:border-b-2 border-transparent transition duration-100 -mb-px px-2 py-2","hover:border-tremor-content hover:text-tremor-content-emphasis text-tremor-content","dark:hover:border-dark-tremor-content-emphasis dark:hover:text-dark-tremor-content-emphasis dark:text-dark-tremor-content",t?(0,s.bM)(t,i.K.border).selectBorderColor:"ui-selected:border-tremor-brand dark:ui-selected:border-dark-tremor-brand");case"solid":return(0,o.q)("border-transparent border rounded-tremor-small px-2.5 py-1","ui-selected:border-tremor-border ui-selected:bg-tremor-background ui-selected:shadow-tremor-input hover:text-tremor-content-emphasis ui-selected:text-tremor-brand","dark:ui-selected:border-dark-tremor-border dark:ui-selected:bg-dark-tremor-background dark:ui-selected:shadow-dark-tremor-input dark:hover:text-dark-tremor-content-emphasis dark:ui-selected:text-dark-tremor-brand",t?(0,s.bM)(t,i.K.text).selectTextColor:"text-tremor-content dark:text-dark-tremor-content")}}(b,f),p)},m),n?l.createElement(n,{className:(0,o.q)(u("icon"),"flex-none h-5 w-5",g?"mr-2":"")}):null,g?l.createElement("span",null,g):null)});p.displayName="Tab"},26734:function(e,t,n){n.d(t,{Z:function(){return c}});var a=n(69703),r=n(80991),i=n(99250),o=n(65492),s=n(64090);let l=(0,o.fn)("TabGroup"),c=s.forwardRef((e,t)=>{let{defaultIndex:n,index:o,onIndexChange:c,children:d,className:u}=e,p=(0,a._T)(e,["defaultIndex","index","onIndexChange","children","className"]);return s.createElement(r.O.Group,Object.assign({as:"div",ref:t,defaultIndex:n,selectedIndex:o,onChange:c,className:(0,i.q)(l("root"),"w-full",u)},p),d)});c.displayName="TabGroup"},41608:function(e,t,n){n.d(t,{O:function(){return c},Z:function(){return u}});var a=n(69703),r=n(64090),i=n(50027);n(18174),n(21871),n(41213);var o=n(80991),s=n(99250);let l=(0,n(65492).fn)("TabList"),c=(0,r.createContext)("line"),d={line:(0,s.q)("flex border-b space-x-4","border-tremor-border","dark:border-dark-tremor-border"),solid:(0,s.q)("inline-flex p-0.5 rounded-tremor-default space-x-1.5","bg-tremor-background-subtle","dark:bg-dark-tremor-background-subtle")},u=r.forwardRef((e,t)=>{let{color:n,variant:u="line",children:p,className:g}=e,m=(0,a._T)(e,["color","variant","children","className"]);return r.createElement(o.O.List,Object.assign({ref:t,className:(0,s.q)(l("root"),"justify-start overflow-x-clip",d[u],g)},m),r.createElement(c.Provider,{value:u},r.createElement(i.Z.Provider,{value:n},p)))});u.displayName="TabList"},32126:function(e,t,n){n.d(t,{Z:function(){return d}});var a=n(69703);n(50027);var r=n(18174);n(21871);var i=n(41213),o=n(99250),s=n(65492),l=n(64090);let c=(0,s.fn)("TabPanel"),d=l.forwardRef((e,t)=>{let{children:n,className:s}=e,d=(0,a._T)(e,["children","className"]),{selectedValue:u}=(0,l.useContext)(i.Z),p=u===(0,l.useContext)(r.Z);return l.createElement("div",Object.assign({ref:t,className:(0,o.q)(c("root"),"w-full mt-2",p?"":"hidden",s),"aria-selected":p?"true":"false"},d),n)});d.displayName="TabPanel"},23682:function(e,t,n){n.d(t,{Z:function(){return u}});var a=n(69703),r=n(80991);n(50027);var i=n(18174);n(21871);var o=n(41213),s=n(99250),l=n(65492),c=n(64090);let d=(0,l.fn)("TabPanels"),u=c.forwardRef((e,t)=>{let{children:n,className:l}=e,u=(0,a._T)(e,["children","className"]);return c.createElement(r.O.Panels,Object.assign({as:"div",ref:t,className:(0,s.q)(d("root"),"w-full",l)},u),e=>{let{selectedIndex:t}=e;return c.createElement(o.Z.Provider,{value:{selectedValue:t}},c.Children.map(n,(e,t)=>c.createElement(i.Z.Provider,{value:t},e)))})});u.displayName="TabPanels"},50027:function(e,t,n){n.d(t,{Z:function(){return i}});var a=n(64090),r=n(54942);n(99250);let i=(0,a.createContext)(r.fr.Blue)},18174:function(e,t,n){n.d(t,{Z:function(){return a}});let a=(0,n(64090).createContext)(0)},21871:function(e,t,n){n.d(t,{Z:function(){return a}});let a=(0,n(64090).createContext)(void 0)},41213:function(e,t,n){n.d(t,{Z:function(){return a}});let a=(0,n(64090).createContext)({selectedValue:void 0,handleValueChange:void 0})},21467:function(e,t,n){n.d(t,{i:function(){return s}});var a=n(64090),r=n(44329),i=n(54165),o=n(57499);function s(e){return t=>a.createElement(i.ZP,{theme:{token:{motion:!1,zIndexPopupBase:0}}},a.createElement(e,Object.assign({},t)))}t.Z=(e,t,n,i)=>s(s=>{let{prefixCls:l,style:c}=s,d=a.useRef(null),[u,p]=a.useState(0),[g,m]=a.useState(0),[b,f]=(0,r.Z)(!1,{value:s.open}),{getPrefixCls:E}=a.useContext(o.E_),h=E(t||"select",l);a.useEffect(()=>{if(f(!0),"undefined"!=typeof ResizeObserver){let e=new ResizeObserver(e=>{let t=e[0].target;p(t.offsetHeight+8),m(t.offsetWidth)}),t=setInterval(()=>{var a;let r=n?".".concat(n(h)):".".concat(h,"-dropdown"),i=null===(a=d.current)||void 0===a?void 0:a.querySelector(r);i&&(clearInterval(t),e.observe(i))},10);return()=>{clearInterval(t),e.disconnect()}}},[]);let S=Object.assign(Object.assign({},s),{style:Object.assign(Object.assign({},c),{margin:0}),open:b,visible:b,getPopupContainer:()=>d.current});return i&&(S=i(S)),a.createElement("div",{ref:d,style:{paddingBottom:u,position:"relative",minWidth:g}},a.createElement(e,Object.assign({},S)))})},99129:function(e,t,n){let a;n.d(t,{Z:function(){return eY}});var r=n(63787),i=n(64090),o=n(37274),s=n(57499),l=n(54165),c=n(99537),d=n(77136),u=n(20653),p=n(40388),g=n(16480),m=n.n(g),b=n(51761),f=n(47387),E=n(70595),h=n(24750),S=n(89211),y=n(1861),T=n(51350),A=e=>{let{type:t,children:n,prefixCls:a,buttonProps:r,close:o,autoFocus:s,emitEvent:l,isSilent:c,quitOnNullishReturnValue:d,actionFn:u}=e,p=i.useRef(!1),g=i.useRef(null),[m,b]=(0,S.Z)(!1),f=function(){null==o||o.apply(void 0,arguments)};i.useEffect(()=>{let e=null;return s&&(e=setTimeout(()=>{var e;null===(e=g.current)||void 0===e||e.focus()})),()=>{e&&clearTimeout(e)}},[]);let E=e=>{e&&e.then&&(b(!0),e.then(function(){b(!1,!0),f.apply(void 0,arguments),p.current=!1},e=>{if(b(!1,!0),p.current=!1,null==c||!c())return Promise.reject(e)}))};return i.createElement(y.ZP,Object.assign({},(0,T.nx)(t),{onClick:e=>{let t;if(!p.current){if(p.current=!0,!u){f();return}if(l){var n;if(t=u(e),d&&!((n=t)&&n.then)){p.current=!1,f(e);return}}else if(u.length)t=u(o),p.current=!1;else if(!(t=u())){f();return}E(t)}},loading:m,prefixCls:a},r,{ref:g}),n)};let R=i.createContext({}),{Provider:I}=R;var N=()=>{let{autoFocusButton:e,cancelButtonProps:t,cancelTextLocale:n,isSilent:a,mergedOkCancel:r,rootPrefixCls:o,close:s,onCancel:l,onConfirm:c}=(0,i.useContext)(R);return r?i.createElement(A,{isSilent:a,actionFn:l,close:function(){null==s||s.apply(void 0,arguments),null==c||c(!1)},autoFocus:"cancel"===e,buttonProps:t,prefixCls:"".concat(o,"-btn")},n):null},_=()=>{let{autoFocusButton:e,close:t,isSilent:n,okButtonProps:a,rootPrefixCls:r,okTextLocale:o,okType:s,onConfirm:l,onOk:c}=(0,i.useContext)(R);return i.createElement(A,{isSilent:n,type:s||"primary",actionFn:c,close:function(){null==t||t.apply(void 0,arguments),null==l||l(!0)},autoFocus:"ok"===e,buttonProps:a,prefixCls:"".concat(r,"-btn")},o)},v=n(81303),w=n(14749),k=n(80406),C=n(88804),O=i.createContext({}),x=n(5239),L=n(31506),D=n(91010),P=n(4295),M=n(72480);function F(e,t,n){var a=t;return!a&&n&&(a="".concat(e,"-").concat(n)),a}function U(e,t){var n=e["page".concat(t?"Y":"X","Offset")],a="scroll".concat(t?"Top":"Left");if("number"!=typeof n){var r=e.document;"number"!=typeof(n=r.documentElement[a])&&(n=r.body[a])}return n}var B=n(49367),G=n(74084),$=i.memo(function(e){return e.children},function(e,t){return!t.shouldUpdate}),H={width:0,height:0,overflow:"hidden",outline:"none"},z=i.forwardRef(function(e,t){var n,a,r,o=e.prefixCls,s=e.className,l=e.style,c=e.title,d=e.ariaId,u=e.footer,p=e.closable,g=e.closeIcon,b=e.onClose,f=e.children,E=e.bodyStyle,h=e.bodyProps,S=e.modalRender,y=e.onMouseDown,T=e.onMouseUp,A=e.holderRef,R=e.visible,I=e.forceRender,N=e.width,_=e.height,v=e.classNames,k=e.styles,C=i.useContext(O).panel,L=(0,G.x1)(A,C),D=(0,i.useRef)(),P=(0,i.useRef)();i.useImperativeHandle(t,function(){return{focus:function(){var e;null===(e=D.current)||void 0===e||e.focus()},changeActive:function(e){var t=document.activeElement;e&&t===P.current?D.current.focus():e||t!==D.current||P.current.focus()}}});var M={};void 0!==N&&(M.width=N),void 0!==_&&(M.height=_),u&&(n=i.createElement("div",{className:m()("".concat(o,"-footer"),null==v?void 0:v.footer),style:(0,x.Z)({},null==k?void 0:k.footer)},u)),c&&(a=i.createElement("div",{className:m()("".concat(o,"-header"),null==v?void 0:v.header),style:(0,x.Z)({},null==k?void 0:k.header)},i.createElement("div",{className:"".concat(o,"-title"),id:d},c))),p&&(r=i.createElement("button",{type:"button",onClick:b,"aria-label":"Close",className:"".concat(o,"-close")},g||i.createElement("span",{className:"".concat(o,"-close-x")})));var F=i.createElement("div",{className:m()("".concat(o,"-content"),null==v?void 0:v.content),style:null==k?void 0:k.content},r,a,i.createElement("div",(0,w.Z)({className:m()("".concat(o,"-body"),null==v?void 0:v.body),style:(0,x.Z)((0,x.Z)({},E),null==k?void 0:k.body)},h),f),n);return i.createElement("div",{key:"dialog-element",role:"dialog","aria-labelledby":c?d:null,"aria-modal":"true",ref:L,style:(0,x.Z)((0,x.Z)({},l),M),className:m()(o,s),onMouseDown:y,onMouseUp:T},i.createElement("div",{tabIndex:0,ref:D,style:H,"aria-hidden":"true"}),i.createElement($,{shouldUpdate:R||I},S?S(F):F),i.createElement("div",{tabIndex:0,ref:P,style:H,"aria-hidden":"true"}))}),j=i.forwardRef(function(e,t){var n=e.prefixCls,a=e.title,r=e.style,o=e.className,s=e.visible,l=e.forceRender,c=e.destroyOnClose,d=e.motionName,u=e.ariaId,p=e.onVisibleChanged,g=e.mousePosition,b=(0,i.useRef)(),f=i.useState(),E=(0,k.Z)(f,2),h=E[0],S=E[1],y={};function T(){var e,t,n,a,r,i=(n={left:(t=(e=b.current).getBoundingClientRect()).left,top:t.top},r=(a=e.ownerDocument).defaultView||a.parentWindow,n.left+=U(r),n.top+=U(r,!0),n);S(g?"".concat(g.x-i.left,"px ").concat(g.y-i.top,"px"):"")}return h&&(y.transformOrigin=h),i.createElement(B.ZP,{visible:s,onVisibleChanged:p,onAppearPrepare:T,onEnterPrepare:T,forceRender:l,motionName:d,removeOnLeave:c,ref:b},function(s,l){var c=s.className,d=s.style;return i.createElement(z,(0,w.Z)({},e,{ref:t,title:a,ariaId:u,prefixCls:n,holderRef:l,style:(0,x.Z)((0,x.Z)((0,x.Z)({},d),r),y),className:m()(o,c)}))})});function V(e){var t=e.prefixCls,n=e.style,a=e.visible,r=e.maskProps,o=e.motionName,s=e.className;return i.createElement(B.ZP,{key:"mask",visible:a,motionName:o,leavedClassName:"".concat(t,"-mask-hidden")},function(e,a){var o=e.className,l=e.style;return i.createElement("div",(0,w.Z)({ref:a,style:(0,x.Z)((0,x.Z)({},l),n),className:m()("".concat(t,"-mask"),o,s)},r))})}function W(e){var t=e.prefixCls,n=void 0===t?"rc-dialog":t,a=e.zIndex,r=e.visible,o=void 0!==r&&r,s=e.keyboard,l=void 0===s||s,c=e.focusTriggerAfterClose,d=void 0===c||c,u=e.wrapStyle,p=e.wrapClassName,g=e.wrapProps,b=e.onClose,f=e.afterOpenChange,E=e.afterClose,h=e.transitionName,S=e.animation,y=e.closable,T=e.mask,A=void 0===T||T,R=e.maskTransitionName,I=e.maskAnimation,N=e.maskClosable,_=e.maskStyle,v=e.maskProps,C=e.rootClassName,O=e.classNames,U=e.styles,B=(0,i.useRef)(),G=(0,i.useRef)(),$=(0,i.useRef)(),H=i.useState(o),z=(0,k.Z)(H,2),W=z[0],q=z[1],Y=(0,D.Z)();function K(e){null==b||b(e)}var Z=(0,i.useRef)(!1),X=(0,i.useRef)(),Q=null;return(void 0===N||N)&&(Q=function(e){Z.current?Z.current=!1:G.current===e.target&&K(e)}),(0,i.useEffect)(function(){o&&(q(!0),(0,L.Z)(G.current,document.activeElement)||(B.current=document.activeElement))},[o]),(0,i.useEffect)(function(){return function(){clearTimeout(X.current)}},[]),i.createElement("div",(0,w.Z)({className:m()("".concat(n,"-root"),C)},(0,M.Z)(e,{data:!0})),i.createElement(V,{prefixCls:n,visible:A&&o,motionName:F(n,R,I),style:(0,x.Z)((0,x.Z)({zIndex:a},_),null==U?void 0:U.mask),maskProps:v,className:null==O?void 0:O.mask}),i.createElement("div",(0,w.Z)({tabIndex:-1,onKeyDown:function(e){if(l&&e.keyCode===P.Z.ESC){e.stopPropagation(),K(e);return}o&&e.keyCode===P.Z.TAB&&$.current.changeActive(!e.shiftKey)},className:m()("".concat(n,"-wrap"),p,null==O?void 0:O.wrapper),ref:G,onClick:Q,style:(0,x.Z)((0,x.Z)((0,x.Z)({zIndex:a},u),null==U?void 0:U.wrapper),{},{display:W?null:"none"})},g),i.createElement(j,(0,w.Z)({},e,{onMouseDown:function(){clearTimeout(X.current),Z.current=!0},onMouseUp:function(){X.current=setTimeout(function(){Z.current=!1})},ref:$,closable:void 0===y||y,ariaId:Y,prefixCls:n,visible:o&&W,onClose:K,onVisibleChanged:function(e){if(e)!function(){if(!(0,L.Z)(G.current,document.activeElement)){var e;null===(e=$.current)||void 0===e||e.focus()}}();else{if(q(!1),A&&B.current&&d){try{B.current.focus({preventScroll:!0})}catch(e){}B.current=null}W&&(null==E||E())}null==f||f(e)},motionName:F(n,h,S)}))))}j.displayName="Content",n(53850);var q=function(e){var t=e.visible,n=e.getContainer,a=e.forceRender,r=e.destroyOnClose,o=void 0!==r&&r,s=e.afterClose,l=e.panelRef,c=i.useState(t),d=(0,k.Z)(c,2),u=d[0],p=d[1],g=i.useMemo(function(){return{panel:l}},[l]);return(i.useEffect(function(){t&&p(!0)},[t]),a||!o||u)?i.createElement(O.Provider,{value:g},i.createElement(C.Z,{open:t||a||u,autoDestroy:!1,getContainer:n,autoLock:t||u},i.createElement(W,(0,w.Z)({},e,{destroyOnClose:o,afterClose:function(){null==s||s(),p(!1)}})))):null};q.displayName="Dialog";var Y=function(e,t,n){let a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:i.createElement(v.Z,null),r=arguments.length>4&&void 0!==arguments[4]&&arguments[4];if("boolean"==typeof e?!e:void 0===t?!r:!1===t||null===t)return[!1,null];let o="boolean"==typeof t||null==t?a:t;return[!0,n?n(o):o]},K=n(22127),Z=n(86718),X=n(47137),Q=n(92801),J=n(48563);function ee(){}let et=i.createContext({add:ee,remove:ee});var en=n(17094),ea=()=>{let{cancelButtonProps:e,cancelTextLocale:t,onCancel:n}=(0,i.useContext)(R);return i.createElement(y.ZP,Object.assign({onClick:n},e),t)},er=()=>{let{confirmLoading:e,okButtonProps:t,okType:n,okTextLocale:a,onOk:r}=(0,i.useContext)(R);return i.createElement(y.ZP,Object.assign({},(0,T.nx)(n),{loading:e,onClick:r},t),a)},ei=n(4678);function eo(e,t){return i.createElement("span",{className:"".concat(e,"-close-x")},t||i.createElement(v.Z,{className:"".concat(e,"-close-icon")}))}let es=e=>{let t;let{okText:n,okType:a="primary",cancelText:o,confirmLoading:s,onOk:l,onCancel:c,okButtonProps:d,cancelButtonProps:u,footer:p}=e,[g]=(0,E.Z)("Modal",(0,ei.A)()),m={confirmLoading:s,okButtonProps:d,cancelButtonProps:u,okTextLocale:n||(null==g?void 0:g.okText),cancelTextLocale:o||(null==g?void 0:g.cancelText),okType:a,onOk:l,onCancel:c},b=i.useMemo(()=>m,(0,r.Z)(Object.values(m)));return"function"==typeof p||void 0===p?(t=i.createElement(i.Fragment,null,i.createElement(ea,null),i.createElement(er,null)),"function"==typeof p&&(t=p(t,{OkBtn:er,CancelBtn:ea})),t=i.createElement(I,{value:b},t)):t=p,i.createElement(en.n,{disabled:!1},t)};var el=n(11303),ec=n(13703),ed=n(58854),eu=n(80316),ep=n(76585),eg=n(8985);function em(e){return{position:e,inset:0}}let eb=e=>{let{componentCls:t,antCls:n}=e;return[{["".concat(t,"-root")]:{["".concat(t).concat(n,"-zoom-enter, ").concat(t).concat(n,"-zoom-appear")]:{transform:"none",opacity:0,animationDuration:e.motionDurationSlow,userSelect:"none"},["".concat(t).concat(n,"-zoom-leave ").concat(t,"-content")]:{pointerEvents:"none"},["".concat(t,"-mask")]:Object.assign(Object.assign({},em("fixed")),{zIndex:e.zIndexPopupBase,height:"100%",backgroundColor:e.colorBgMask,pointerEvents:"none",["".concat(t,"-hidden")]:{display:"none"}}),["".concat(t,"-wrap")]:Object.assign(Object.assign({},em("fixed")),{zIndex:e.zIndexPopupBase,overflow:"auto",outline:0,WebkitOverflowScrolling:"touch",["&:has(".concat(t).concat(n,"-zoom-enter), &:has(").concat(t).concat(n,"-zoom-appear)")]:{pointerEvents:"none"}})}},{["".concat(t,"-root")]:(0,ec.J$)(e)}]},ef=e=>{let{componentCls:t}=e;return[{["".concat(t,"-root")]:{["".concat(t,"-wrap-rtl")]:{direction:"rtl"},["".concat(t,"-centered")]:{textAlign:"center","&::before":{display:"inline-block",width:0,height:"100%",verticalAlign:"middle",content:'""'},[t]:{top:0,display:"inline-block",paddingBottom:0,textAlign:"start",verticalAlign:"middle"}},["@media (max-width: ".concat(e.screenSMMax,"px)")]:{[t]:{maxWidth:"calc(100vw - 16px)",margin:"".concat((0,eg.bf)(e.marginXS)," auto")},["".concat(t,"-centered")]:{[t]:{flex:1}}}}},{[t]:Object.assign(Object.assign({},(0,el.Wf)(e)),{pointerEvents:"none",position:"relative",top:100,width:"auto",maxWidth:"calc(100vw - ".concat((0,eg.bf)(e.calc(e.margin).mul(2).equal()),")"),margin:"0 auto",paddingBottom:e.paddingLG,["".concat(t,"-title")]:{margin:0,color:e.titleColor,fontWeight:e.fontWeightStrong,fontSize:e.titleFontSize,lineHeight:e.titleLineHeight,wordWrap:"break-word"},["".concat(t,"-content")]:{position:"relative",backgroundColor:e.contentBg,backgroundClip:"padding-box",border:0,borderRadius:e.borderRadiusLG,boxShadow:e.boxShadow,pointerEvents:"auto",padding:e.contentPadding},["".concat(t,"-close")]:Object.assign({position:"absolute",top:e.calc(e.modalHeaderHeight).sub(e.modalCloseBtnSize).div(2).equal(),insetInlineEnd:e.calc(e.modalHeaderHeight).sub(e.modalCloseBtnSize).div(2).equal(),zIndex:e.calc(e.zIndexPopupBase).add(10).equal(),padding:0,color:e.modalCloseIconColor,fontWeight:e.fontWeightStrong,lineHeight:1,textDecoration:"none",background:"transparent",borderRadius:e.borderRadiusSM,width:e.modalCloseBtnSize,height:e.modalCloseBtnSize,border:0,outline:0,cursor:"pointer",transition:"color ".concat(e.motionDurationMid,", background-color ").concat(e.motionDurationMid),"&-x":{display:"flex",fontSize:e.fontSizeLG,fontStyle:"normal",lineHeight:"".concat((0,eg.bf)(e.modalCloseBtnSize)),justifyContent:"center",textTransform:"none",textRendering:"auto"},"&:hover":{color:e.modalIconHoverColor,backgroundColor:e.closeBtnHoverBg,textDecoration:"none"},"&:active":{backgroundColor:e.closeBtnActiveBg}},(0,el.Qy)(e)),["".concat(t,"-header")]:{color:e.colorText,background:e.headerBg,borderRadius:"".concat((0,eg.bf)(e.borderRadiusLG)," ").concat((0,eg.bf)(e.borderRadiusLG)," 0 0"),marginBottom:e.headerMarginBottom,padding:e.headerPadding,borderBottom:e.headerBorderBottom},["".concat(t,"-body")]:{fontSize:e.fontSize,lineHeight:e.lineHeight,wordWrap:"break-word",padding:e.bodyPadding},["".concat(t,"-footer")]:{textAlign:"end",background:e.footerBg,marginTop:e.footerMarginTop,padding:e.footerPadding,borderTop:e.footerBorderTop,borderRadius:e.footerBorderRadius,["> ".concat(e.antCls,"-btn + ").concat(e.antCls,"-btn")]:{marginInlineStart:e.marginXS}},["".concat(t,"-open")]:{overflow:"hidden"}})},{["".concat(t,"-pure-panel")]:{top:"auto",padding:0,display:"flex",flexDirection:"column",["".concat(t,"-content,\n ").concat(t,"-body,\n ").concat(t,"-confirm-body-wrapper")]:{display:"flex",flexDirection:"column",flex:"auto"},["".concat(t,"-confirm-body")]:{marginBottom:"auto"}}}]},eE=e=>{let{componentCls:t}=e;return{["".concat(t,"-root")]:{["".concat(t,"-wrap-rtl")]:{direction:"rtl",["".concat(t,"-confirm-body")]:{direction:"rtl"}}}}},eh=e=>{let t=e.padding,n=e.fontSizeHeading5,a=e.lineHeightHeading5;return(0,eu.TS)(e,{modalHeaderHeight:e.calc(e.calc(a).mul(n).equal()).add(e.calc(t).mul(2).equal()).equal(),modalFooterBorderColorSplit:e.colorSplit,modalFooterBorderStyle:e.lineType,modalFooterBorderWidth:e.lineWidth,modalIconHoverColor:e.colorIconHover,modalCloseIconColor:e.colorIcon,modalCloseBtnSize:e.fontHeight,modalConfirmIconSize:e.fontHeight,modalTitleHeight:e.calc(e.titleFontSize).mul(e.titleLineHeight).equal()})},eS=e=>({footerBg:"transparent",headerBg:e.colorBgElevated,titleLineHeight:e.lineHeightHeading5,titleFontSize:e.fontSizeHeading5,contentBg:e.colorBgElevated,titleColor:e.colorTextHeading,closeBtnHoverBg:e.wireframe?"transparent":e.colorFillContent,closeBtnActiveBg:e.wireframe?"transparent":e.colorFillContentHover,contentPadding:e.wireframe?0:"".concat((0,eg.bf)(e.paddingMD)," ").concat((0,eg.bf)(e.paddingContentHorizontalLG)),headerPadding:e.wireframe?"".concat((0,eg.bf)(e.padding)," ").concat((0,eg.bf)(e.paddingLG)):0,headerBorderBottom:e.wireframe?"".concat((0,eg.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorSplit):"none",headerMarginBottom:e.wireframe?0:e.marginXS,bodyPadding:e.wireframe?e.paddingLG:0,footerPadding:e.wireframe?"".concat((0,eg.bf)(e.paddingXS)," ").concat((0,eg.bf)(e.padding)):0,footerBorderTop:e.wireframe?"".concat((0,eg.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorSplit):"none",footerBorderRadius:e.wireframe?"0 0 ".concat((0,eg.bf)(e.borderRadiusLG)," ").concat((0,eg.bf)(e.borderRadiusLG)):0,footerMarginTop:e.wireframe?0:e.marginSM,confirmBodyPadding:e.wireframe?"".concat((0,eg.bf)(2*e.padding)," ").concat((0,eg.bf)(2*e.padding)," ").concat((0,eg.bf)(e.paddingLG)):0,confirmIconMarginInlineEnd:e.wireframe?e.margin:e.marginSM,confirmBtnsMarginTop:e.wireframe?e.marginLG:e.marginSM});var ey=(0,ep.I$)("Modal",e=>{let t=eh(e);return[ef(t),eE(t),eb(t),(0,ed._y)(t,"zoom")]},eS,{unitless:{titleLineHeight:!0}}),eT=n(92935),eA=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,a=Object.getOwnPropertySymbols(e);rt.indexOf(a[r])&&Object.prototype.propertyIsEnumerable.call(e,a[r])&&(n[a[r]]=e[a[r]]);return n};(0,K.Z)()&&window.document.documentElement&&document.documentElement.addEventListener("click",e=>{a={x:e.pageX,y:e.pageY},setTimeout(()=>{a=null},100)},!0);var eR=e=>{var t;let{getPopupContainer:n,getPrefixCls:r,direction:o,modal:l}=i.useContext(s.E_),c=t=>{let{onCancel:n}=e;null==n||n(t)},{prefixCls:d,className:u,rootClassName:p,open:g,wrapClassName:E,centered:h,getContainer:S,closeIcon:y,closable:T,focusTriggerAfterClose:A=!0,style:R,visible:I,width:N=520,footer:_,classNames:w,styles:k}=e,C=eA(e,["prefixCls","className","rootClassName","open","wrapClassName","centered","getContainer","closeIcon","closable","focusTriggerAfterClose","style","visible","width","footer","classNames","styles"]),O=r("modal",d),x=r(),L=(0,eT.Z)(O),[D,P,M]=ey(O,L),F=m()(E,{["".concat(O,"-centered")]:!!h,["".concat(O,"-wrap-rtl")]:"rtl"===o}),U=null!==_&&i.createElement(es,Object.assign({},e,{onOk:t=>{let{onOk:n}=e;null==n||n(t)},onCancel:c})),[B,G]=Y(T,y,e=>eo(O,e),i.createElement(v.Z,{className:"".concat(O,"-close-icon")}),!0),$=function(e){let t=i.useContext(et),n=i.useRef();return(0,J.zX)(a=>{if(a){let r=e?a.querySelector(e):a;t.add(r),n.current=r}else t.remove(n.current)})}(".".concat(O,"-content")),[H,z]=(0,b.Cn)("Modal",C.zIndex);return D(i.createElement(Q.BR,null,i.createElement(X.Ux,{status:!0,override:!0},i.createElement(Z.Z.Provider,{value:z},i.createElement(q,Object.assign({width:N},C,{zIndex:H,getContainer:void 0===S?n:S,prefixCls:O,rootClassName:m()(P,p,M,L),footer:U,visible:null!=g?g:I,mousePosition:null!==(t=C.mousePosition)&&void 0!==t?t:a,onClose:c,closable:B,closeIcon:G,focusTriggerAfterClose:A,transitionName:(0,f.m)(x,"zoom",e.transitionName),maskTransitionName:(0,f.m)(x,"fade",e.maskTransitionName),className:m()(P,u,null==l?void 0:l.className),style:Object.assign(Object.assign({},null==l?void 0:l.style),R),classNames:Object.assign(Object.assign({wrapper:F},null==l?void 0:l.classNames),w),styles:Object.assign(Object.assign({},null==l?void 0:l.styles),k),panelRef:$}))))))};let eI=e=>{let{componentCls:t,titleFontSize:n,titleLineHeight:a,modalConfirmIconSize:r,fontSize:i,lineHeight:o,modalTitleHeight:s,fontHeight:l,confirmBodyPadding:c}=e,d="".concat(t,"-confirm");return{[d]:{"&-rtl":{direction:"rtl"},["".concat(e.antCls,"-modal-header")]:{display:"none"},["".concat(d,"-body-wrapper")]:Object.assign({},(0,el.dF)()),["&".concat(t," ").concat(t,"-body")]:{padding:c},["".concat(d,"-body")]:{display:"flex",flexWrap:"nowrap",alignItems:"start",["> ".concat(e.iconCls)]:{flex:"none",fontSize:r,marginInlineEnd:e.confirmIconMarginInlineEnd,marginTop:e.calc(e.calc(l).sub(r).equal()).div(2).equal()},["&-has-title > ".concat(e.iconCls)]:{marginTop:e.calc(e.calc(s).sub(r).equal()).div(2).equal()}},["".concat(d,"-paragraph")]:{display:"flex",flexDirection:"column",flex:"auto",rowGap:e.marginXS,maxWidth:"calc(100% - ".concat((0,eg.bf)(e.calc(e.modalConfirmIconSize).add(e.marginSM).equal()),")")},["".concat(d,"-title")]:{color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:n,lineHeight:a},["".concat(d,"-content")]:{color:e.colorText,fontSize:i,lineHeight:o},["".concat(d,"-btns")]:{textAlign:"end",marginTop:e.confirmBtnsMarginTop,["".concat(e.antCls,"-btn + ").concat(e.antCls,"-btn")]:{marginBottom:0,marginInlineStart:e.marginXS}}},["".concat(d,"-error ").concat(d,"-body > ").concat(e.iconCls)]:{color:e.colorError},["".concat(d,"-warning ").concat(d,"-body > ").concat(e.iconCls,",\n ").concat(d,"-confirm ").concat(d,"-body > ").concat(e.iconCls)]:{color:e.colorWarning},["".concat(d,"-info ").concat(d,"-body > ").concat(e.iconCls)]:{color:e.colorInfo},["".concat(d,"-success ").concat(d,"-body > ").concat(e.iconCls)]:{color:e.colorSuccess}}};var eN=(0,ep.bk)(["Modal","confirm"],e=>[eI(eh(e))],eS,{order:-1e3}),e_=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,a=Object.getOwnPropertySymbols(e);rt.indexOf(a[r])&&Object.prototype.propertyIsEnumerable.call(e,a[r])&&(n[a[r]]=e[a[r]]);return n};function ev(e){let{prefixCls:t,icon:n,okText:a,cancelText:o,confirmPrefixCls:s,type:l,okCancel:g,footer:b,locale:f}=e,h=e_(e,["prefixCls","icon","okText","cancelText","confirmPrefixCls","type","okCancel","footer","locale"]),S=n;if(!n&&null!==n)switch(l){case"info":S=i.createElement(p.Z,null);break;case"success":S=i.createElement(c.Z,null);break;case"error":S=i.createElement(d.Z,null);break;default:S=i.createElement(u.Z,null)}let y=null!=g?g:"confirm"===l,T=null!==e.autoFocusButton&&(e.autoFocusButton||"ok"),[A]=(0,E.Z)("Modal"),R=f||A,v=a||(y?null==R?void 0:R.okText:null==R?void 0:R.justOkText),w=Object.assign({autoFocusButton:T,cancelTextLocale:o||(null==R?void 0:R.cancelText),okTextLocale:v,mergedOkCancel:y},h),k=i.useMemo(()=>w,(0,r.Z)(Object.values(w))),C=i.createElement(i.Fragment,null,i.createElement(N,null),i.createElement(_,null)),O=void 0!==e.title&&null!==e.title,x="".concat(s,"-body");return i.createElement("div",{className:"".concat(s,"-body-wrapper")},i.createElement("div",{className:m()(x,{["".concat(x,"-has-title")]:O})},S,i.createElement("div",{className:"".concat(s,"-paragraph")},O&&i.createElement("span",{className:"".concat(s,"-title")},e.title),i.createElement("div",{className:"".concat(s,"-content")},e.content))),void 0===b||"function"==typeof b?i.createElement(I,{value:k},i.createElement("div",{className:"".concat(s,"-btns")},"function"==typeof b?b(C,{OkBtn:_,CancelBtn:N}):C)):b,i.createElement(eN,{prefixCls:t}))}let ew=e=>{let{close:t,zIndex:n,afterClose:a,open:r,keyboard:o,centered:s,getContainer:l,maskStyle:c,direction:d,prefixCls:u,wrapClassName:p,rootPrefixCls:g,bodyStyle:E,closable:S=!1,closeIcon:y,modalRender:T,focusTriggerAfterClose:A,onConfirm:R,styles:I}=e,N="".concat(u,"-confirm"),_=e.width||416,v=e.style||{},w=void 0===e.mask||e.mask,k=void 0!==e.maskClosable&&e.maskClosable,C=m()(N,"".concat(N,"-").concat(e.type),{["".concat(N,"-rtl")]:"rtl"===d},e.className),[,O]=(0,h.ZP)(),x=i.useMemo(()=>void 0!==n?n:O.zIndexPopupBase+b.u6,[n,O]);return i.createElement(eR,{prefixCls:u,className:C,wrapClassName:m()({["".concat(N,"-centered")]:!!e.centered},p),onCancel:()=>{null==t||t({triggerCancel:!0}),null==R||R(!1)},open:r,title:"",footer:null,transitionName:(0,f.m)(g||"","zoom",e.transitionName),maskTransitionName:(0,f.m)(g||"","fade",e.maskTransitionName),mask:w,maskClosable:k,style:v,styles:Object.assign({body:E,mask:c},I),width:_,zIndex:x,afterClose:a,keyboard:o,centered:s,getContainer:l,closable:S,closeIcon:y,modalRender:T,focusTriggerAfterClose:A},i.createElement(ev,Object.assign({},e,{confirmPrefixCls:N})))};var ek=e=>{let{rootPrefixCls:t,iconPrefixCls:n,direction:a,theme:r}=e;return i.createElement(l.ZP,{prefixCls:t,iconPrefixCls:n,direction:a,theme:r},i.createElement(ew,Object.assign({},e)))},eC=[];let eO="",ex=e=>{var t,n;let{prefixCls:a,getContainer:r,direction:o}=e,l=(0,ei.A)(),c=(0,i.useContext)(s.E_),d=eO||c.getPrefixCls(),u=a||"".concat(d,"-modal"),p=r;return!1===p&&(p=void 0),i.createElement(ek,Object.assign({},e,{rootPrefixCls:d,prefixCls:u,iconPrefixCls:c.iconPrefixCls,theme:c.theme,direction:null!=o?o:c.direction,locale:null!==(n=null===(t=c.locale)||void 0===t?void 0:t.Modal)&&void 0!==n?n:l,getContainer:p}))};function eL(e){let t;let n=(0,l.w6)(),a=document.createDocumentFragment(),s=Object.assign(Object.assign({},e),{close:u,open:!0});function c(){for(var t=arguments.length,n=Array(t),i=0;ie&&e.triggerCancel);e.onCancel&&s&&e.onCancel.apply(e,[()=>{}].concat((0,r.Z)(n.slice(1))));for(let e=0;e{let t=n.getPrefixCls(void 0,eO),r=n.getIconPrefixCls(),s=n.getTheme(),c=i.createElement(ex,Object.assign({},e));(0,o.s)(i.createElement(l.ZP,{prefixCls:t,iconPrefixCls:r,theme:s},n.holderRender?n.holderRender(c):c),a)})}function u(){for(var t=arguments.length,n=Array(t),a=0;a{"function"==typeof e.afterClose&&e.afterClose(),c.apply(this,n)}})).visible&&delete s.visible,d(s)}return d(s),eC.push(u),{destroy:u,update:function(e){d(s="function"==typeof e?e(s):Object.assign(Object.assign({},s),e))}}}function eD(e){return Object.assign(Object.assign({},e),{type:"warning"})}function eP(e){return Object.assign(Object.assign({},e),{type:"info"})}function eM(e){return Object.assign(Object.assign({},e),{type:"success"})}function eF(e){return Object.assign(Object.assign({},e),{type:"error"})}function eU(e){return Object.assign(Object.assign({},e),{type:"confirm"})}var eB=n(21467),eG=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,a=Object.getOwnPropertySymbols(e);rt.indexOf(a[r])&&Object.prototype.propertyIsEnumerable.call(e,a[r])&&(n[a[r]]=e[a[r]]);return n},e$=(0,eB.i)(e=>{let{prefixCls:t,className:n,closeIcon:a,closable:r,type:o,title:l,children:c,footer:d}=e,u=eG(e,["prefixCls","className","closeIcon","closable","type","title","children","footer"]),{getPrefixCls:p}=i.useContext(s.E_),g=p(),b=t||p("modal"),f=(0,eT.Z)(g),[E,h,S]=ey(b,f),y="".concat(b,"-confirm"),T={};return T=o?{closable:null!=r&&r,title:"",footer:"",children:i.createElement(ev,Object.assign({},e,{prefixCls:b,confirmPrefixCls:y,rootPrefixCls:g,content:c}))}:{closable:null==r||r,title:l,footer:null!==d&&i.createElement(es,Object.assign({},e)),children:c},E(i.createElement(z,Object.assign({prefixCls:b,className:m()(h,"".concat(b,"-pure-panel"),o&&y,o&&"".concat(y,"-").concat(o),n,S,f)},u,{closeIcon:eo(b,a),closable:r},T)))}),eH=n(79474),ez=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,a=Object.getOwnPropertySymbols(e);rt.indexOf(a[r])&&Object.prototype.propertyIsEnumerable.call(e,a[r])&&(n[a[r]]=e[a[r]]);return n},ej=i.forwardRef((e,t)=>{var n,{afterClose:a,config:o}=e,l=ez(e,["afterClose","config"]);let[c,d]=i.useState(!0),[u,p]=i.useState(o),{direction:g,getPrefixCls:m}=i.useContext(s.E_),b=m("modal"),f=m(),h=function(){d(!1);for(var e=arguments.length,t=Array(e),n=0;ne&&e.triggerCancel);u.onCancel&&a&&u.onCancel.apply(u,[()=>{}].concat((0,r.Z)(t.slice(1))))};i.useImperativeHandle(t,()=>({destroy:h,update:e=>{p(t=>Object.assign(Object.assign({},t),e))}}));let S=null!==(n=u.okCancel)&&void 0!==n?n:"confirm"===u.type,[y]=(0,E.Z)("Modal",eH.Z.Modal);return i.createElement(ek,Object.assign({prefixCls:b,rootPrefixCls:f},u,{close:h,open:c,afterClose:()=>{var e;a(),null===(e=u.afterClose)||void 0===e||e.call(u)},okText:u.okText||(S?null==y?void 0:y.okText:null==y?void 0:y.justOkText),direction:u.direction||g,cancelText:u.cancelText||(null==y?void 0:y.cancelText)},l))});let eV=0,eW=i.memo(i.forwardRef((e,t)=>{let[n,a]=function(){let[e,t]=i.useState([]);return[e,i.useCallback(e=>(t(t=>[].concat((0,r.Z)(t),[e])),()=>{t(t=>t.filter(t=>t!==e))}),[])]}();return i.useImperativeHandle(t,()=>({patchElement:a}),[]),i.createElement(i.Fragment,null,n)}));function eq(e){return eL(eD(e))}eR.useModal=function(){let e=i.useRef(null),[t,n]=i.useState([]);i.useEffect(()=>{t.length&&((0,r.Z)(t).forEach(e=>{e()}),n([]))},[t]);let a=i.useCallback(t=>function(a){var o;let s,l;eV+=1;let c=i.createRef(),d=new Promise(e=>{s=e}),u=!1,p=i.createElement(ej,{key:"modal-".concat(eV),config:t(a),ref:c,afterClose:()=>{null==l||l()},isSilent:()=>u,onConfirm:e=>{s(e)}});return(l=null===(o=e.current)||void 0===o?void 0:o.patchElement(p))&&eC.push(l),{destroy:()=>{function e(){var e;null===(e=c.current)||void 0===e||e.destroy()}c.current?e():n(t=>[].concat((0,r.Z)(t),[e]))},update:e=>{function t(){var t;null===(t=c.current)||void 0===t||t.update(e)}c.current?t():n(e=>[].concat((0,r.Z)(e),[t]))},then:e=>(u=!0,d.then(e))}},[]);return[i.useMemo(()=>({info:a(eP),success:a(eM),error:a(eF),warning:a(eD),confirm:a(eU)}),[]),i.createElement(eW,{key:"modal-holder",ref:e})]},eR.info=function(e){return eL(eP(e))},eR.success=function(e){return eL(eM(e))},eR.error=function(e){return eL(eF(e))},eR.warning=eq,eR.warn=eq,eR.confirm=function(e){return eL(eU(e))},eR.destroyAll=function(){for(;eC.length;){let e=eC.pop();e&&e()}},eR.config=function(e){let{rootPrefixCls:t}=e;eO=t},eR._InternalPanelDoNotUseOrYouWillBeFired=e$;var eY=eR},13703:function(e,t,n){n.d(t,{J$:function(){return s}});var a=n(8985),r=n(59353);let i=new a.E4("antFadeIn",{"0%":{opacity:0},"100%":{opacity:1}}),o=new a.E4("antFadeOut",{"0%":{opacity:1},"100%":{opacity:0}}),s=function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],{antCls:n}=e,a="".concat(n,"-fade"),s=t?"&":"";return[(0,r.R)(a,i,o,e.motionDurationMid,t),{["\n ".concat(s).concat(a,"-enter,\n ").concat(s).concat(a,"-appear\n ")]:{opacity:0,animationTimingFunction:"linear"},["".concat(s).concat(a,"-leave")]:{animationTimingFunction:"linear"}}]}},44056:function(e){e.exports=function(e,n){for(var a,r,i,o=e||"",s=n||"div",l={},c=0;c4&&m.slice(0,4)===o&&s.test(t)&&("-"===t.charAt(4)?b=o+(n=t.slice(5).replace(l,u)).charAt(0).toUpperCase()+n.slice(1):(g=(p=t).slice(4),t=l.test(g)?p:("-"!==(g=g.replace(c,d)).charAt(0)&&(g="-"+g),o+g)),f=r),new f(b,t))};var s=/^data[-\w.:]+$/i,l=/-[a-z]/g,c=/[A-Z]/g;function d(e){return"-"+e.toLowerCase()}function u(e){return e.charAt(1).toUpperCase()}},31872:function(e,t,n){var a=n(96130),r=n(64730),i=n(61861),o=n(46982),s=n(83671),l=n(53618);e.exports=a([i,r,o,s,l])},83671:function(e,t,n){var a=n(7667),r=n(13585),i=a.booleanish,o=a.number,s=a.spaceSeparated;e.exports=r({transform:function(e,t){return"role"===t?t:"aria-"+t.slice(4).toLowerCase()},properties:{ariaActiveDescendant:null,ariaAtomic:i,ariaAutoComplete:null,ariaBusy:i,ariaChecked:i,ariaColCount:o,ariaColIndex:o,ariaColSpan:o,ariaControls:s,ariaCurrent:null,ariaDescribedBy:s,ariaDetails:null,ariaDisabled:i,ariaDropEffect:s,ariaErrorMessage:null,ariaExpanded:i,ariaFlowTo:s,ariaGrabbed:i,ariaHasPopup:null,ariaHidden:i,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:s,ariaLevel:o,ariaLive:null,ariaModal:i,ariaMultiLine:i,ariaMultiSelectable:i,ariaOrientation:null,ariaOwns:s,ariaPlaceholder:null,ariaPosInSet:o,ariaPressed:i,ariaReadOnly:i,ariaRelevant:null,ariaRequired:i,ariaRoleDescription:s,ariaRowCount:o,ariaRowIndex:o,ariaRowSpan:o,ariaSelected:i,ariaSetSize:o,ariaSort:null,ariaValueMax:o,ariaValueMin:o,ariaValueNow:o,ariaValueText:null,role:null}})},53618:function(e,t,n){var a=n(7667),r=n(13585),i=n(46640),o=a.boolean,s=a.overloadedBoolean,l=a.booleanish,c=a.number,d=a.spaceSeparated,u=a.commaSeparated;e.exports=r({space:"html",attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},transform:i,mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:u,acceptCharset:d,accessKey:d,action:null,allow:null,allowFullScreen:o,allowPaymentRequest:o,allowUserMedia:o,alt:null,as:null,async:o,autoCapitalize:null,autoComplete:d,autoFocus:o,autoPlay:o,capture:o,charSet:null,checked:o,cite:null,className:d,cols:c,colSpan:null,content:null,contentEditable:l,controls:o,controlsList:d,coords:c|u,crossOrigin:null,data:null,dateTime:null,decoding:null,default:o,defer:o,dir:null,dirName:null,disabled:o,download:s,draggable:l,encType:null,enterKeyHint:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:o,formTarget:null,headers:d,height:c,hidden:o,high:c,href:null,hrefLang:null,htmlFor:d,httpEquiv:d,id:null,imageSizes:null,imageSrcSet:u,inputMode:null,integrity:null,is:null,isMap:o,itemId:null,itemProp:d,itemRef:d,itemScope:o,itemType:d,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:o,low:c,manifest:null,max:null,maxLength:c,media:null,method:null,min:null,minLength:c,multiple:o,muted:o,name:null,nonce:null,noModule:o,noValidate:o,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforePrint:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextMenu:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:o,optimum:c,pattern:null,ping:d,placeholder:null,playsInline:o,poster:null,preload:null,readOnly:o,referrerPolicy:null,rel:d,required:o,reversed:o,rows:c,rowSpan:c,sandbox:d,scope:null,scoped:o,seamless:o,selected:o,shape:null,size:c,sizes:null,slot:null,span:c,spellCheck:l,src:null,srcDoc:null,srcLang:null,srcSet:u,start:c,step:null,style:null,tabIndex:c,target:null,title:null,translate:null,type:null,typeMustMatch:o,useMap:null,value:l,width:c,wrap:null,align:null,aLink:null,archive:d,axis:null,background:null,bgColor:null,border:c,borderColor:null,bottomMargin:c,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:o,declare:o,event:null,face:null,frame:null,frameBorder:null,hSpace:c,leftMargin:c,link:null,longDesc:null,lowSrc:null,marginHeight:c,marginWidth:c,noResize:o,noHref:o,noShade:o,noWrap:o,object:null,profile:null,prompt:null,rev:null,rightMargin:c,rules:null,scheme:null,scrolling:l,standby:null,summary:null,text:null,topMargin:c,valueType:null,version:null,vAlign:null,vLink:null,vSpace:c,allowTransparency:null,autoCorrect:null,autoSave:null,disablePictureInPicture:o,disableRemotePlayback:o,prefix:null,property:null,results:c,security:null,unselectable:null}})},46640:function(e,t,n){var a=n(25852);e.exports=function(e,t){return a(e,t.toLowerCase())}},25852:function(e){e.exports=function(e,t){return t in e?e[t]:t}},13585:function(e,t,n){var a=n(39900),r=n(94949),i=n(7478);e.exports=function(e){var t,n,o=e.space,s=e.mustUseProperty||[],l=e.attributes||{},c=e.properties,d=e.transform,u={},p={};for(t in c)n=new i(t,d(l,t),c[t],o),-1!==s.indexOf(t)&&(n.mustUseProperty=!0),u[t]=n,p[a(t)]=t,p[a(n.attribute)]=t;return new r(u,p,o)}},7478:function(e,t,n){var a=n(74108),r=n(7667);e.exports=s,s.prototype=new a,s.prototype.defined=!0;var i=["boolean","booleanish","overloadedBoolean","number","commaSeparated","spaceSeparated","commaOrSpaceSeparated"],o=i.length;function s(e,t,n,s){var l,c,d,u=-1;for(s&&(this.space=s),a.call(this,e,t);++u
- Open In Colab - - - -### 1. Get your LiteLLM Token - -Go to [admin.litellm.ai](https://admin.litellm.ai/) and copy the code snippet with your unique token - -Usage - -### 2. Set up your environment - -**Add it to your .env** - -```python -import os - -os.env["LITELLM_TOKEN"] = "e24c4c06-d027-4c30-9e78-18bc3a50aebb" # replace with your unique token - -``` - -**Turn on LiteLLM Client** -```python -import litellm -litellm.client = True -``` - -### 3. Make a normal `completion()` call -```python -import litellm -from litellm import completion -import os - -# set env variables -os.environ["LITELLM_TOKEN"] = "e24c4c06-d027-4c30-9e78-18bc3a50aebb" # replace with your unique token -os.environ["OPENAI_API_KEY"] = "openai key" - -litellm.use_client = True # enable logging dashboard -messages = [{ "content": "Hello, how are you?","role": "user"}] - -# openai call -response = completion(model="gpt-3.5-turbo", messages=messages) -``` - -Your `completion()` call print with a link to your session dashboard (https://admin.litellm.ai/) - -In the above case it would be: [`admin.litellm.ai/e24c4c06-d027-4c30-9e78-18bc3a50aebb`](https://admin.litellm.ai/e24c4c06-d027-4c30-9e78-18bc3a50aebb) - -Click on your personal dashboard link. Here's how you can find it šŸ‘‡ - -Dashboard - -[šŸ‘‹ Tell us if you need better privacy controls](https://calendly.com/d/4mp-gd3-k5k/berriai-1-1-onboarding-litellm-hosted-version?month=2023-08) - -### 3. Review request log - -Oh! Looks like our request was made successfully. Let's click on it and see exactly what got sent to the LLM provider. - - - - -Ah! So we can see that this request was made to a **Baseten** (see litellm_params > custom_llm_provider) for a model with ID - **7qQNLDB** (see model). The message sent was - `"Hey, how's it going?"` and the response received was - `"As an AI language model, I don't have feelings or emotions, but I can assist you with your queries. How can I assist you today?"` - -Dashboard Log Row - -:::info - -šŸŽ‰ Congratulations! You've successfully debugger your first log! - -::: \ No newline at end of file diff --git a/docs/my-website/docs/providers/togetherai.md b/docs/my-website/docs/providers/togetherai.md index 1021f5ba84..e069ea69dd 100644 --- a/docs/my-website/docs/providers/togetherai.md +++ b/docs/my-website/docs/providers/togetherai.md @@ -208,7 +208,7 @@ print(response) Instead of using the `custom_llm_provider` arg to specify which provider you're using (e.g. together ai), you can just pass the provider name as part of the model name, and LiteLLM will parse it out. -Expected format: / +Expected format: `/` e.g. completion(model="together_ai/togethercomputer/Llama-2-7B-32K-Instruct", ...) diff --git a/docs/my-website/docs/proxy/deploy.md b/docs/my-website/docs/proxy/deploy.md index a3c8590b5f..8767417f5a 100644 --- a/docs/my-website/docs/proxy/deploy.md +++ b/docs/my-website/docs/proxy/deploy.md @@ -669,7 +669,7 @@ Once the stack is created, get the DatabaseURL of the Database resource, copy th #### 3. Connect to the EC2 Instance and deploy litellm on the EC2 container From the EC2 console, connect to the instance created by the stack (e.g., using SSH). -Run the following command, replacing with the value you copied in step 2 +Run the following command, replacing `` with the value you copied in step 2 ```shell docker run --name litellm-proxy \ diff --git a/docs/my-website/docs/tutorials/TogetherAI_liteLLM.md b/docs/my-website/docs/tutorials/TogetherAI_liteLLM.md index 08e8d56f06..31e9bfa6cb 100644 --- a/docs/my-website/docs/tutorials/TogetherAI_liteLLM.md +++ b/docs/my-website/docs/tutorials/TogetherAI_liteLLM.md @@ -26,6 +26,7 @@ print(response) ``` {'choices': [{'finish_reason': 'stop', 'index': 0, 'message': {'role': 'assistant', 'content': "\n\nI'm not able to provide real-time weather information. However, I can suggest"}}], 'created': 1691629657.9288375, 'model': 'togethercomputer/llama-2-70b-chat', 'usage': {'prompt_tokens': 9, 'completion_tokens': 17, 'total_tokens': 26}} +``` LiteLLM handles the prompt formatting for Together AI's Llama2 models as well, converting your message to the From ae86722a8da8c279dd08e558ea0abb3a035f758e Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 15 Jun 2024 15:09:49 -0700 Subject: [PATCH 73/83] test proxy server.py --- litellm/tests/test_proxy_server.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/litellm/tests/test_proxy_server.py b/litellm/tests/test_proxy_server.py index 114b96872f..d8bfb52297 100644 --- a/litellm/tests/test_proxy_server.py +++ b/litellm/tests/test_proxy_server.py @@ -26,7 +26,7 @@ logging.basicConfig( from fastapi.testclient import TestClient from fastapi import FastAPI from litellm.proxy.proxy_server import ( - router, + app, save_worker_config, initialize, ) # Replace with the actual module where your FastAPI router is defined @@ -119,9 +119,6 @@ def client_no_auth(fake_env_vars): config_fp = f"{filepath}/test_configs/test_config_no_auth.yaml" # initialize can get run in parallel, it sets specific variables for the fast api app, sinc eit gets run in parallel different tests use the wrong variables asyncio.run(initialize(config=config_fp, debug=True)) - app = FastAPI() - app.include_router(router) # Include your router in the test app - return TestClient(app) @@ -426,6 +423,10 @@ def test_add_new_model(client_no_auth): def test_health(client_no_auth): global headers import time + from litellm._logging import verbose_logger, verbose_proxy_logger + import logging + + verbose_proxy_logger.setLevel(logging.DEBUG) try: response = client_no_auth.get("/health") From 0865e26bc03ab98bd17732291b2f459370def171 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 15 Jun 2024 15:11:10 -0700 Subject: [PATCH 74/83] docs - fix build time errors --- docs/my-website/docs/tutorials/TogetherAI_liteLLM.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/my-website/docs/tutorials/TogetherAI_liteLLM.md b/docs/my-website/docs/tutorials/TogetherAI_liteLLM.md index 31e9bfa6cb..dd9dd28867 100644 --- a/docs/my-website/docs/tutorials/TogetherAI_liteLLM.md +++ b/docs/my-website/docs/tutorials/TogetherAI_liteLLM.md @@ -23,6 +23,9 @@ https://api.together.xyz/playground/chat?model=togethercomputer%2Fllama-2-70b-ch model_name = "together_ai/togethercomputer/llama-2-70b-chat" response = completion(model=model_name, messages=messages) print(response) +``` + + ``` {'choices': [{'finish_reason': 'stop', 'index': 0, 'message': {'role': 'assistant', 'content': "\n\nI'm not able to provide real-time weather information. However, I can suggest"}}], 'created': 1691629657.9288375, 'model': 'togethercomputer/llama-2-70b-chat', 'usage': {'prompt_tokens': 9, 'completion_tokens': 17, 'total_tokens': 26}} From ae884f741ee6ae67e8e9ca7dc602110e402e4d07 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 15 Jun 2024 15:26:44 -0700 Subject: [PATCH 75/83] fix - non sso ui sign up flow --- litellm/proxy/proxy_server.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 9a9f976bee..844daff116 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -11503,7 +11503,8 @@ async def login(request: Request): if secrets.compare_digest(username, ui_username) and secrets.compare_digest( password, ui_password ): - user_role = "app_owner" + # Non SSO -> If user is using UI_USERNAME and UI_PASSWORD they are Proxy admin + user_role = LitellmUserRoles.PROXY_ADMIN user_id = username key_user_id = user_id if ( @@ -11511,7 +11512,6 @@ async def login(request: Request): and os.environ["PROXY_ADMIN_ID"] == user_id ) or user_id == "admin": # checks if user is admin - user_role = "app_admin" key_user_id = os.getenv("PROXY_ADMIN_ID", "default_user_id") # Admin is Authe'd in - generate key for the UI to access Proxy @@ -11520,7 +11520,7 @@ async def login(request: Request): await user_update( data=UpdateUserRequest( user_id=key_user_id, - user_role=LitellmUserRoles.PROXY_ADMIN, + user_role=user_role, ) ) if os.getenv("DATABASE_URL") is not None: @@ -11548,7 +11548,7 @@ async def login(request: Request): "user_id": user_id, "key": key, "user_email": user_id, - "user_role": "app_admin", # this is the path without sso - we can assume only admins will use this + "user_role": user_role, # this is the path without sso - we can assume only admins will use this "login_method": "username_password", "premium_user": premium_user, }, @@ -11558,8 +11558,15 @@ async def login(request: Request): litellm_dashboard_ui += "?userID=" + user_id + "&token=" + jwt_token return RedirectResponse(url=litellm_dashboard_ui, status_code=303) elif _user_row is not None: + """ + When sharing invite links + + -> if the user has no role in the DB assume they are only a viewer + """ user_id = getattr(_user_row, "user_id", "unknown") - user_role = getattr(_user_row, "user_role", "unknown") + user_role = getattr( + _user_row, "user_role", LitellmUserRoles.INTERNAL_USER_VIEW_ONLY + ) user_email = getattr(_user_row, "user_email", "unknown") _password = getattr(_user_row, "password", "unknown") From 2f9aa308f175f1035778ec395bd4f73ccb3be8c8 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 15 Jun 2024 15:33:26 -0700 Subject: [PATCH 76/83] fix - remove deprecated clickhouse utils --- enterprise/utils.py | 230 ----------------------------- litellm/integrations/clickhouse.py | 8 - 2 files changed, 238 deletions(-) diff --git a/enterprise/utils.py b/enterprise/utils.py index b8f660927b..baff3b1b02 100644 --- a/enterprise/utils.py +++ b/enterprise/utils.py @@ -122,236 +122,6 @@ async def ui_get_spend_by_tags( return {"spend_per_tag": ui_tags} -async def view_spend_logs_from_clickhouse( - api_key=None, user_id=None, request_id=None, start_date=None, end_date=None -): - verbose_logger.debug("Reading logs from Clickhouse") - import os - - # if user has setup clickhouse - # TODO: Move this to be a helper function - # querying clickhouse for this data - import clickhouse_connect - from datetime import datetime - - port = os.getenv("CLICKHOUSE_PORT") - if port is not None and isinstance(port, str): - port = int(port) - - client = clickhouse_connect.get_client( - host=os.getenv("CLICKHOUSE_HOST"), - port=port, - username=os.getenv("CLICKHOUSE_USERNAME", ""), - password=os.getenv("CLICKHOUSE_PASSWORD", ""), - ) - if ( - start_date is not None - and isinstance(start_date, str) - and end_date is not None - and isinstance(end_date, str) - ): - # Convert the date strings to datetime objects - start_date_obj = datetime.strptime(start_date, "%Y-%m-%d") - end_date_obj = datetime.strptime(end_date, "%Y-%m-%d") - - # get top spend per day - response = client.query( - f""" - SELECT - toDate(startTime) AS day, - sum(spend) AS total_spend - FROM - spend_logs - WHERE - toDate(startTime) BETWEEN toDate('2024-02-01') AND toDate('2024-02-29') - GROUP BY - day - ORDER BY - total_spend - """ - ) - - results = [] - result_rows = list(response.result_rows) - for response in result_rows: - current_row = {} - current_row["users"] = {"example": 0.0} - current_row["models"] = {} - - current_row["spend"] = float(response[1]) - current_row["startTime"] = str(response[0]) - - # stubbed api_key - current_row[""] = 0.0 # type: ignore - results.append(current_row) - - return results - else: - # check if spend logs exist, if it does then return last 10 logs, sorted in descending order of startTime - response = client.query( - """ - SELECT - * - FROM - default.spend_logs - ORDER BY - startTime DESC - LIMIT - 10 - """ - ) - - # get size of spend logs - num_rows = client.query("SELECT count(*) FROM default.spend_logs") - num_rows = num_rows.result_rows[0][0] - - # safely access num_rows.result_rows[0][0] - if num_rows is None: - num_rows = 0 - - raw_rows = list(response.result_rows) - response_data = { - "logs": raw_rows, - "log_count": num_rows, - } - return response_data - - -def _create_clickhouse_material_views(client=None, table_names=[]): - # Create Materialized Views if they don't exist - # Materialized Views send new inserted rows to the aggregate tables - - verbose_logger.debug("Clickhouse: Creating Materialized Views") - if "daily_aggregated_spend_per_model_mv" not in table_names: - verbose_logger.debug("Clickhouse: Creating daily_aggregated_spend_per_model_mv") - client.command( - """ - CREATE MATERIALIZED VIEW daily_aggregated_spend_per_model_mv - TO daily_aggregated_spend_per_model - AS - SELECT - toDate(startTime) as day, - sumState(spend) AS DailySpend, - model as model - FROM spend_logs - GROUP BY - day, model - """ - ) - if "daily_aggregated_spend_per_api_key_mv" not in table_names: - verbose_logger.debug( - "Clickhouse: Creating daily_aggregated_spend_per_api_key_mv" - ) - client.command( - """ - CREATE MATERIALIZED VIEW daily_aggregated_spend_per_api_key_mv - TO daily_aggregated_spend_per_api_key - AS - SELECT - toDate(startTime) as day, - sumState(spend) AS DailySpend, - api_key as api_key - FROM spend_logs - GROUP BY - day, api_key - """ - ) - if "daily_aggregated_spend_per_user_mv" not in table_names: - verbose_logger.debug("Clickhouse: Creating daily_aggregated_spend_per_user_mv") - client.command( - """ - CREATE MATERIALIZED VIEW daily_aggregated_spend_per_user_mv - TO daily_aggregated_spend_per_user - AS - SELECT - toDate(startTime) as day, - sumState(spend) AS DailySpend, - user as user - FROM spend_logs - GROUP BY - day, user - """ - ) - if "daily_aggregated_spend_mv" not in table_names: - verbose_logger.debug("Clickhouse: Creating daily_aggregated_spend_mv") - client.command( - """ - CREATE MATERIALIZED VIEW daily_aggregated_spend_mv - TO daily_aggregated_spend - AS - SELECT - toDate(startTime) as day, - sumState(spend) AS DailySpend - FROM spend_logs - GROUP BY - day - """ - ) - - -def _create_clickhouse_aggregate_tables(client=None, table_names=[]): - # Basic Logging works without this - this is only used for low latency reporting apis - verbose_logger.debug("Clickhouse: Creating Aggregate Tables") - - # Create Aggregeate Tables if they don't exist - if "daily_aggregated_spend_per_model" not in table_names: - verbose_logger.debug("Clickhouse: Creating daily_aggregated_spend_per_model") - client.command( - """ - CREATE TABLE daily_aggregated_spend_per_model - ( - `day` Date, - `DailySpend` AggregateFunction(sum, Float64), - `model` String - ) - ENGINE = SummingMergeTree() - ORDER BY (day, model); - """ - ) - if "daily_aggregated_spend_per_api_key" not in table_names: - verbose_logger.debug("Clickhouse: Creating daily_aggregated_spend_per_api_key") - client.command( - """ - CREATE TABLE daily_aggregated_spend_per_api_key - ( - `day` Date, - `DailySpend` AggregateFunction(sum, Float64), - `api_key` String - ) - ENGINE = SummingMergeTree() - ORDER BY (day, api_key); - """ - ) - if "daily_aggregated_spend_per_user" not in table_names: - verbose_logger.debug("Clickhouse: Creating daily_aggregated_spend_per_user") - client.command( - """ - CREATE TABLE daily_aggregated_spend_per_user - ( - `day` Date, - `DailySpend` AggregateFunction(sum, Float64), - `user` String - ) - ENGINE = SummingMergeTree() - ORDER BY (day, user); - """ - ) - if "daily_aggregated_spend" not in table_names: - verbose_logger.debug("Clickhouse: Creating daily_aggregated_spend") - client.command( - """ - CREATE TABLE daily_aggregated_spend - ( - `day` Date, - `DailySpend` AggregateFunction(sum, Float64), - ) - ENGINE = SummingMergeTree() - ORDER BY (day); - """ - ) - return - - def _forecast_daily_cost(data: list): import requests # type: ignore from datetime import datetime, timedelta diff --git a/litellm/integrations/clickhouse.py b/litellm/integrations/clickhouse.py index f8b6b1bbf0..eff1836ef1 100644 --- a/litellm/integrations/clickhouse.py +++ b/litellm/integrations/clickhouse.py @@ -226,14 +226,6 @@ def _start_clickhouse(): response = client.query("DESCRIBE default.spend_logs") verbose_logger.debug(f"spend logs schema ={response.result_rows}") - # RUN Enterprise Clickhouse Setup - # TLDR: For Enterprise - we create views / aggregate tables for low latency reporting APIs - from litellm.proxy.enterprise.utils import _create_clickhouse_aggregate_tables - from litellm.proxy.enterprise.utils import _create_clickhouse_material_views - - _create_clickhouse_aggregate_tables(client=client, table_names=table_names) - _create_clickhouse_material_views(client=client, table_names=table_names) - class ClickhouseLogger: # Class variables or attributes From 5e8b65f1f182fd53bfc4666935c4eb35edae1055 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 15 Jun 2024 15:40:49 -0700 Subject: [PATCH 77/83] ui - show exceptions --- .../src/components/model_dashboard.tsx | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/ui/litellm-dashboard/src/components/model_dashboard.tsx b/ui/litellm-dashboard/src/components/model_dashboard.tsx index 44ce40ebbb..fb189b8c44 100644 --- a/ui/litellm-dashboard/src/components/model_dashboard.tsx +++ b/ui/litellm-dashboard/src/components/model_dashboard.tsx @@ -2080,6 +2080,24 @@ const ModelDashboard: React.FC = ({ + + + + All Exceptions for {selectedModelGroup} + + + + + + @@ -2098,15 +2116,7 @@ const ModelDashboard: React.FC = ({ - {/* */} - + From 70e3295eadd8655e4e97dd4f78a9e943bc3e9608 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Sat, 15 Jun 2024 15:53:46 -0700 Subject: [PATCH 78/83] ui - new build --- litellm/proxy/_experimental/out/404.html | 1 + .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../out/_next/static/chunks/131-19b05e5ce40fa85d.js | 8 -------- .../out/_next/static/chunks/131-6a03368053f9d26d.js | 8 ++++++++ .../{759-d7572f2a46f911d5.js => 759-83a8bdddfe32b5d9.js} | 4 ++-- ...out-9bbef188642a56c0.js => layout-23af663d40748d68.js} | 0 .../out/_next/static/chunks/app/page-4c5ebd62e10ab7aa.js | 1 - .../out/_next/static/chunks/app/page-626098dc8320c801.js | 1 + .../out/_next/static/chunks/webpack-6f7793f21bbb2fbe.js | 2 +- .../out/_next/static/css/159e0004b5599df8.css | 5 ----- .../out/_next/static/css/b65d5698d1a1958d.css | 5 +++++ litellm/proxy/_experimental/out/index.html | 2 +- litellm/proxy/_experimental/out/index.txt | 4 ++-- litellm/proxy/_experimental/out/model_hub.html | 1 + litellm/proxy/_experimental/out/model_hub.txt | 4 ++-- litellm/proxy/_experimental/out/onboarding.html | 1 + litellm/proxy/_experimental/out/onboarding.txt | 2 +- ui/litellm-dashboard/out/404.html | 2 +- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 .../out/_next/static/chunks/131-19b05e5ce40fa85d.js | 8 -------- .../out/_next/static/chunks/131-6a03368053f9d26d.js | 8 ++++++++ .../{759-d7572f2a46f911d5.js => 759-83a8bdddfe32b5d9.js} | 4 ++-- ...out-9bbef188642a56c0.js => layout-23af663d40748d68.js} | 0 .../out/_next/static/chunks/app/page-4c5ebd62e10ab7aa.js | 1 - .../out/_next/static/chunks/app/page-626098dc8320c801.js | 1 + .../out/_next/static/chunks/webpack-6f7793f21bbb2fbe.js | 2 +- .../out/_next/static/css/159e0004b5599df8.css | 5 ----- .../out/_next/static/css/b65d5698d1a1958d.css | 5 +++++ ui/litellm-dashboard/out/index.html | 2 +- ui/litellm-dashboard/out/index.txt | 4 ++-- ui/litellm-dashboard/out/model_hub.html | 2 +- ui/litellm-dashboard/out/model_hub.txt | 4 ++-- ui/litellm-dashboard/out/onboarding.html | 2 +- ui/litellm-dashboard/out/onboarding.txt | 2 +- 36 files changed, 52 insertions(+), 49 deletions(-) create mode 100644 litellm/proxy/_experimental/out/404.html rename litellm/proxy/_experimental/out/_next/static/{QKxw7XOxQ8siV-V22vqEN => S9_6IC27HNWjJtr-LNaAO}/_buildManifest.js (100%) rename litellm/proxy/_experimental/out/_next/static/{QKxw7XOxQ8siV-V22vqEN => S9_6IC27HNWjJtr-LNaAO}/_ssgManifest.js (100%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/131-19b05e5ce40fa85d.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/131-6a03368053f9d26d.js rename litellm/proxy/_experimental/out/_next/static/chunks/{759-d7572f2a46f911d5.js => 759-83a8bdddfe32b5d9.js} (53%) rename litellm/proxy/_experimental/out/_next/static/chunks/app/{layout-9bbef188642a56c0.js => layout-23af663d40748d68.js} (100%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-4c5ebd62e10ab7aa.js create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/app/page-626098dc8320c801.js rename ui/litellm-dashboard/out/_next/static/chunks/webpack-496e007a0280178b.js => litellm/proxy/_experimental/out/_next/static/chunks/webpack-6f7793f21bbb2fbe.js (98%) delete mode 100644 litellm/proxy/_experimental/out/_next/static/css/159e0004b5599df8.css create mode 100644 litellm/proxy/_experimental/out/_next/static/css/b65d5698d1a1958d.css create mode 100644 litellm/proxy/_experimental/out/model_hub.html create mode 100644 litellm/proxy/_experimental/out/onboarding.html rename ui/litellm-dashboard/out/_next/static/{QKxw7XOxQ8siV-V22vqEN => S9_6IC27HNWjJtr-LNaAO}/_buildManifest.js (100%) rename ui/litellm-dashboard/out/_next/static/{QKxw7XOxQ8siV-V22vqEN => S9_6IC27HNWjJtr-LNaAO}/_ssgManifest.js (100%) delete mode 100644 ui/litellm-dashboard/out/_next/static/chunks/131-19b05e5ce40fa85d.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/131-6a03368053f9d26d.js rename ui/litellm-dashboard/out/_next/static/chunks/{759-d7572f2a46f911d5.js => 759-83a8bdddfe32b5d9.js} (53%) rename ui/litellm-dashboard/out/_next/static/chunks/app/{layout-9bbef188642a56c0.js => layout-23af663d40748d68.js} (100%) delete mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/page-4c5ebd62e10ab7aa.js create mode 100644 ui/litellm-dashboard/out/_next/static/chunks/app/page-626098dc8320c801.js rename litellm/proxy/_experimental/out/_next/static/chunks/webpack-496e007a0280178b.js => ui/litellm-dashboard/out/_next/static/chunks/webpack-6f7793f21bbb2fbe.js (98%) delete mode 100644 ui/litellm-dashboard/out/_next/static/css/159e0004b5599df8.css create mode 100644 ui/litellm-dashboard/out/_next/static/css/b65d5698d1a1958d.css diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html new file mode 100644 index 0000000000..e648c625ed --- /dev/null +++ b/litellm/proxy/_experimental/out/404.html @@ -0,0 +1 @@ +404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/S9_6IC27HNWjJtr-LNaAO/_buildManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_buildManifest.js rename to litellm/proxy/_experimental/out/_next/static/S9_6IC27HNWjJtr-LNaAO/_buildManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/S9_6IC27HNWjJtr-LNaAO/_ssgManifest.js similarity index 100% rename from litellm/proxy/_experimental/out/_next/static/QKxw7XOxQ8siV-V22vqEN/_ssgManifest.js rename to litellm/proxy/_experimental/out/_next/static/S9_6IC27HNWjJtr-LNaAO/_ssgManifest.js diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/131-19b05e5ce40fa85d.js b/litellm/proxy/_experimental/out/_next/static/chunks/131-19b05e5ce40fa85d.js deleted file mode 100644 index 92aaed0ddd..0000000000 --- a/litellm/proxy/_experimental/out/_next/static/chunks/131-19b05e5ce40fa85d.js +++ /dev/null @@ -1,8 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[131],{84174:function(e,t,n){n.d(t,{Z:function(){return s}});var a=n(14749),r=n(64090),i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"}}]},name:"copy",theme:"outlined"},o=n(60688),s=r.forwardRef(function(e,t){return r.createElement(o.Z,(0,a.Z)({},e,{ref:t,icon:i}))})},50459:function(e,t,n){n.d(t,{Z:function(){return s}});var a=n(14749),r=n(64090),i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"}}]},name:"right",theme:"outlined"},o=n(60688),s=r.forwardRef(function(e,t){return r.createElement(o.Z,(0,a.Z)({},e,{ref:t,icon:i}))})},92836:function(e,t,n){n.d(t,{Z:function(){return p}});var a=n(69703),r=n(80991),i=n(2898),o=n(99250),s=n(65492),l=n(64090),c=n(41608),d=n(50027);n(18174),n(21871),n(41213);let u=(0,s.fn)("Tab"),p=l.forwardRef((e,t)=>{let{icon:n,className:p,children:g}=e,m=(0,a._T)(e,["icon","className","children"]),b=(0,l.useContext)(c.O),f=(0,l.useContext)(d.Z);return l.createElement(r.O,Object.assign({ref:t,className:(0,o.q)(u("root"),"flex whitespace-nowrap truncate max-w-xs outline-none focus:ring-0 text-tremor-default transition duration-100",f?(0,s.bM)(f,i.K.text).selectTextColor:"solid"===b?"ui-selected:text-tremor-content-emphasis dark:ui-selected:text-dark-tremor-content-emphasis":"ui-selected:text-tremor-brand dark:ui-selected:text-dark-tremor-brand",function(e,t){switch(e){case"line":return(0,o.q)("ui-selected:border-b-2 hover:border-b-2 border-transparent transition duration-100 -mb-px px-2 py-2","hover:border-tremor-content hover:text-tremor-content-emphasis text-tremor-content","dark:hover:border-dark-tremor-content-emphasis dark:hover:text-dark-tremor-content-emphasis dark:text-dark-tremor-content",t?(0,s.bM)(t,i.K.border).selectBorderColor:"ui-selected:border-tremor-brand dark:ui-selected:border-dark-tremor-brand");case"solid":return(0,o.q)("border-transparent border rounded-tremor-small px-2.5 py-1","ui-selected:border-tremor-border ui-selected:bg-tremor-background ui-selected:shadow-tremor-input hover:text-tremor-content-emphasis ui-selected:text-tremor-brand","dark:ui-selected:border-dark-tremor-border dark:ui-selected:bg-dark-tremor-background dark:ui-selected:shadow-dark-tremor-input dark:hover:text-dark-tremor-content-emphasis dark:ui-selected:text-dark-tremor-brand",t?(0,s.bM)(t,i.K.text).selectTextColor:"text-tremor-content dark:text-dark-tremor-content")}}(b,f),p)},m),n?l.createElement(n,{className:(0,o.q)(u("icon"),"flex-none h-5 w-5",g?"mr-2":"")}):null,g?l.createElement("span",null,g):null)});p.displayName="Tab"},26734:function(e,t,n){n.d(t,{Z:function(){return c}});var a=n(69703),r=n(80991),i=n(99250),o=n(65492),s=n(64090);let l=(0,o.fn)("TabGroup"),c=s.forwardRef((e,t)=>{let{defaultIndex:n,index:o,onIndexChange:c,children:d,className:u}=e,p=(0,a._T)(e,["defaultIndex","index","onIndexChange","children","className"]);return s.createElement(r.O.Group,Object.assign({as:"div",ref:t,defaultIndex:n,selectedIndex:o,onChange:c,className:(0,i.q)(l("root"),"w-full",u)},p),d)});c.displayName="TabGroup"},41608:function(e,t,n){n.d(t,{O:function(){return c},Z:function(){return u}});var a=n(69703),r=n(64090),i=n(50027);n(18174),n(21871),n(41213);var o=n(80991),s=n(99250);let l=(0,n(65492).fn)("TabList"),c=(0,r.createContext)("line"),d={line:(0,s.q)("flex border-b space-x-4","border-tremor-border","dark:border-dark-tremor-border"),solid:(0,s.q)("inline-flex p-0.5 rounded-tremor-default space-x-1.5","bg-tremor-background-subtle","dark:bg-dark-tremor-background-subtle")},u=r.forwardRef((e,t)=>{let{color:n,variant:u="line",children:p,className:g}=e,m=(0,a._T)(e,["color","variant","children","className"]);return r.createElement(o.O.List,Object.assign({ref:t,className:(0,s.q)(l("root"),"justify-start overflow-x-clip",d[u],g)},m),r.createElement(c.Provider,{value:u},r.createElement(i.Z.Provider,{value:n},p)))});u.displayName="TabList"},32126:function(e,t,n){n.d(t,{Z:function(){return d}});var a=n(69703);n(50027);var r=n(18174);n(21871);var i=n(41213),o=n(99250),s=n(65492),l=n(64090);let c=(0,s.fn)("TabPanel"),d=l.forwardRef((e,t)=>{let{children:n,className:s}=e,d=(0,a._T)(e,["children","className"]),{selectedValue:u}=(0,l.useContext)(i.Z),p=u===(0,l.useContext)(r.Z);return l.createElement("div",Object.assign({ref:t,className:(0,o.q)(c("root"),"w-full mt-2",p?"":"hidden",s),"aria-selected":p?"true":"false"},d),n)});d.displayName="TabPanel"},23682:function(e,t,n){n.d(t,{Z:function(){return u}});var a=n(69703),r=n(80991);n(50027);var i=n(18174);n(21871);var o=n(41213),s=n(99250),l=n(65492),c=n(64090);let d=(0,l.fn)("TabPanels"),u=c.forwardRef((e,t)=>{let{children:n,className:l}=e,u=(0,a._T)(e,["children","className"]);return c.createElement(r.O.Panels,Object.assign({as:"div",ref:t,className:(0,s.q)(d("root"),"w-full",l)},u),e=>{let{selectedIndex:t}=e;return c.createElement(o.Z.Provider,{value:{selectedValue:t}},c.Children.map(n,(e,t)=>c.createElement(i.Z.Provider,{value:t},e)))})});u.displayName="TabPanels"},50027:function(e,t,n){n.d(t,{Z:function(){return i}});var a=n(64090),r=n(54942);n(99250);let i=(0,a.createContext)(r.fr.Blue)},18174:function(e,t,n){n.d(t,{Z:function(){return a}});let a=(0,n(64090).createContext)(0)},21871:function(e,t,n){n.d(t,{Z:function(){return a}});let a=(0,n(64090).createContext)(void 0)},41213:function(e,t,n){n.d(t,{Z:function(){return a}});let a=(0,n(64090).createContext)({selectedValue:void 0,handleValueChange:void 0})},21467:function(e,t,n){n.d(t,{i:function(){return s}});var a=n(64090),r=n(44329),i=n(54165),o=n(57499);function s(e){return t=>a.createElement(i.ZP,{theme:{token:{motion:!1,zIndexPopupBase:0}}},a.createElement(e,Object.assign({},t)))}t.Z=(e,t,n,i)=>s(s=>{let{prefixCls:l,style:c}=s,d=a.useRef(null),[u,p]=a.useState(0),[g,m]=a.useState(0),[b,f]=(0,r.Z)(!1,{value:s.open}),{getPrefixCls:E}=a.useContext(o.E_),h=E(t||"select",l);a.useEffect(()=>{if(f(!0),"undefined"!=typeof ResizeObserver){let e=new ResizeObserver(e=>{let t=e[0].target;p(t.offsetHeight+8),m(t.offsetWidth)}),t=setInterval(()=>{var a;let r=n?".".concat(n(h)):".".concat(h,"-dropdown"),i=null===(a=d.current)||void 0===a?void 0:a.querySelector(r);i&&(clearInterval(t),e.observe(i))},10);return()=>{clearInterval(t),e.disconnect()}}},[]);let S=Object.assign(Object.assign({},s),{style:Object.assign(Object.assign({},c),{margin:0}),open:b,visible:b,getPopupContainer:()=>d.current});return i&&(S=i(S)),a.createElement("div",{ref:d,style:{paddingBottom:u,position:"relative",minWidth:g}},a.createElement(e,Object.assign({},S)))})},99129:function(e,t,n){let a;n.d(t,{Z:function(){return eY}});var r=n(63787),i=n(64090),o=n(37274),s=n(57499),l=n(54165),c=n(99537),d=n(77136),u=n(20653),p=n(40388),g=n(16480),m=n.n(g),b=n(51761),f=n(47387),E=n(70595),h=n(24750),S=n(89211),y=n(1861),T=n(51350),A=e=>{let{type:t,children:n,prefixCls:a,buttonProps:r,close:o,autoFocus:s,emitEvent:l,isSilent:c,quitOnNullishReturnValue:d,actionFn:u}=e,p=i.useRef(!1),g=i.useRef(null),[m,b]=(0,S.Z)(!1),f=function(){null==o||o.apply(void 0,arguments)};i.useEffect(()=>{let e=null;return s&&(e=setTimeout(()=>{var e;null===(e=g.current)||void 0===e||e.focus()})),()=>{e&&clearTimeout(e)}},[]);let E=e=>{e&&e.then&&(b(!0),e.then(function(){b(!1,!0),f.apply(void 0,arguments),p.current=!1},e=>{if(b(!1,!0),p.current=!1,null==c||!c())return Promise.reject(e)}))};return i.createElement(y.ZP,Object.assign({},(0,T.nx)(t),{onClick:e=>{let t;if(!p.current){if(p.current=!0,!u){f();return}if(l){var n;if(t=u(e),d&&!((n=t)&&n.then)){p.current=!1,f(e);return}}else if(u.length)t=u(o),p.current=!1;else if(!(t=u())){f();return}E(t)}},loading:m,prefixCls:a},r,{ref:g}),n)};let R=i.createContext({}),{Provider:I}=R;var N=()=>{let{autoFocusButton:e,cancelButtonProps:t,cancelTextLocale:n,isSilent:a,mergedOkCancel:r,rootPrefixCls:o,close:s,onCancel:l,onConfirm:c}=(0,i.useContext)(R);return r?i.createElement(A,{isSilent:a,actionFn:l,close:function(){null==s||s.apply(void 0,arguments),null==c||c(!1)},autoFocus:"cancel"===e,buttonProps:t,prefixCls:"".concat(o,"-btn")},n):null},_=()=>{let{autoFocusButton:e,close:t,isSilent:n,okButtonProps:a,rootPrefixCls:r,okTextLocale:o,okType:s,onConfirm:l,onOk:c}=(0,i.useContext)(R);return i.createElement(A,{isSilent:n,type:s||"primary",actionFn:c,close:function(){null==t||t.apply(void 0,arguments),null==l||l(!0)},autoFocus:"ok"===e,buttonProps:a,prefixCls:"".concat(r,"-btn")},o)},v=n(81303),w=n(14749),k=n(80406),C=n(88804),O=i.createContext({}),x=n(5239),L=n(31506),D=n(91010),P=n(4295),M=n(72480);function F(e,t,n){var a=t;return!a&&n&&(a="".concat(e,"-").concat(n)),a}function U(e,t){var n=e["page".concat(t?"Y":"X","Offset")],a="scroll".concat(t?"Top":"Left");if("number"!=typeof n){var r=e.document;"number"!=typeof(n=r.documentElement[a])&&(n=r.body[a])}return n}var B=n(49367),G=n(74084),$=i.memo(function(e){return e.children},function(e,t){return!t.shouldUpdate}),H={width:0,height:0,overflow:"hidden",outline:"none"},z=i.forwardRef(function(e,t){var n,a,r,o=e.prefixCls,s=e.className,l=e.style,c=e.title,d=e.ariaId,u=e.footer,p=e.closable,g=e.closeIcon,b=e.onClose,f=e.children,E=e.bodyStyle,h=e.bodyProps,S=e.modalRender,y=e.onMouseDown,T=e.onMouseUp,A=e.holderRef,R=e.visible,I=e.forceRender,N=e.width,_=e.height,v=e.classNames,k=e.styles,C=i.useContext(O).panel,L=(0,G.x1)(A,C),D=(0,i.useRef)(),P=(0,i.useRef)();i.useImperativeHandle(t,function(){return{focus:function(){var e;null===(e=D.current)||void 0===e||e.focus()},changeActive:function(e){var t=document.activeElement;e&&t===P.current?D.current.focus():e||t!==D.current||P.current.focus()}}});var M={};void 0!==N&&(M.width=N),void 0!==_&&(M.height=_),u&&(n=i.createElement("div",{className:m()("".concat(o,"-footer"),null==v?void 0:v.footer),style:(0,x.Z)({},null==k?void 0:k.footer)},u)),c&&(a=i.createElement("div",{className:m()("".concat(o,"-header"),null==v?void 0:v.header),style:(0,x.Z)({},null==k?void 0:k.header)},i.createElement("div",{className:"".concat(o,"-title"),id:d},c))),p&&(r=i.createElement("button",{type:"button",onClick:b,"aria-label":"Close",className:"".concat(o,"-close")},g||i.createElement("span",{className:"".concat(o,"-close-x")})));var F=i.createElement("div",{className:m()("".concat(o,"-content"),null==v?void 0:v.content),style:null==k?void 0:k.content},r,a,i.createElement("div",(0,w.Z)({className:m()("".concat(o,"-body"),null==v?void 0:v.body),style:(0,x.Z)((0,x.Z)({},E),null==k?void 0:k.body)},h),f),n);return i.createElement("div",{key:"dialog-element",role:"dialog","aria-labelledby":c?d:null,"aria-modal":"true",ref:L,style:(0,x.Z)((0,x.Z)({},l),M),className:m()(o,s),onMouseDown:y,onMouseUp:T},i.createElement("div",{tabIndex:0,ref:D,style:H,"aria-hidden":"true"}),i.createElement($,{shouldUpdate:R||I},S?S(F):F),i.createElement("div",{tabIndex:0,ref:P,style:H,"aria-hidden":"true"}))}),j=i.forwardRef(function(e,t){var n=e.prefixCls,a=e.title,r=e.style,o=e.className,s=e.visible,l=e.forceRender,c=e.destroyOnClose,d=e.motionName,u=e.ariaId,p=e.onVisibleChanged,g=e.mousePosition,b=(0,i.useRef)(),f=i.useState(),E=(0,k.Z)(f,2),h=E[0],S=E[1],y={};function T(){var e,t,n,a,r,i=(n={left:(t=(e=b.current).getBoundingClientRect()).left,top:t.top},r=(a=e.ownerDocument).defaultView||a.parentWindow,n.left+=U(r),n.top+=U(r,!0),n);S(g?"".concat(g.x-i.left,"px ").concat(g.y-i.top,"px"):"")}return h&&(y.transformOrigin=h),i.createElement(B.ZP,{visible:s,onVisibleChanged:p,onAppearPrepare:T,onEnterPrepare:T,forceRender:l,motionName:d,removeOnLeave:c,ref:b},function(s,l){var c=s.className,d=s.style;return i.createElement(z,(0,w.Z)({},e,{ref:t,title:a,ariaId:u,prefixCls:n,holderRef:l,style:(0,x.Z)((0,x.Z)((0,x.Z)({},d),r),y),className:m()(o,c)}))})});function V(e){var t=e.prefixCls,n=e.style,a=e.visible,r=e.maskProps,o=e.motionName,s=e.className;return i.createElement(B.ZP,{key:"mask",visible:a,motionName:o,leavedClassName:"".concat(t,"-mask-hidden")},function(e,a){var o=e.className,l=e.style;return i.createElement("div",(0,w.Z)({ref:a,style:(0,x.Z)((0,x.Z)({},l),n),className:m()("".concat(t,"-mask"),o,s)},r))})}function W(e){var t=e.prefixCls,n=void 0===t?"rc-dialog":t,a=e.zIndex,r=e.visible,o=void 0!==r&&r,s=e.keyboard,l=void 0===s||s,c=e.focusTriggerAfterClose,d=void 0===c||c,u=e.wrapStyle,p=e.wrapClassName,g=e.wrapProps,b=e.onClose,f=e.afterOpenChange,E=e.afterClose,h=e.transitionName,S=e.animation,y=e.closable,T=e.mask,A=void 0===T||T,R=e.maskTransitionName,I=e.maskAnimation,N=e.maskClosable,_=e.maskStyle,v=e.maskProps,C=e.rootClassName,O=e.classNames,U=e.styles,B=(0,i.useRef)(),G=(0,i.useRef)(),$=(0,i.useRef)(),H=i.useState(o),z=(0,k.Z)(H,2),W=z[0],q=z[1],Y=(0,D.Z)();function K(e){null==b||b(e)}var Z=(0,i.useRef)(!1),X=(0,i.useRef)(),Q=null;return(void 0===N||N)&&(Q=function(e){Z.current?Z.current=!1:G.current===e.target&&K(e)}),(0,i.useEffect)(function(){o&&(q(!0),(0,L.Z)(G.current,document.activeElement)||(B.current=document.activeElement))},[o]),(0,i.useEffect)(function(){return function(){clearTimeout(X.current)}},[]),i.createElement("div",(0,w.Z)({className:m()("".concat(n,"-root"),C)},(0,M.Z)(e,{data:!0})),i.createElement(V,{prefixCls:n,visible:A&&o,motionName:F(n,R,I),style:(0,x.Z)((0,x.Z)({zIndex:a},_),null==U?void 0:U.mask),maskProps:v,className:null==O?void 0:O.mask}),i.createElement("div",(0,w.Z)({tabIndex:-1,onKeyDown:function(e){if(l&&e.keyCode===P.Z.ESC){e.stopPropagation(),K(e);return}o&&e.keyCode===P.Z.TAB&&$.current.changeActive(!e.shiftKey)},className:m()("".concat(n,"-wrap"),p,null==O?void 0:O.wrapper),ref:G,onClick:Q,style:(0,x.Z)((0,x.Z)((0,x.Z)({zIndex:a},u),null==U?void 0:U.wrapper),{},{display:W?null:"none"})},g),i.createElement(j,(0,w.Z)({},e,{onMouseDown:function(){clearTimeout(X.current),Z.current=!0},onMouseUp:function(){X.current=setTimeout(function(){Z.current=!1})},ref:$,closable:void 0===y||y,ariaId:Y,prefixCls:n,visible:o&&W,onClose:K,onVisibleChanged:function(e){if(e)!function(){if(!(0,L.Z)(G.current,document.activeElement)){var e;null===(e=$.current)||void 0===e||e.focus()}}();else{if(q(!1),A&&B.current&&d){try{B.current.focus({preventScroll:!0})}catch(e){}B.current=null}W&&(null==E||E())}null==f||f(e)},motionName:F(n,h,S)}))))}j.displayName="Content",n(53850);var q=function(e){var t=e.visible,n=e.getContainer,a=e.forceRender,r=e.destroyOnClose,o=void 0!==r&&r,s=e.afterClose,l=e.panelRef,c=i.useState(t),d=(0,k.Z)(c,2),u=d[0],p=d[1],g=i.useMemo(function(){return{panel:l}},[l]);return(i.useEffect(function(){t&&p(!0)},[t]),a||!o||u)?i.createElement(O.Provider,{value:g},i.createElement(C.Z,{open:t||a||u,autoDestroy:!1,getContainer:n,autoLock:t||u},i.createElement(W,(0,w.Z)({},e,{destroyOnClose:o,afterClose:function(){null==s||s(),p(!1)}})))):null};q.displayName="Dialog";var Y=function(e,t,n){let a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:i.createElement(v.Z,null),r=arguments.length>4&&void 0!==arguments[4]&&arguments[4];if("boolean"==typeof e?!e:void 0===t?!r:!1===t||null===t)return[!1,null];let o="boolean"==typeof t||null==t?a:t;return[!0,n?n(o):o]},K=n(22127),Z=n(86718),X=n(47137),Q=n(92801),J=n(48563);function ee(){}let et=i.createContext({add:ee,remove:ee});var en=n(17094),ea=()=>{let{cancelButtonProps:e,cancelTextLocale:t,onCancel:n}=(0,i.useContext)(R);return i.createElement(y.ZP,Object.assign({onClick:n},e),t)},er=()=>{let{confirmLoading:e,okButtonProps:t,okType:n,okTextLocale:a,onOk:r}=(0,i.useContext)(R);return i.createElement(y.ZP,Object.assign({},(0,T.nx)(n),{loading:e,onClick:r},t),a)},ei=n(4678);function eo(e,t){return i.createElement("span",{className:"".concat(e,"-close-x")},t||i.createElement(v.Z,{className:"".concat(e,"-close-icon")}))}let es=e=>{let t;let{okText:n,okType:a="primary",cancelText:o,confirmLoading:s,onOk:l,onCancel:c,okButtonProps:d,cancelButtonProps:u,footer:p}=e,[g]=(0,E.Z)("Modal",(0,ei.A)()),m={confirmLoading:s,okButtonProps:d,cancelButtonProps:u,okTextLocale:n||(null==g?void 0:g.okText),cancelTextLocale:o||(null==g?void 0:g.cancelText),okType:a,onOk:l,onCancel:c},b=i.useMemo(()=>m,(0,r.Z)(Object.values(m)));return"function"==typeof p||void 0===p?(t=i.createElement(i.Fragment,null,i.createElement(ea,null),i.createElement(er,null)),"function"==typeof p&&(t=p(t,{OkBtn:er,CancelBtn:ea})),t=i.createElement(I,{value:b},t)):t=p,i.createElement(en.n,{disabled:!1},t)};var el=n(11303),ec=n(13703),ed=n(58854),eu=n(80316),ep=n(76585),eg=n(8985);function em(e){return{position:e,inset:0}}let eb=e=>{let{componentCls:t,antCls:n}=e;return[{["".concat(t,"-root")]:{["".concat(t).concat(n,"-zoom-enter, ").concat(t).concat(n,"-zoom-appear")]:{transform:"none",opacity:0,animationDuration:e.motionDurationSlow,userSelect:"none"},["".concat(t).concat(n,"-zoom-leave ").concat(t,"-content")]:{pointerEvents:"none"},["".concat(t,"-mask")]:Object.assign(Object.assign({},em("fixed")),{zIndex:e.zIndexPopupBase,height:"100%",backgroundColor:e.colorBgMask,pointerEvents:"none",["".concat(t,"-hidden")]:{display:"none"}}),["".concat(t,"-wrap")]:Object.assign(Object.assign({},em("fixed")),{zIndex:e.zIndexPopupBase,overflow:"auto",outline:0,WebkitOverflowScrolling:"touch",["&:has(".concat(t).concat(n,"-zoom-enter), &:has(").concat(t).concat(n,"-zoom-appear)")]:{pointerEvents:"none"}})}},{["".concat(t,"-root")]:(0,ec.J$)(e)}]},ef=e=>{let{componentCls:t}=e;return[{["".concat(t,"-root")]:{["".concat(t,"-wrap-rtl")]:{direction:"rtl"},["".concat(t,"-centered")]:{textAlign:"center","&::before":{display:"inline-block",width:0,height:"100%",verticalAlign:"middle",content:'""'},[t]:{top:0,display:"inline-block",paddingBottom:0,textAlign:"start",verticalAlign:"middle"}},["@media (max-width: ".concat(e.screenSMMax,"px)")]:{[t]:{maxWidth:"calc(100vw - 16px)",margin:"".concat((0,eg.bf)(e.marginXS)," auto")},["".concat(t,"-centered")]:{[t]:{flex:1}}}}},{[t]:Object.assign(Object.assign({},(0,el.Wf)(e)),{pointerEvents:"none",position:"relative",top:100,width:"auto",maxWidth:"calc(100vw - ".concat((0,eg.bf)(e.calc(e.margin).mul(2).equal()),")"),margin:"0 auto",paddingBottom:e.paddingLG,["".concat(t,"-title")]:{margin:0,color:e.titleColor,fontWeight:e.fontWeightStrong,fontSize:e.titleFontSize,lineHeight:e.titleLineHeight,wordWrap:"break-word"},["".concat(t,"-content")]:{position:"relative",backgroundColor:e.contentBg,backgroundClip:"padding-box",border:0,borderRadius:e.borderRadiusLG,boxShadow:e.boxShadow,pointerEvents:"auto",padding:e.contentPadding},["".concat(t,"-close")]:Object.assign({position:"absolute",top:e.calc(e.modalHeaderHeight).sub(e.modalCloseBtnSize).div(2).equal(),insetInlineEnd:e.calc(e.modalHeaderHeight).sub(e.modalCloseBtnSize).div(2).equal(),zIndex:e.calc(e.zIndexPopupBase).add(10).equal(),padding:0,color:e.modalCloseIconColor,fontWeight:e.fontWeightStrong,lineHeight:1,textDecoration:"none",background:"transparent",borderRadius:e.borderRadiusSM,width:e.modalCloseBtnSize,height:e.modalCloseBtnSize,border:0,outline:0,cursor:"pointer",transition:"color ".concat(e.motionDurationMid,", background-color ").concat(e.motionDurationMid),"&-x":{display:"flex",fontSize:e.fontSizeLG,fontStyle:"normal",lineHeight:"".concat((0,eg.bf)(e.modalCloseBtnSize)),justifyContent:"center",textTransform:"none",textRendering:"auto"},"&:hover":{color:e.modalIconHoverColor,backgroundColor:e.closeBtnHoverBg,textDecoration:"none"},"&:active":{backgroundColor:e.closeBtnActiveBg}},(0,el.Qy)(e)),["".concat(t,"-header")]:{color:e.colorText,background:e.headerBg,borderRadius:"".concat((0,eg.bf)(e.borderRadiusLG)," ").concat((0,eg.bf)(e.borderRadiusLG)," 0 0"),marginBottom:e.headerMarginBottom,padding:e.headerPadding,borderBottom:e.headerBorderBottom},["".concat(t,"-body")]:{fontSize:e.fontSize,lineHeight:e.lineHeight,wordWrap:"break-word",padding:e.bodyPadding},["".concat(t,"-footer")]:{textAlign:"end",background:e.footerBg,marginTop:e.footerMarginTop,padding:e.footerPadding,borderTop:e.footerBorderTop,borderRadius:e.footerBorderRadius,["> ".concat(e.antCls,"-btn + ").concat(e.antCls,"-btn")]:{marginInlineStart:e.marginXS}},["".concat(t,"-open")]:{overflow:"hidden"}})},{["".concat(t,"-pure-panel")]:{top:"auto",padding:0,display:"flex",flexDirection:"column",["".concat(t,"-content,\n ").concat(t,"-body,\n ").concat(t,"-confirm-body-wrapper")]:{display:"flex",flexDirection:"column",flex:"auto"},["".concat(t,"-confirm-body")]:{marginBottom:"auto"}}}]},eE=e=>{let{componentCls:t}=e;return{["".concat(t,"-root")]:{["".concat(t,"-wrap-rtl")]:{direction:"rtl",["".concat(t,"-confirm-body")]:{direction:"rtl"}}}}},eh=e=>{let t=e.padding,n=e.fontSizeHeading5,a=e.lineHeightHeading5;return(0,eu.TS)(e,{modalHeaderHeight:e.calc(e.calc(a).mul(n).equal()).add(e.calc(t).mul(2).equal()).equal(),modalFooterBorderColorSplit:e.colorSplit,modalFooterBorderStyle:e.lineType,modalFooterBorderWidth:e.lineWidth,modalIconHoverColor:e.colorIconHover,modalCloseIconColor:e.colorIcon,modalCloseBtnSize:e.fontHeight,modalConfirmIconSize:e.fontHeight,modalTitleHeight:e.calc(e.titleFontSize).mul(e.titleLineHeight).equal()})},eS=e=>({footerBg:"transparent",headerBg:e.colorBgElevated,titleLineHeight:e.lineHeightHeading5,titleFontSize:e.fontSizeHeading5,contentBg:e.colorBgElevated,titleColor:e.colorTextHeading,closeBtnHoverBg:e.wireframe?"transparent":e.colorFillContent,closeBtnActiveBg:e.wireframe?"transparent":e.colorFillContentHover,contentPadding:e.wireframe?0:"".concat((0,eg.bf)(e.paddingMD)," ").concat((0,eg.bf)(e.paddingContentHorizontalLG)),headerPadding:e.wireframe?"".concat((0,eg.bf)(e.padding)," ").concat((0,eg.bf)(e.paddingLG)):0,headerBorderBottom:e.wireframe?"".concat((0,eg.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorSplit):"none",headerMarginBottom:e.wireframe?0:e.marginXS,bodyPadding:e.wireframe?e.paddingLG:0,footerPadding:e.wireframe?"".concat((0,eg.bf)(e.paddingXS)," ").concat((0,eg.bf)(e.padding)):0,footerBorderTop:e.wireframe?"".concat((0,eg.bf)(e.lineWidth)," ").concat(e.lineType," ").concat(e.colorSplit):"none",footerBorderRadius:e.wireframe?"0 0 ".concat((0,eg.bf)(e.borderRadiusLG)," ").concat((0,eg.bf)(e.borderRadiusLG)):0,footerMarginTop:e.wireframe?0:e.marginSM,confirmBodyPadding:e.wireframe?"".concat((0,eg.bf)(2*e.padding)," ").concat((0,eg.bf)(2*e.padding)," ").concat((0,eg.bf)(e.paddingLG)):0,confirmIconMarginInlineEnd:e.wireframe?e.margin:e.marginSM,confirmBtnsMarginTop:e.wireframe?e.marginLG:e.marginSM});var ey=(0,ep.I$)("Modal",e=>{let t=eh(e);return[ef(t),eE(t),eb(t),(0,ed._y)(t,"zoom")]},eS,{unitless:{titleLineHeight:!0}}),eT=n(92935),eA=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,a=Object.getOwnPropertySymbols(e);rt.indexOf(a[r])&&Object.prototype.propertyIsEnumerable.call(e,a[r])&&(n[a[r]]=e[a[r]]);return n};(0,K.Z)()&&window.document.documentElement&&document.documentElement.addEventListener("click",e=>{a={x:e.pageX,y:e.pageY},setTimeout(()=>{a=null},100)},!0);var eR=e=>{var t;let{getPopupContainer:n,getPrefixCls:r,direction:o,modal:l}=i.useContext(s.E_),c=t=>{let{onCancel:n}=e;null==n||n(t)},{prefixCls:d,className:u,rootClassName:p,open:g,wrapClassName:E,centered:h,getContainer:S,closeIcon:y,closable:T,focusTriggerAfterClose:A=!0,style:R,visible:I,width:N=520,footer:_,classNames:w,styles:k}=e,C=eA(e,["prefixCls","className","rootClassName","open","wrapClassName","centered","getContainer","closeIcon","closable","focusTriggerAfterClose","style","visible","width","footer","classNames","styles"]),O=r("modal",d),x=r(),L=(0,eT.Z)(O),[D,P,M]=ey(O,L),F=m()(E,{["".concat(O,"-centered")]:!!h,["".concat(O,"-wrap-rtl")]:"rtl"===o}),U=null!==_&&i.createElement(es,Object.assign({},e,{onOk:t=>{let{onOk:n}=e;null==n||n(t)},onCancel:c})),[B,G]=Y(T,y,e=>eo(O,e),i.createElement(v.Z,{className:"".concat(O,"-close-icon")}),!0),$=function(e){let t=i.useContext(et),n=i.useRef();return(0,J.zX)(a=>{if(a){let r=e?a.querySelector(e):a;t.add(r),n.current=r}else t.remove(n.current)})}(".".concat(O,"-content")),[H,z]=(0,b.Cn)("Modal",C.zIndex);return D(i.createElement(Q.BR,null,i.createElement(X.Ux,{status:!0,override:!0},i.createElement(Z.Z.Provider,{value:z},i.createElement(q,Object.assign({width:N},C,{zIndex:H,getContainer:void 0===S?n:S,prefixCls:O,rootClassName:m()(P,p,M,L),footer:U,visible:null!=g?g:I,mousePosition:null!==(t=C.mousePosition)&&void 0!==t?t:a,onClose:c,closable:B,closeIcon:G,focusTriggerAfterClose:A,transitionName:(0,f.m)(x,"zoom",e.transitionName),maskTransitionName:(0,f.m)(x,"fade",e.maskTransitionName),className:m()(P,u,null==l?void 0:l.className),style:Object.assign(Object.assign({},null==l?void 0:l.style),R),classNames:Object.assign(Object.assign({wrapper:F},null==l?void 0:l.classNames),w),styles:Object.assign(Object.assign({},null==l?void 0:l.styles),k),panelRef:$}))))))};let eI=e=>{let{componentCls:t,titleFontSize:n,titleLineHeight:a,modalConfirmIconSize:r,fontSize:i,lineHeight:o,modalTitleHeight:s,fontHeight:l,confirmBodyPadding:c}=e,d="".concat(t,"-confirm");return{[d]:{"&-rtl":{direction:"rtl"},["".concat(e.antCls,"-modal-header")]:{display:"none"},["".concat(d,"-body-wrapper")]:Object.assign({},(0,el.dF)()),["&".concat(t," ").concat(t,"-body")]:{padding:c},["".concat(d,"-body")]:{display:"flex",flexWrap:"nowrap",alignItems:"start",["> ".concat(e.iconCls)]:{flex:"none",fontSize:r,marginInlineEnd:e.confirmIconMarginInlineEnd,marginTop:e.calc(e.calc(l).sub(r).equal()).div(2).equal()},["&-has-title > ".concat(e.iconCls)]:{marginTop:e.calc(e.calc(s).sub(r).equal()).div(2).equal()}},["".concat(d,"-paragraph")]:{display:"flex",flexDirection:"column",flex:"auto",rowGap:e.marginXS,maxWidth:"calc(100% - ".concat((0,eg.bf)(e.calc(e.modalConfirmIconSize).add(e.marginSM).equal()),")")},["".concat(d,"-title")]:{color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:n,lineHeight:a},["".concat(d,"-content")]:{color:e.colorText,fontSize:i,lineHeight:o},["".concat(d,"-btns")]:{textAlign:"end",marginTop:e.confirmBtnsMarginTop,["".concat(e.antCls,"-btn + ").concat(e.antCls,"-btn")]:{marginBottom:0,marginInlineStart:e.marginXS}}},["".concat(d,"-error ").concat(d,"-body > ").concat(e.iconCls)]:{color:e.colorError},["".concat(d,"-warning ").concat(d,"-body > ").concat(e.iconCls,",\n ").concat(d,"-confirm ").concat(d,"-body > ").concat(e.iconCls)]:{color:e.colorWarning},["".concat(d,"-info ").concat(d,"-body > ").concat(e.iconCls)]:{color:e.colorInfo},["".concat(d,"-success ").concat(d,"-body > ").concat(e.iconCls)]:{color:e.colorSuccess}}};var eN=(0,ep.bk)(["Modal","confirm"],e=>[eI(eh(e))],eS,{order:-1e3}),e_=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,a=Object.getOwnPropertySymbols(e);rt.indexOf(a[r])&&Object.prototype.propertyIsEnumerable.call(e,a[r])&&(n[a[r]]=e[a[r]]);return n};function ev(e){let{prefixCls:t,icon:n,okText:a,cancelText:o,confirmPrefixCls:s,type:l,okCancel:g,footer:b,locale:f}=e,h=e_(e,["prefixCls","icon","okText","cancelText","confirmPrefixCls","type","okCancel","footer","locale"]),S=n;if(!n&&null!==n)switch(l){case"info":S=i.createElement(p.Z,null);break;case"success":S=i.createElement(c.Z,null);break;case"error":S=i.createElement(d.Z,null);break;default:S=i.createElement(u.Z,null)}let y=null!=g?g:"confirm"===l,T=null!==e.autoFocusButton&&(e.autoFocusButton||"ok"),[A]=(0,E.Z)("Modal"),R=f||A,v=a||(y?null==R?void 0:R.okText:null==R?void 0:R.justOkText),w=Object.assign({autoFocusButton:T,cancelTextLocale:o||(null==R?void 0:R.cancelText),okTextLocale:v,mergedOkCancel:y},h),k=i.useMemo(()=>w,(0,r.Z)(Object.values(w))),C=i.createElement(i.Fragment,null,i.createElement(N,null),i.createElement(_,null)),O=void 0!==e.title&&null!==e.title,x="".concat(s,"-body");return i.createElement("div",{className:"".concat(s,"-body-wrapper")},i.createElement("div",{className:m()(x,{["".concat(x,"-has-title")]:O})},S,i.createElement("div",{className:"".concat(s,"-paragraph")},O&&i.createElement("span",{className:"".concat(s,"-title")},e.title),i.createElement("div",{className:"".concat(s,"-content")},e.content))),void 0===b||"function"==typeof b?i.createElement(I,{value:k},i.createElement("div",{className:"".concat(s,"-btns")},"function"==typeof b?b(C,{OkBtn:_,CancelBtn:N}):C)):b,i.createElement(eN,{prefixCls:t}))}let ew=e=>{let{close:t,zIndex:n,afterClose:a,open:r,keyboard:o,centered:s,getContainer:l,maskStyle:c,direction:d,prefixCls:u,wrapClassName:p,rootPrefixCls:g,bodyStyle:E,closable:S=!1,closeIcon:y,modalRender:T,focusTriggerAfterClose:A,onConfirm:R,styles:I}=e,N="".concat(u,"-confirm"),_=e.width||416,v=e.style||{},w=void 0===e.mask||e.mask,k=void 0!==e.maskClosable&&e.maskClosable,C=m()(N,"".concat(N,"-").concat(e.type),{["".concat(N,"-rtl")]:"rtl"===d},e.className),[,O]=(0,h.ZP)(),x=i.useMemo(()=>void 0!==n?n:O.zIndexPopupBase+b.u6,[n,O]);return i.createElement(eR,{prefixCls:u,className:C,wrapClassName:m()({["".concat(N,"-centered")]:!!e.centered},p),onCancel:()=>{null==t||t({triggerCancel:!0}),null==R||R(!1)},open:r,title:"",footer:null,transitionName:(0,f.m)(g||"","zoom",e.transitionName),maskTransitionName:(0,f.m)(g||"","fade",e.maskTransitionName),mask:w,maskClosable:k,style:v,styles:Object.assign({body:E,mask:c},I),width:_,zIndex:x,afterClose:a,keyboard:o,centered:s,getContainer:l,closable:S,closeIcon:y,modalRender:T,focusTriggerAfterClose:A},i.createElement(ev,Object.assign({},e,{confirmPrefixCls:N})))};var ek=e=>{let{rootPrefixCls:t,iconPrefixCls:n,direction:a,theme:r}=e;return i.createElement(l.ZP,{prefixCls:t,iconPrefixCls:n,direction:a,theme:r},i.createElement(ew,Object.assign({},e)))},eC=[];let eO="",ex=e=>{var t,n;let{prefixCls:a,getContainer:r,direction:o}=e,l=(0,ei.A)(),c=(0,i.useContext)(s.E_),d=eO||c.getPrefixCls(),u=a||"".concat(d,"-modal"),p=r;return!1===p&&(p=void 0),i.createElement(ek,Object.assign({},e,{rootPrefixCls:d,prefixCls:u,iconPrefixCls:c.iconPrefixCls,theme:c.theme,direction:null!=o?o:c.direction,locale:null!==(n=null===(t=c.locale)||void 0===t?void 0:t.Modal)&&void 0!==n?n:l,getContainer:p}))};function eL(e){let t;let n=(0,l.w6)(),a=document.createDocumentFragment(),s=Object.assign(Object.assign({},e),{close:u,open:!0});function c(){for(var t=arguments.length,n=Array(t),i=0;ie&&e.triggerCancel);e.onCancel&&s&&e.onCancel.apply(e,[()=>{}].concat((0,r.Z)(n.slice(1))));for(let e=0;e{let t=n.getPrefixCls(void 0,eO),r=n.getIconPrefixCls(),s=n.getTheme(),c=i.createElement(ex,Object.assign({},e));(0,o.s)(i.createElement(l.ZP,{prefixCls:t,iconPrefixCls:r,theme:s},n.holderRender?n.holderRender(c):c),a)})}function u(){for(var t=arguments.length,n=Array(t),a=0;a{"function"==typeof e.afterClose&&e.afterClose(),c.apply(this,n)}})).visible&&delete s.visible,d(s)}return d(s),eC.push(u),{destroy:u,update:function(e){d(s="function"==typeof e?e(s):Object.assign(Object.assign({},s),e))}}}function eD(e){return Object.assign(Object.assign({},e),{type:"warning"})}function eP(e){return Object.assign(Object.assign({},e),{type:"info"})}function eM(e){return Object.assign(Object.assign({},e),{type:"success"})}function eF(e){return Object.assign(Object.assign({},e),{type:"error"})}function eU(e){return Object.assign(Object.assign({},e),{type:"confirm"})}var eB=n(21467),eG=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,a=Object.getOwnPropertySymbols(e);rt.indexOf(a[r])&&Object.prototype.propertyIsEnumerable.call(e,a[r])&&(n[a[r]]=e[a[r]]);return n},e$=(0,eB.i)(e=>{let{prefixCls:t,className:n,closeIcon:a,closable:r,type:o,title:l,children:c,footer:d}=e,u=eG(e,["prefixCls","className","closeIcon","closable","type","title","children","footer"]),{getPrefixCls:p}=i.useContext(s.E_),g=p(),b=t||p("modal"),f=(0,eT.Z)(g),[E,h,S]=ey(b,f),y="".concat(b,"-confirm"),T={};return T=o?{closable:null!=r&&r,title:"",footer:"",children:i.createElement(ev,Object.assign({},e,{prefixCls:b,confirmPrefixCls:y,rootPrefixCls:g,content:c}))}:{closable:null==r||r,title:l,footer:null!==d&&i.createElement(es,Object.assign({},e)),children:c},E(i.createElement(z,Object.assign({prefixCls:b,className:m()(h,"".concat(b,"-pure-panel"),o&&y,o&&"".concat(y,"-").concat(o),n,S,f)},u,{closeIcon:eo(b,a),closable:r},T)))}),eH=n(79474),ez=function(e,t){var n={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>t.indexOf(a)&&(n[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,a=Object.getOwnPropertySymbols(e);rt.indexOf(a[r])&&Object.prototype.propertyIsEnumerable.call(e,a[r])&&(n[a[r]]=e[a[r]]);return n},ej=i.forwardRef((e,t)=>{var n,{afterClose:a,config:o}=e,l=ez(e,["afterClose","config"]);let[c,d]=i.useState(!0),[u,p]=i.useState(o),{direction:g,getPrefixCls:m}=i.useContext(s.E_),b=m("modal"),f=m(),h=function(){d(!1);for(var e=arguments.length,t=Array(e),n=0;ne&&e.triggerCancel);u.onCancel&&a&&u.onCancel.apply(u,[()=>{}].concat((0,r.Z)(t.slice(1))))};i.useImperativeHandle(t,()=>({destroy:h,update:e=>{p(t=>Object.assign(Object.assign({},t),e))}}));let S=null!==(n=u.okCancel)&&void 0!==n?n:"confirm"===u.type,[y]=(0,E.Z)("Modal",eH.Z.Modal);return i.createElement(ek,Object.assign({prefixCls:b,rootPrefixCls:f},u,{close:h,open:c,afterClose:()=>{var e;a(),null===(e=u.afterClose)||void 0===e||e.call(u)},okText:u.okText||(S?null==y?void 0:y.okText:null==y?void 0:y.justOkText),direction:u.direction||g,cancelText:u.cancelText||(null==y?void 0:y.cancelText)},l))});let eV=0,eW=i.memo(i.forwardRef((e,t)=>{let[n,a]=function(){let[e,t]=i.useState([]);return[e,i.useCallback(e=>(t(t=>[].concat((0,r.Z)(t),[e])),()=>{t(t=>t.filter(t=>t!==e))}),[])]}();return i.useImperativeHandle(t,()=>({patchElement:a}),[]),i.createElement(i.Fragment,null,n)}));function eq(e){return eL(eD(e))}eR.useModal=function(){let e=i.useRef(null),[t,n]=i.useState([]);i.useEffect(()=>{t.length&&((0,r.Z)(t).forEach(e=>{e()}),n([]))},[t]);let a=i.useCallback(t=>function(a){var o;let s,l;eV+=1;let c=i.createRef(),d=new Promise(e=>{s=e}),u=!1,p=i.createElement(ej,{key:"modal-".concat(eV),config:t(a),ref:c,afterClose:()=>{null==l||l()},isSilent:()=>u,onConfirm:e=>{s(e)}});return(l=null===(o=e.current)||void 0===o?void 0:o.patchElement(p))&&eC.push(l),{destroy:()=>{function e(){var e;null===(e=c.current)||void 0===e||e.destroy()}c.current?e():n(t=>[].concat((0,r.Z)(t),[e]))},update:e=>{function t(){var t;null===(t=c.current)||void 0===t||t.update(e)}c.current?t():n(e=>[].concat((0,r.Z)(e),[t]))},then:e=>(u=!0,d.then(e))}},[]);return[i.useMemo(()=>({info:a(eP),success:a(eM),error:a(eF),warning:a(eD),confirm:a(eU)}),[]),i.createElement(eW,{key:"modal-holder",ref:e})]},eR.info=function(e){return eL(eP(e))},eR.success=function(e){return eL(eM(e))},eR.error=function(e){return eL(eF(e))},eR.warning=eq,eR.warn=eq,eR.confirm=function(e){return eL(eU(e))},eR.destroyAll=function(){for(;eC.length;){let e=eC.pop();e&&e()}},eR.config=function(e){let{rootPrefixCls:t}=e;eO=t},eR._InternalPanelDoNotUseOrYouWillBeFired=e$;var eY=eR},13703:function(e,t,n){n.d(t,{J$:function(){return s}});var a=n(8985),r=n(59353);let i=new a.E4("antFadeIn",{"0%":{opacity:0},"100%":{opacity:1}}),o=new a.E4("antFadeOut",{"0%":{opacity:1},"100%":{opacity:0}}),s=function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],{antCls:n}=e,a="".concat(n,"-fade"),s=t?"&":"";return[(0,r.R)(a,i,o,e.motionDurationMid,t),{["\n ".concat(s).concat(a,"-enter,\n ").concat(s).concat(a,"-appear\n ")]:{opacity:0,animationTimingFunction:"linear"},["".concat(s).concat(a,"-leave")]:{animationTimingFunction:"linear"}}]}},44056:function(e){e.exports=function(e,n){for(var a,r,i,o=e||"",s=n||"div",l={},c=0;c4&&m.slice(0,4)===o&&s.test(t)&&("-"===t.charAt(4)?b=o+(n=t.slice(5).replace(l,u)).charAt(0).toUpperCase()+n.slice(1):(g=(p=t).slice(4),t=l.test(g)?p:("-"!==(g=g.replace(c,d)).charAt(0)&&(g="-"+g),o+g)),f=r),new f(b,t))};var s=/^data[-\w.:]+$/i,l=/-[a-z]/g,c=/[A-Z]/g;function d(e){return"-"+e.toLowerCase()}function u(e){return e.charAt(1).toUpperCase()}},31872:function(e,t,n){var a=n(96130),r=n(64730),i=n(61861),o=n(46982),s=n(83671),l=n(53618);e.exports=a([i,r,o,s,l])},83671:function(e,t,n){var a=n(7667),r=n(13585),i=a.booleanish,o=a.number,s=a.spaceSeparated;e.exports=r({transform:function(e,t){return"role"===t?t:"aria-"+t.slice(4).toLowerCase()},properties:{ariaActiveDescendant:null,ariaAtomic:i,ariaAutoComplete:null,ariaBusy:i,ariaChecked:i,ariaColCount:o,ariaColIndex:o,ariaColSpan:o,ariaControls:s,ariaCurrent:null,ariaDescribedBy:s,ariaDetails:null,ariaDisabled:i,ariaDropEffect:s,ariaErrorMessage:null,ariaExpanded:i,ariaFlowTo:s,ariaGrabbed:i,ariaHasPopup:null,ariaHidden:i,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:s,ariaLevel:o,ariaLive:null,ariaModal:i,ariaMultiLine:i,ariaMultiSelectable:i,ariaOrientation:null,ariaOwns:s,ariaPlaceholder:null,ariaPosInSet:o,ariaPressed:i,ariaReadOnly:i,ariaRelevant:null,ariaRequired:i,ariaRoleDescription:s,ariaRowCount:o,ariaRowIndex:o,ariaRowSpan:o,ariaSelected:i,ariaSetSize:o,ariaSort:null,ariaValueMax:o,ariaValueMin:o,ariaValueNow:o,ariaValueText:null,role:null}})},53618:function(e,t,n){var a=n(7667),r=n(13585),i=n(46640),o=a.boolean,s=a.overloadedBoolean,l=a.booleanish,c=a.number,d=a.spaceSeparated,u=a.commaSeparated;e.exports=r({space:"html",attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},transform:i,mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:u,acceptCharset:d,accessKey:d,action:null,allow:null,allowFullScreen:o,allowPaymentRequest:o,allowUserMedia:o,alt:null,as:null,async:o,autoCapitalize:null,autoComplete:d,autoFocus:o,autoPlay:o,capture:o,charSet:null,checked:o,cite:null,className:d,cols:c,colSpan:null,content:null,contentEditable:l,controls:o,controlsList:d,coords:c|u,crossOrigin:null,data:null,dateTime:null,decoding:null,default:o,defer:o,dir:null,dirName:null,disabled:o,download:s,draggable:l,encType:null,enterKeyHint:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:o,formTarget:null,headers:d,height:c,hidden:o,high:c,href:null,hrefLang:null,htmlFor:d,httpEquiv:d,id:null,imageSizes:null,imageSrcSet:u,inputMode:null,integrity:null,is:null,isMap:o,itemId:null,itemProp:d,itemRef:d,itemScope:o,itemType:d,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:o,low:c,manifest:null,max:null,maxLength:c,media:null,method:null,min:null,minLength:c,multiple:o,muted:o,name:null,nonce:null,noModule:o,noValidate:o,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforePrint:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextMenu:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:o,optimum:c,pattern:null,ping:d,placeholder:null,playsInline:o,poster:null,preload:null,readOnly:o,referrerPolicy:null,rel:d,required:o,reversed:o,rows:c,rowSpan:c,sandbox:d,scope:null,scoped:o,seamless:o,selected:o,shape:null,size:c,sizes:null,slot:null,span:c,spellCheck:l,src:null,srcDoc:null,srcLang:null,srcSet:u,start:c,step:null,style:null,tabIndex:c,target:null,title:null,translate:null,type:null,typeMustMatch:o,useMap:null,value:l,width:c,wrap:null,align:null,aLink:null,archive:d,axis:null,background:null,bgColor:null,border:c,borderColor:null,bottomMargin:c,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:o,declare:o,event:null,face:null,frame:null,frameBorder:null,hSpace:c,leftMargin:c,link:null,longDesc:null,lowSrc:null,marginHeight:c,marginWidth:c,noResize:o,noHref:o,noShade:o,noWrap:o,object:null,profile:null,prompt:null,rev:null,rightMargin:c,rules:null,scheme:null,scrolling:l,standby:null,summary:null,text:null,topMargin:c,valueType:null,version:null,vAlign:null,vLink:null,vSpace:c,allowTransparency:null,autoCorrect:null,autoSave:null,disablePictureInPicture:o,disableRemotePlayback:o,prefix:null,property:null,results:c,security:null,unselectable:null}})},46640:function(e,t,n){var a=n(25852);e.exports=function(e,t){return a(e,t.toLowerCase())}},25852:function(e){e.exports=function(e,t){return t in e?e[t]:t}},13585:function(e,t,n){var a=n(39900),r=n(94949),i=n(7478);e.exports=function(e){var t,n,o=e.space,s=e.mustUseProperty||[],l=e.attributes||{},c=e.properties,d=e.transform,u={},p={};for(t in c)n=new i(t,d(l,t),c[t],o),-1!==s.indexOf(t)&&(n.mustUseProperty=!0),u[t]=n,p[a(t)]=t,p[a(n.attribute)]=t;return new r(u,p,o)}},7478:function(e,t,n){var a=n(74108),r=n(7667);e.exports=s,s.prototype=new a,s.prototype.defined=!0;var i=["boolean","booleanish","overloadedBoolean","number","commaSeparated","spaceSeparated","commaOrSpaceSeparated"],o=i.length;function s(e,t,n,s){var l,c,d,u=-1;for(s&&(this.space=s),a.call(this,e,t);++u